1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Platform Synchronization tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronization.hpp"
25
26 #include "vktTestCaseUtil.hpp"
27
28 #include "vkPlatform.hpp"
29 #include "vkStrUtil.hpp"
30 #include "vkRef.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkDeviceUtil.hpp"
33
34 #include "tcuTestLog.hpp"
35 #include "tcuFormatUtil.hpp"
36
37 #include "deUniquePtr.hpp"
38 #include "deThread.hpp"
39 #include "vkMemUtil.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkTypeUtil.hpp"
43
44 #include <limits>
45
46 namespace vkt
47 {
48
49 using namespace vk;
50 using namespace tcu;
51
52 namespace
53 {
54
55 using std::vector;
56 using std::string;
57 using tcu::TestLog;
58 using de::UniquePtr;
59 using de::MovePtr;
60
61 static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
62
buildShaders(SourceCollections & shaderCollection)63 void buildShaders (SourceCollections& shaderCollection)
64 {
65 shaderCollection.glslSources.add("glslvert") <<
66 glu::VertexSource(
67 "#version 310 es\n"
68 "precision mediump float;\n"
69 "layout (location = 0) in vec4 vertexPosition;\n"
70 "void main()\n"
71 "{\n"
72 " gl_Position = vertexPosition;\n"
73 "}\n");
74
75 shaderCollection.glslSources.add("glslfrag") <<
76 glu::FragmentSource(
77 "#version 310 es\n"
78 "precision mediump float;\n"
79 "layout (location = 0) out vec4 outputColor;\n"
80 "void main()\n"
81 "{\n"
82 " outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
83 "}\n");
84 }
85
createTestDevice(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 * outQueueFamilyIndex)86 Move<VkDevice> createTestDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 *outQueueFamilyIndex)
87 {
88 VkDeviceQueueCreateInfo queueInfo;
89 VkDeviceCreateInfo deviceInfo;
90 size_t queueNdx;
91 const deUint32 queueCount = 2u;
92 const float queuePriority[queueCount] = { 1.0f, 1.0f };
93
94 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
95 const VkPhysicalDeviceFeatures physicalDeviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
96
97 for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
98 {
99 if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && (queueProps[queueNdx].queueCount >= queueCount))
100 break;
101 }
102
103 if (queueNdx >= queueProps.size())
104 {
105 // No queue family index found
106 std::ostringstream msg;
107 msg << "Cannot create device with " << queueCount << " graphics queues";
108
109 throw tcu::NotSupportedError(msg.str());
110 }
111
112 deMemset(&queueInfo, 0, sizeof(queueInfo));
113 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
114
115 deMemset(&queueInfo, 0xcd, sizeof(queueInfo));
116 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
117 queueInfo.pNext = DE_NULL;
118 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
119 queueInfo.queueFamilyIndex = (deUint32)queueNdx;
120 queueInfo.queueCount = queueCount;
121 queueInfo.pQueuePriorities = queuePriority;
122
123 deMemset(&deviceInfo, 0xcd, sizeof(deviceInfo));
124 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
125 deviceInfo.pNext = DE_NULL;
126 deviceInfo.queueCreateInfoCount = 1u;
127 deviceInfo.pQueueCreateInfos = &queueInfo;
128 deviceInfo.enabledExtensionCount = 0u;
129 deviceInfo.ppEnabledExtensionNames = DE_NULL;
130 deviceInfo.enabledLayerCount = 0u;
131 deviceInfo.ppEnabledLayerNames = DE_NULL;
132 deviceInfo.pEnabledFeatures = &physicalDeviceFeatures;
133
134 *outQueueFamilyIndex = queueInfo.queueFamilyIndex;
135
136 return createDevice(vki, physicalDevice, &deviceInfo);
137 };
138
139 struct BufferParameters
140 {
141 const void* memory;
142 VkDeviceSize size;
143 VkBufferUsageFlags usage;
144 VkSharingMode sharingMode;
145 deUint32 queueFamilyCount;
146 const deUint32* queueFamilyIndex;
147 VkAccessFlags inputBarrierFlags;
148 };
149
150 struct Buffer
151 {
152 MovePtr<Allocation> allocation;
153 vector<VkMemoryBarrier> memoryBarrier;
154 vk::Move<VkBuffer> buffer;
155 };
156
createVulkanBuffer(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const BufferParameters & bufferParameters,Buffer & buffer,MemoryRequirement visibility)157 void createVulkanBuffer (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
158 {
159 VkBufferCreateInfo bufferCreateParams;
160
161 deMemset(&bufferCreateParams, 0xcd, sizeof(bufferCreateParams));
162 bufferCreateParams.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
163 bufferCreateParams.pNext = DE_NULL;
164 bufferCreateParams.flags = 0;
165 bufferCreateParams.size = bufferParameters.size;
166 bufferCreateParams.usage = bufferParameters.usage;
167 bufferCreateParams.sharingMode = bufferParameters.sharingMode;
168 bufferCreateParams.queueFamilyIndexCount = bufferParameters.queueFamilyCount;
169 bufferCreateParams.pQueueFamilyIndices = bufferParameters.queueFamilyIndex;
170
171 buffer.buffer = createBuffer(vkd, device, &bufferCreateParams);
172 buffer.allocation = allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer.buffer), visibility);
173
174 VK_CHECK(vkd.bindBufferMemory(device, *buffer.buffer, buffer.allocation->getMemory(), buffer.allocation->getOffset()));
175
176 // If caller provides a host memory buffer for the allocation, then go
177 // ahead and copy the provided data into the allocation and update the
178 // barrier list with the associated access
179 if (bufferParameters.memory != DE_NULL)
180 {
181 VkMemoryBarrier barrier;
182 VkMappedMemoryRange range;
183
184 deMemset(&range, 0xcd, sizeof(range));
185 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
186 range.pNext = DE_NULL;
187 range.memory = buffer.allocation->getMemory();
188 range.offset = buffer.allocation->getOffset();
189 range.size = bufferParameters.size;
190
191 deMemcpy(buffer.allocation->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size);
192 VK_CHECK(vkd.flushMappedMemoryRanges(device, 1, &range));
193
194 deMemset(&barrier, 0xcd, sizeof(barrier));
195 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
196 barrier.pNext = DE_NULL;
197 barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
198 barrier.dstAccessMask = bufferParameters.inputBarrierFlags;
199
200 buffer.memoryBarrier.push_back(barrier);
201 }
202 }
203
204 struct ImageParameters
205 {
206 VkImageType imageType;
207 VkFormat format;
208 VkExtent3D extent3D;
209 deUint32 mipLevels;
210 VkSampleCountFlagBits samples;
211 VkImageTiling tiling;
212 VkBufferUsageFlags usage;
213 VkSharingMode sharingMode;
214 deUint32 queueFamilyCount;
215 const deUint32* queueFamilyNdxList;
216 VkImageLayout initialLayout;
217 VkImageLayout finalLayout;
218 VkAccessFlags barrierInputMask;
219 };
220
221 struct Image
222 {
223 vk::Move<VkImage> image;
224 vk::Move<VkImageView> imageView;
225 MovePtr<Allocation> allocation;
226 vector<VkImageMemoryBarrier> imageMemoryBarrier;
227 };
228
createVulkanImage(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const ImageParameters & imageParameters,Image & image,MemoryRequirement visibility)229 void createVulkanImage (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
230 {
231 VkComponentMapping componentMap;
232 VkImageSubresourceRange subresourceRange;
233 VkImageViewCreateInfo imageViewCreateInfo;
234 VkImageCreateInfo imageCreateParams;
235 VkImageMemoryBarrier imageBarrier;
236
237 deMemset(&imageCreateParams, 0xcd, sizeof(imageCreateParams));
238 imageCreateParams.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
239 imageCreateParams.pNext = DE_NULL;
240 imageCreateParams.flags = 0;
241 imageCreateParams.imageType = imageParameters.imageType;
242 imageCreateParams.format = imageParameters.format;
243 imageCreateParams.extent = imageParameters.extent3D;
244 imageCreateParams.mipLevels = imageParameters.mipLevels;
245 imageCreateParams.arrayLayers = 1;
246 imageCreateParams.samples = imageParameters.samples;
247 imageCreateParams.tiling = imageParameters.tiling;
248 imageCreateParams.usage = imageParameters.usage;
249 imageCreateParams.sharingMode = imageParameters.sharingMode;
250 imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount;
251 imageCreateParams.pQueueFamilyIndices = imageParameters.queueFamilyNdxList;
252 imageCreateParams.initialLayout = imageParameters.initialLayout;
253
254 image.image = createImage(vkd, device, &imageCreateParams);
255 image.allocation = allocator.allocate(getImageMemoryRequirements(vkd, device, *image.image), visibility);
256
257 VK_CHECK(vkd.bindImageMemory(device, *image.image, image.allocation->getMemory(), image.allocation->getOffset()));
258
259 componentMap.r = VK_COMPONENT_SWIZZLE_R;
260 componentMap.g = VK_COMPONENT_SWIZZLE_G;
261 componentMap.b = VK_COMPONENT_SWIZZLE_B;
262 componentMap.a = VK_COMPONENT_SWIZZLE_A;
263
264 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
265 subresourceRange.baseMipLevel = 0;
266 subresourceRange.levelCount = imageParameters.mipLevels;
267 subresourceRange.baseArrayLayer = 0;
268 subresourceRange.layerCount = 1;
269
270 deMemset(&imageViewCreateInfo, 0xcd, sizeof(imageViewCreateInfo));
271 imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
272 imageViewCreateInfo.pNext = DE_NULL;
273 imageViewCreateInfo.flags = 0;
274 imageViewCreateInfo.image = image.image.get();
275 imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
276 imageViewCreateInfo.format = imageParameters.format;
277 imageViewCreateInfo.components = componentMap;
278 imageViewCreateInfo.subresourceRange = subresourceRange;
279
280 image.imageView = createImageView(vkd, device, &imageViewCreateInfo);
281
282 deMemset(&imageBarrier, 0xcd, sizeof(imageBarrier));
283 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
284 imageBarrier.pNext = DE_NULL;
285 imageBarrier.srcAccessMask = 0;
286 imageBarrier.dstAccessMask = imageParameters.barrierInputMask;
287 imageBarrier.oldLayout = imageParameters.initialLayout;
288 imageBarrier.newLayout = imageParameters.finalLayout;
289 imageBarrier.srcQueueFamilyIndex = imageParameters.queueFamilyNdxList[0];
290 imageBarrier.dstQueueFamilyIndex = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
291 imageBarrier.image = image.image.get();
292 imageBarrier.subresourceRange = subresourceRange;
293
294 image.imageMemoryBarrier.push_back(imageBarrier);
295 }
296
297 struct RenderPassParameters
298 {
299 VkFormat colorFormat;
300 VkSampleCountFlagBits colorSamples;
301 };
302
createColorOnlyRenderPass(const DeviceInterface & vkd,VkDevice device,const RenderPassParameters & renderPassParameters,vk::Move<VkRenderPass> & renderPass)303 void createColorOnlyRenderPass (const DeviceInterface& vkd, VkDevice device, const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
304 {
305 VkAttachmentDescription colorAttachmentDesc;
306 VkAttachmentReference colorAttachmentRef;
307 VkAttachmentReference stencilAttachmentRef;
308 VkSubpassDescription subpassDesc;
309 VkRenderPassCreateInfo renderPassParams;
310 VkRenderPass newRenderPass;
311
312 colorAttachmentDesc.flags = 0;
313 colorAttachmentDesc.format = renderPassParameters.colorFormat;
314 colorAttachmentDesc.samples = renderPassParameters.colorSamples;
315 colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
316 colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
317 colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
318 colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
319 colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
320 colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
321
322 colorAttachmentRef.attachment = 0;
323 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
324
325 stencilAttachmentRef.attachment = VK_NO_ATTACHMENT;
326 stencilAttachmentRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
327
328 subpassDesc.flags = 0;
329 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
330 subpassDesc.inputAttachmentCount = 0;
331 subpassDesc.pInputAttachments = DE_NULL;
332 subpassDesc.colorAttachmentCount = 1;
333 subpassDesc.pColorAttachments = &colorAttachmentRef;
334 subpassDesc.pResolveAttachments = DE_NULL;
335 subpassDesc.pDepthStencilAttachment = &stencilAttachmentRef;
336 subpassDesc.preserveAttachmentCount = 0;
337 subpassDesc.pPreserveAttachments = DE_NULL;
338
339 deMemset(&renderPassParams, 0xcd, sizeof(renderPassParams));
340 renderPassParams.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
341 renderPassParams.pNext = DE_NULL;
342 renderPassParams.flags = 0;
343 renderPassParams.attachmentCount = 1;
344 renderPassParams.pAttachments = &colorAttachmentDesc;
345 renderPassParams.subpassCount = 1;
346 renderPassParams.pSubpasses = &subpassDesc;
347 renderPassParams.dependencyCount = 0;
348 renderPassParams.pDependencies = DE_NULL;
349
350 renderPass = createRenderPass(vkd, device, &renderPassParams);
351 }
352
353 struct ShaderDescParams
354 {
355 VkShaderModule shaderModule;
356 VkShaderStageFlagBits stage;
357 };
358
359 struct VertexDesc
360 {
361 deUint32 location;
362 VkFormat format;
363 deUint32 stride;
364 deUint32 offset;
365 };
366
createVertexInfo(const vector<VertexDesc> & vertexDesc,vector<VkVertexInputBindingDescription> & bindingList,vector<VkVertexInputAttributeDescription> & attrList,VkPipelineVertexInputStateCreateInfo & vertexInputState)367 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
368 {
369 for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
370 {
371 deUint32 bindingId = 0;
372 VkVertexInputBindingDescription bindingDesc;
373 VkVertexInputAttributeDescription attrDesc;
374
375 bindingDesc.binding = bindingId;
376 bindingDesc.stride = vertDescIter->stride;
377 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
378 bindingList.push_back(bindingDesc);
379
380 attrDesc.location = vertDescIter->location;
381 attrDesc.binding = bindingId;
382 attrDesc.format = vertDescIter->format;
383 attrDesc.offset = vertDescIter->offset;
384 attrList.push_back(attrDesc);
385
386 bindingId++;
387 }
388
389 deMemset(&vertexInputState, 0xcd, sizeof(vertexInputState));
390 vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
391 vertexInputState.pNext = DE_NULL,
392 vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
393 vertexInputState.pVertexBindingDescriptions = &bindingList[0];
394 vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
395 vertexInputState.pVertexAttributeDescriptions = &attrList[0];
396 }
397
createCommandBuffer(const DeviceInterface & deviceInterface,const VkDevice device,const deUint32 queueFamilyNdx,vk::Move<VkCommandBuffer> * commandBufferRef,vk::Move<VkCommandPool> * commandPoolRef)398 void createCommandBuffer (const DeviceInterface& deviceInterface, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef, vk::Move<VkCommandPool>* commandPoolRef)
399 {
400 vk::Move<VkCommandPool> commandPool;
401 VkCommandPoolCreateInfo commandPoolInfo;
402 VkCommandBufferAllocateInfo commandBufferInfo;
403 VkCommandBuffer commandBuffer;
404
405 deMemset(&commandPoolInfo, 0xcd, sizeof(commandPoolInfo));
406 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
407 commandPoolInfo.pNext = DE_NULL;
408 commandPoolInfo.flags = 0;
409 commandPoolInfo.queueFamilyIndex = queueFamilyNdx;
410
411 commandPool = createCommandPool(deviceInterface, device, &commandPoolInfo, DE_NULL);
412
413 deMemset(&commandBufferInfo, 0xcd, sizeof(commandBufferInfo));
414 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
415 commandBufferInfo.pNext = DE_NULL;
416 commandBufferInfo.commandPool = commandPool.get();
417 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
418 commandBufferInfo.commandBufferCount = 1;
419
420 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
421 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool.get()));
422 *commandPoolRef = commandPool;
423 }
424
createFences(const DeviceInterface & deviceInterface,VkDevice device,bool signaled,deUint32 numFences,VkFence * fence)425 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
426 {
427 VkFenceCreateInfo fenceState;
428 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
429
430 deMemset(&fenceState, 0xcd, sizeof(fenceState));
431 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
432 fenceState.pNext = DE_NULL;
433 fenceState.flags = signalFlag;
434
435 for (deUint32 ndx = 0; ndx < numFences; ndx++)
436 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
437 }
438
destroyFences(const DeviceInterface & deviceInterface,VkDevice device,deUint32 numFences,VkFence * fence)439 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
440 {
441 for (deUint32 ndx = 0; ndx < numFences; ndx++)
442 deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
443 }
444
445 struct RenderInfo
446 {
447 deInt32 width;
448 deInt32 height;
449 deUint32 vertexBufferSize;
450 VkBuffer vertexBuffer;
451 VkImage image;
452 VkCommandBuffer commandBuffer;
453 VkRenderPass renderPass;
454 VkFramebuffer framebuffer;
455 VkPipeline pipeline;
456 deUint32 mipLevels;
457 const deUint32* queueFamilyNdxList;
458 deUint32 queueFamilyNdxCount;
459 bool waitEvent;
460 VkEvent event;
461 vector<VkImageMemoryBarrier>* barriers;
462 };
463
recordRenderPass(const DeviceInterface & deviceInterface,const RenderInfo & renderInfo)464 void recordRenderPass (const DeviceInterface& deviceInterface, const RenderInfo& renderInfo)
465 {
466 const VkDeviceSize bindingOffset = 0;
467 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0);
468 VkRenderPassBeginInfo renderPassBeginState;
469 VkImageMemoryBarrier renderBarrier;
470
471 deMemset(&renderPassBeginState, 0xcd, sizeof(renderPassBeginState));
472 renderPassBeginState.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
473 renderPassBeginState.pNext = DE_NULL;
474 renderPassBeginState.renderPass = renderInfo.renderPass;
475 renderPassBeginState.framebuffer = renderInfo.framebuffer;
476 renderPassBeginState.renderArea.offset.x = 0;
477 renderPassBeginState.renderArea.offset.y = 0;
478 renderPassBeginState.renderArea.extent.width = renderInfo.width;
479 renderPassBeginState.renderArea.extent.height = renderInfo.height;
480 renderPassBeginState.clearValueCount = 1;
481 renderPassBeginState.pClearValues = &clearValue;
482
483 deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE);
484 if (renderInfo.waitEvent)
485 deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
486 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
487 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
488 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
489 deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer);
490
491 deMemset(&renderBarrier, 0xcd, sizeof(renderBarrier));
492 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
493 renderBarrier.pNext = DE_NULL;
494 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
495 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
496 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
497 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
498 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0];
499 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
500 renderBarrier.image = renderInfo.image;
501 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
502 renderBarrier.subresourceRange.baseMipLevel = 0;
503 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels;
504 renderBarrier.subresourceRange.baseArrayLayer = 0;
505 renderBarrier.subresourceRange.layerCount = 1;
506 renderInfo.barriers->push_back(renderBarrier);
507 }
508
509 struct TransferInfo
510 {
511 VkCommandBuffer commandBuffer;
512 deUint32 width;
513 deUint32 height;
514 VkImage image;
515 VkBuffer buffer;
516 VkDeviceSize size;
517 deUint32 mipLevel;
518 VkOffset3D imageOffset;
519 vector<VkBufferMemoryBarrier>* barriers;
520 };
521
copyToCPU(const DeviceInterface & vkd,TransferInfo * transferInfo)522 void copyToCPU (const DeviceInterface& vkd, TransferInfo* transferInfo)
523 {
524 VkBufferImageCopy copyState;
525
526 copyState.bufferOffset = 0;
527 copyState.bufferRowLength = transferInfo->width;
528 copyState.bufferImageHeight = transferInfo->height;
529 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
530 copyState.imageSubresource.mipLevel = transferInfo->mipLevel;
531 copyState.imageSubresource.baseArrayLayer = 0;
532 copyState.imageSubresource.layerCount = 1;
533 copyState.imageOffset = transferInfo->imageOffset;
534 copyState.imageExtent.width = (deInt32)(transferInfo->width);
535 copyState.imageExtent.height = (deInt32)(transferInfo->height);
536 copyState.imageExtent.depth = 1;
537
538 vkd.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State);
539
540 {
541 VkBufferMemoryBarrier bufferBarrier;
542 deMemset(&bufferBarrier, 0xcd, sizeof(bufferBarrier));
543 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
544 bufferBarrier.pNext = DE_NULL;
545 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
546 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
547 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
548 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
549 bufferBarrier.buffer = transferInfo->buffer;
550 bufferBarrier.offset = 0;
551 bufferBarrier.size = transferInfo->size;
552 transferInfo->barriers->push_back(bufferBarrier);
553 }
554 }
555
556 struct TestContext
557 {
558 const DeviceInterface& vkd;
559 const VkDevice device;
560 const deUint32 queueFamilyIndex;
561 const BinaryCollection& binaryCollection;
562 Allocator& allocator;
563
564 const tcu::Vec4* vertices;
565 deUint32 numVertices;
566 tcu::IVec2 renderDimension;
567 VkFence fences[2];
568 VkDeviceSize renderSize;
569 MovePtr<Allocation> renderReadBuffer;
570 MovePtr<Allocation> vertexBufferAllocation;
571 vk::Move<VkBuffer> vertexBuffer;
572 vk::Move<VkBuffer> renderBuffer;
573 bool waitEvent;
574 VkEvent event;
575 vk::Move<VkImage> image;
576 vk::Move<VkImageView> imageView;
577 vk::Move<VkFramebuffer> framebuffer;
578 vk::Move<VkCommandPool> commandPool;
579 vk::Move<VkCommandBuffer> cmdBuffer;
580 vk::Move<VkRenderPass> renderPass;
581 vk::Move<VkPipelineCache> pipelineCache;
582 vk::Move<VkPipeline> pipeline;
583 MovePtr<Allocation> imageAllocation;
584
TestContextvkt::__anonb823dca60111::TestContext585 TestContext (const DeviceInterface& vkd_,
586 const VkDevice device_,
587 deUint32 queueFamilyIndex_,
588 const BinaryCollection& binaryCollection_,
589 Allocator& allocator_)
590 : vkd (vkd_)
591 , device (device_)
592 , queueFamilyIndex (queueFamilyIndex_)
593 , binaryCollection (binaryCollection_)
594 , allocator (allocator_)
595 , numVertices (0)
596 , waitEvent (false)
597 {
598 createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences);
599 }
600
~TestContextvkt::__anonb823dca60111::TestContext601 ~TestContext()
602 {
603 destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences);
604 }
605 };
606
generateWork(TestContext & testContext)607 void generateWork (TestContext& testContext)
608 {
609 const DeviceInterface& deviceInterface = testContext.vkd;
610 const deUint32 queueFamilyNdx = testContext.queueFamilyIndex;
611
612 // \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted
613 // as pipeline has been constructed.
614 const vk::Unique<VkShaderModule> vertShaderModule (createShaderModule(deviceInterface,
615 testContext.device,
616 testContext.binaryCollection.get("glslvert"),
617 (VkShaderModuleCreateFlags)0));
618
619 const vk::Unique<VkShaderModule> fragShaderModule (createShaderModule(deviceInterface,
620 testContext.device,
621 testContext.binaryCollection.get("glslfrag"),
622 (VkShaderModuleCreateFlags)0));
623 const VkPipelineShaderStageCreateInfo shaderStageParams[] =
624 {
625 {
626 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
627 DE_NULL,
628 (VkPipelineShaderStageCreateFlags)0,
629 VK_SHADER_STAGE_VERTEX_BIT,
630 *vertShaderModule,
631 "main",
632 (const VkSpecializationInfo*)DE_NULL,
633 },
634 {
635 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
636 DE_NULL,
637 (VkPipelineShaderStageCreateFlags)0,
638 VK_SHADER_STAGE_FRAGMENT_BIT,
639 *fragShaderModule,
640 "main",
641 (const VkSpecializationInfo*)DE_NULL,
642 }
643 };
644
645 vk::Move<VkPipelineLayout> layout;
646 vector<ShaderDescParams> shaderDescParams;
647 VertexDesc vertexDesc;
648 vector<VertexDesc> vertexDescList;
649 vector<VkVertexInputAttributeDescription> attrList;
650 vector<VkBufferMemoryBarrier> bufferMemoryBarrier;
651 deUint32 memoryBarrierNdx;
652 deUint32 bufferMemoryBarrierNdx;
653 deUint32 imageMemoryBarrierNdx;
654 vector<VkVertexInputBindingDescription> bindingList;
655 VkPipelineVertexInputStateCreateInfo vertexInputState;
656 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
657 VkPipelineDepthStencilStateCreateInfo depthStencilState;
658 VkPipelineColorBlendAttachmentState blendAttachment;
659 VkPipelineColorBlendStateCreateInfo blendState;
660 VkPipelineLayoutCreateInfo pipelineLayoutState;
661 VkGraphicsPipelineCreateInfo pipelineState;
662 VkPipelineCacheCreateInfo cacheState;
663 VkViewport viewport;
664 VkPipelineViewportStateCreateInfo viewportInfo;
665 VkRect2D scissor;
666 BufferParameters bufferParameters;
667 Buffer buffer;
668 RenderInfo renderInfo;
669 ImageParameters imageParameters;
670 Image image;
671 VkPipelineRasterizationStateCreateInfo rasterState;
672 VkPipelineMultisampleStateCreateInfo multisampleState;
673 VkFramebufferCreateInfo fbState;
674 VkCommandBufferBeginInfo commandBufRecordState;
675 VkCommandBufferInheritanceInfo inheritanceInfo;
676 RenderPassParameters renderPassParameters;
677 TransferInfo transferInfo;
678 vector<void*> barrierList;
679 VkExtent3D extent;
680 vector<VkMemoryBarrier> memoryBarriers;
681 vector<VkBufferMemoryBarrier> bufferBarriers;
682 vector<VkImageMemoryBarrier> imageBarriers;
683
684 memoryBarrierNdx = 0;
685 bufferMemoryBarrierNdx = 0;
686 imageMemoryBarrierNdx = 0;
687 buffer.memoryBarrier.resize(memoryBarrierNdx);
688 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
689 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
690
691 memoryBarriers.resize(0);
692 bufferBarriers.resize(0);
693 imageBarriers.resize(0);
694
695 bufferParameters.memory = testContext.vertices;
696 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4);
697 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
698 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
699 bufferParameters.queueFamilyCount = 1;
700 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
701 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
702 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
703 testContext.vertexBufferAllocation = buffer.allocation;
704 testContext.vertexBuffer = buffer.buffer;
705
706 bufferParameters.memory = DE_NULL;
707 bufferParameters.size = testContext.renderSize;
708 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
709 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
710 bufferParameters.queueFamilyCount = 1;
711 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
712 bufferParameters.inputBarrierFlags = 0;
713 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
714 testContext.renderReadBuffer = buffer.allocation;
715 testContext.renderBuffer = buffer.buffer;
716
717 extent.width = testContext.renderDimension.x();
718 extent.height = testContext.renderDimension.y();
719 extent.depth = 1;
720
721 imageParameters.imageType = VK_IMAGE_TYPE_2D;
722 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
723 imageParameters.extent3D = extent;
724 imageParameters.mipLevels = 1;
725 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT;
726 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL;
727 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
728 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
729 imageParameters.queueFamilyCount = 1;
730 imageParameters.queueFamilyNdxList = &queueFamilyNdx;
731 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
732 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
733 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
734 createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any);
735 testContext.imageAllocation = image.allocation;
736 testContext.image = image.image;
737
738 for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx)
739 imageBarriers.push_back(image.imageMemoryBarrier[ndx]);
740
741 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
742 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT;
743 createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass);
744
745 vertexDesc.location = 0;
746 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
747 vertexDesc.stride = sizeof(tcu::Vec4);
748 vertexDesc.offset = 0;
749 vertexDescList.push_back(vertexDesc);
750
751 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
752
753 deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState));
754 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
755 inputAssemblyState.pNext = DE_NULL;
756 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
757 inputAssemblyState.primitiveRestartEnable = false;
758
759 viewport.x = 0;
760 viewport.y = 0;
761 viewport.width = (float)testContext.renderDimension.x();
762 viewport.height = (float)testContext.renderDimension.y();
763 viewport.minDepth = 0;
764 viewport.maxDepth = 1;
765
766 scissor.offset.x = 0;
767 scissor.offset.y = 0;
768 scissor.extent.width = testContext.renderDimension.x();
769 scissor.extent.height = testContext.renderDimension.y();
770
771 deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo));
772 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
773 viewportInfo.pNext = DE_NULL;
774 viewportInfo.flags = 0;
775 viewportInfo.viewportCount = 1;
776 viewportInfo.pViewports = &viewport;
777 viewportInfo.scissorCount = 1;
778 viewportInfo.pScissors = &scissor;
779
780 deMemset(&rasterState, 0xcd, sizeof(rasterState));
781 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
782 rasterState.pNext = DE_NULL;
783 rasterState.flags = 0;
784 rasterState.depthClampEnable = VK_TRUE;
785 rasterState.rasterizerDiscardEnable = VK_FALSE;
786 rasterState.polygonMode = VK_POLYGON_MODE_FILL;
787 rasterState.cullMode = VK_CULL_MODE_NONE;
788 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
789 rasterState.depthBiasEnable = VK_FALSE;
790 rasterState.lineWidth = 1;
791
792 deMemset(&multisampleState, 0xcd, sizeof(multisampleState));
793 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
794 multisampleState.pNext = DE_NULL;
795 multisampleState.flags = 0;
796 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
797 multisampleState.sampleShadingEnable = VK_FALSE;
798 multisampleState.pSampleMask = DE_NULL;
799 multisampleState.alphaToCoverageEnable = VK_FALSE;
800 multisampleState.alphaToOneEnable = VK_FALSE;
801
802 deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState));
803 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
804 depthStencilState.pNext = DE_NULL;
805 depthStencilState.flags = 0;
806 depthStencilState.depthTestEnable = VK_FALSE;
807 depthStencilState.depthWriteEnable = VK_FALSE;
808 depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
809 depthStencilState.depthBoundsTestEnable = VK_FALSE;
810 depthStencilState.stencilTestEnable = VK_FALSE;
811 depthStencilState.front.failOp = VK_STENCIL_OP_KEEP;
812 depthStencilState.front.passOp = VK_STENCIL_OP_KEEP;
813 depthStencilState.front.depthFailOp = VK_STENCIL_OP_KEEP;
814 depthStencilState.front.compareOp = VK_COMPARE_OP_ALWAYS;
815 depthStencilState.front.compareMask = 0u;
816 depthStencilState.front.writeMask = 0u;
817 depthStencilState.front.reference = 0u;
818 depthStencilState.back = depthStencilState.front;
819
820 deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment));
821 blendAttachment.blendEnable = VK_FALSE;
822 blendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
823 blendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
824 blendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
825 blendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
826 blendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
827 blendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
828
829 deMemset(&blendState, 0xcd, sizeof(blendState));
830 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
831 blendState.pNext = DE_NULL;
832 blendState.flags = 0;
833 blendState.logicOpEnable = VK_FALSE;
834 blendState.logicOp = VK_LOGIC_OP_COPY;
835 blendState.attachmentCount = 1;
836 blendState.pAttachments = &blendAttachment;
837
838 deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState));
839 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
840 pipelineLayoutState.pNext = DE_NULL;
841 pipelineLayoutState.flags = 0;
842 pipelineLayoutState.setLayoutCount = 0;
843 pipelineLayoutState.pSetLayouts = DE_NULL;
844 pipelineLayoutState.pushConstantRangeCount = 0;
845 pipelineLayoutState.pPushConstantRanges = DE_NULL;
846 layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL);
847
848 deMemset(&pipelineState, 0xcd, sizeof(pipelineState));
849 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
850 pipelineState.pNext = DE_NULL;
851 pipelineState.flags = 0;
852 pipelineState.stageCount = DE_LENGTH_OF_ARRAY(shaderStageParams);
853 pipelineState.pStages = &shaderStageParams[0];
854 pipelineState.pVertexInputState = &vertexInputState;
855 pipelineState.pInputAssemblyState = &inputAssemblyState;
856 pipelineState.pTessellationState = DE_NULL;
857 pipelineState.pViewportState = &viewportInfo;
858 pipelineState.pRasterizationState = &rasterState;
859 pipelineState.pMultisampleState = &multisampleState;
860 pipelineState.pDepthStencilState = &depthStencilState;
861 pipelineState.pColorBlendState = &blendState;
862 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
863 pipelineState.layout = layout.get();
864 pipelineState.renderPass = testContext.renderPass.get();
865 pipelineState.subpass = 0;
866 pipelineState.basePipelineHandle = DE_NULL;
867 pipelineState.basePipelineIndex = 0;
868
869 deMemset(&cacheState, 0xcd, sizeof(cacheState));
870 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
871 cacheState.pNext = DE_NULL;
872 cacheState.flags = 0;
873 cacheState.initialDataSize = 0;
874 cacheState.pInitialData = DE_NULL;
875
876 testContext.pipelineCache = createPipelineCache(deviceInterface, testContext.device, &cacheState);
877 testContext.pipeline = createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState);
878
879 deMemset(&fbState, 0xcd, sizeof(fbState));
880 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
881 fbState.pNext = DE_NULL;
882 fbState.flags = 0;
883 fbState.renderPass = testContext.renderPass.get();
884 fbState.attachmentCount = 1;
885 fbState.pAttachments = &image.imageView.get();
886 fbState.width = (deUint32)testContext.renderDimension.x();
887 fbState.height = (deUint32)testContext.renderDimension.y();
888 fbState.layers = 1;
889
890 testContext.framebuffer = createFramebuffer(deviceInterface, testContext.device, &fbState);
891 testContext.imageView = image.imageView;
892
893 deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo));
894 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
895 inheritanceInfo.pNext = DE_NULL;
896 inheritanceInfo.renderPass = testContext.renderPass.get();
897 inheritanceInfo.subpass = 0;
898 inheritanceInfo.framebuffer = *testContext.framebuffer;
899 inheritanceInfo.occlusionQueryEnable = VK_FALSE;
900
901 deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState));
902 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
903 commandBufRecordState.pNext = DE_NULL;
904 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
905 commandBufRecordState.pInheritanceInfo = &inheritanceInfo;
906 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
907
908 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
909 VK_PIPELINE_STAGE_HOST_BIT,
910 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
911 false,
912 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
913 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
914 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
915
916 memoryBarriers.resize(0);
917 bufferBarriers.resize(0);
918 imageBarriers.resize(0);
919
920 renderInfo.width = testContext.renderDimension.x();
921 renderInfo.height = testContext.renderDimension.y();
922 renderInfo.vertexBufferSize = testContext.numVertices;
923 renderInfo.vertexBuffer = testContext.vertexBuffer.get();
924 renderInfo.image = testContext.image.get();
925 renderInfo.commandBuffer = testContext.cmdBuffer.get();
926 renderInfo.renderPass = testContext.renderPass.get();
927 renderInfo.framebuffer = *testContext.framebuffer;
928 renderInfo.pipeline = *testContext.pipeline;
929 renderInfo.mipLevels = 1;
930 renderInfo.queueFamilyNdxList = &queueFamilyNdx;
931 renderInfo.queueFamilyNdxCount = 1;
932 renderInfo.waitEvent = testContext.waitEvent;
933 renderInfo.event = testContext.event;
934 renderInfo.barriers = &imageBarriers;
935 recordRenderPass(deviceInterface, renderInfo);
936
937 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer,
938 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
939 VK_PIPELINE_STAGE_TRANSFER_BIT,
940 false,
941 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
942 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
943 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
944
945 memoryBarriers.resize(0);
946 bufferBarriers.resize(0);
947 imageBarriers.resize(0);
948
949 transferInfo.commandBuffer = renderInfo.commandBuffer;
950 transferInfo.width = testContext.renderDimension.x();
951 transferInfo.height = testContext.renderDimension.y();
952 transferInfo.image = renderInfo.image;
953 transferInfo.buffer = testContext.renderBuffer.get();
954 transferInfo.size = testContext.renderSize;
955 transferInfo.mipLevel = 0;
956 transferInfo.imageOffset.x = 0;
957 transferInfo.imageOffset.y = 0;
958 transferInfo.imageOffset.z = 0;
959 transferInfo.barriers = &bufferBarriers;
960 copyToCPU(deviceInterface, &transferInfo);
961
962 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer,
963 VK_PIPELINE_STAGE_TRANSFER_BIT,
964 VK_PIPELINE_STAGE_HOST_BIT,
965 false,
966 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
967 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
968 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
969
970 memoryBarriers.resize(0);
971 bufferBarriers.resize(0);
972 imageBarriers.resize(0);
973
974 VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer));
975 }
976
initSubmitInfo(VkSubmitInfo * submitInfo,deUint32 submitInfoCount)977 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
978 {
979 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
980 {
981 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
982 submitInfo[ndx].pNext = DE_NULL;
983 submitInfo[ndx].waitSemaphoreCount = 0;
984 submitInfo[ndx].pWaitSemaphores = DE_NULL;
985 submitInfo[ndx].pWaitDstStageMask = DE_NULL;
986 submitInfo[ndx].commandBufferCount = 1;
987 submitInfo[ndx].signalSemaphoreCount = 0;
988 submitInfo[ndx].pSignalSemaphores = DE_NULL;
989 }
990 }
991
testFences(Context & context)992 tcu::TestStatus testFences (Context& context)
993 {
994 TestLog& log = context.getTestContext().getLog();
995 const DeviceInterface& deviceInterface = context.getDeviceInterface();
996 const VkQueue queue = context.getUniversalQueue();
997 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
998 VkDevice device = context.getDevice();
999 VkResult waitStatus;
1000 VkResult fenceStatus;
1001 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator());
1002 VkSubmitInfo submitInfo;
1003 VkMappedMemoryRange range;
1004 void* resultImage;
1005
1006 const tcu::Vec4 vertices[] =
1007 {
1008 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1009 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1010 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1011 };
1012
1013 testContext.vertices = vertices;
1014 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1015 testContext.renderDimension = tcu::IVec2(256, 256);
1016 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1017
1018 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1019 generateWork(testContext);
1020
1021 initSubmitInfo(&submitInfo, 1);
1022 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1023
1024 // Default status is unsignaled
1025 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1026 if (fenceStatus != VK_NOT_READY)
1027 {
1028 log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1029 return tcu::TestStatus::fail("Fence in incorrect state");
1030 }
1031 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]);
1032 if (fenceStatus != VK_NOT_READY)
1033 {
1034 log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1035 return tcu::TestStatus::fail("Fence in incorrect state");
1036 }
1037
1038 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1039
1040 // Wait with timeout = 0
1041 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u);
1042 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1043 {
1044 // Will most likely end with VK_TIMEOUT
1045 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1046 return tcu::TestStatus::fail("Failed to wait for a single fence");
1047 }
1048
1049 // Wait with a reasonable timeout
1050 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT);
1051 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1052 {
1053 // \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient
1054 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1055 return tcu::TestStatus::fail("Failed to wait for a single fence");
1056 }
1057
1058 // Wait for work on fences[0] to actually complete
1059 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max());
1060 if (waitStatus != VK_SUCCESS)
1061 {
1062 log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage;
1063 return tcu::TestStatus::fail("failed to wait for a fence");
1064 }
1065
1066 // Wait until timeout on a fence that has not been submitted
1067 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1);
1068 if (waitStatus != VK_TIMEOUT)
1069 {
1070 log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage;
1071 return tcu::TestStatus::fail("failed to timeout on wait for single fence");
1072 }
1073
1074 // Check that the fence is signaled after the wait
1075 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1076 if (fenceStatus != VK_SUCCESS)
1077 {
1078 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1079 return tcu::TestStatus::fail("Fence in incorrect state");
1080 }
1081
1082 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1083 range.pNext = DE_NULL;
1084 range.memory = testContext.renderReadBuffer->getMemory();
1085 range.offset = 0;
1086 range.size = testContext.renderSize;
1087 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range));
1088 resultImage = testContext.renderReadBuffer->getHostPtr();
1089
1090 log << TestLog::Image( "result",
1091 "result",
1092 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1093 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1094 testContext.renderDimension.x(),
1095 testContext.renderDimension.y(),
1096 1,
1097 resultImage));
1098
1099 return TestStatus::pass("synchronization-fences passed");
1100 }
1101
createSemaphore(const DeviceInterface & deviceInterface,const VkDevice & device,const VkAllocationCallbacks * allocationCallbacks)1102 vk::refdetails::Checked<VkSemaphore> createSemaphore (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
1103 {
1104 VkSemaphoreCreateInfo semaCreateInfo;
1105 VkSemaphore semaphore;
1106
1107 semaCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1108 semaCreateInfo.pNext = DE_NULL;
1109 semaCreateInfo.flags = 0;
1110 VK_CHECK(deviceInterface.createSemaphore(device, &semaCreateInfo, allocationCallbacks, &semaphore));
1111
1112 return vk::check<VkSemaphore>(semaphore);
1113 }
1114
testSemaphores(Context & context)1115 tcu::TestStatus testSemaphores (Context& context)
1116 {
1117 TestLog& log = context.getTestContext().getLog();
1118 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1119 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1120 deUint32 queueFamilyIdx;
1121 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice, &queueFamilyIdx);
1122 const DeviceDriver deviceInterface (instanceInterface, *device);
1123 SimpleAllocator allocator (deviceInterface,
1124 *device,
1125 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice));
1126 VkQueue queue[2];
1127 VkResult testStatus;
1128 TestContext testContext1 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1129 TestContext testContext2 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1130 Unique<VkSemaphore> semaphore (createSemaphore(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkSemaphore>(deviceInterface, device.get(), DE_NULL));
1131 VkSubmitInfo submitInfo[2];
1132 VkMappedMemoryRange range;
1133 void* resultImage;
1134 const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1135
1136 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
1137 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
1138
1139 const tcu::Vec4 vertices1[] =
1140 {
1141 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1142 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1143 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1144 };
1145
1146 const tcu::Vec4 vertices2[] =
1147 {
1148 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1149 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1150 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1151 };
1152
1153 testContext1.vertices = vertices1;
1154 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1155 testContext1.renderDimension = tcu::IVec2(256, 256);
1156 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1157
1158 testContext2.vertices = vertices2;
1159 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1160 testContext2.renderDimension = tcu::IVec2(256, 256);
1161 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1162
1163 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool);
1164 generateWork(testContext1);
1165
1166 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool);
1167 generateWork(testContext2);
1168
1169 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1170
1171 // The difference between the two submit infos is that each will use a unique cmd buffer,
1172 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the
1173 // semaphore but not signal a semaphore
1174 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1175 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1176
1177 submitInfo[0].signalSemaphoreCount = 1;
1178 submitInfo[0].pSignalSemaphores = &semaphore.get();
1179 submitInfo[1].waitSemaphoreCount = 1;
1180 submitInfo[1].pWaitSemaphores = &semaphore.get();
1181 submitInfo[1].pWaitDstStageMask = &waitDstStageMask;
1182
1183 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1184
1185 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], true, DEFAULT_TIMEOUT);
1186 if (testStatus != VK_SUCCESS)
1187 {
1188 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1189 return tcu::TestStatus::fail("failed to wait for a set fence");
1190 }
1191
1192 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1193 range.pNext = DE_NULL;
1194 range.memory = testContext1.renderReadBuffer->getMemory();
1195 range.offset = 0;
1196 range.size = testContext1.renderSize;
1197 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1198 resultImage = testContext1.renderReadBuffer->getHostPtr();
1199
1200 log << TestLog::Image( "result",
1201 "result",
1202 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1203 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1204 testContext1.renderDimension.x(),
1205 testContext1.renderDimension.y(),
1206 1,
1207 resultImage));
1208
1209 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1210
1211 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], true, DEFAULT_TIMEOUT);
1212 if (testStatus != VK_SUCCESS)
1213 {
1214 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1215 return tcu::TestStatus::fail("failed to wait for a set fence");
1216 }
1217
1218 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1219 range.pNext = DE_NULL;
1220 range.memory = testContext2.renderReadBuffer->getMemory();
1221 range.offset = 0;
1222 range.size = testContext2.renderSize;
1223 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1224 resultImage = testContext2.renderReadBuffer->getHostPtr();
1225
1226 log << TestLog::Image( "result",
1227 "result",
1228 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1229 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1230 testContext2.renderDimension.x(),
1231 testContext2.renderDimension.y(),
1232 1,
1233 resultImage));
1234
1235 return tcu::TestStatus::pass("synchronization-semaphores passed");
1236 }
1237
createEvent(const DeviceInterface & deviceInterface,const VkDevice & device,const VkAllocationCallbacks * allocationCallbacks)1238 vk::refdetails::Checked<VkEvent> createEvent (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
1239 {
1240 VkEventCreateInfo eventCreateInfo;
1241 VkEvent event;
1242
1243 eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1244 eventCreateInfo.pNext = DE_NULL;
1245 eventCreateInfo.flags = 0;
1246 VK_CHECK(deviceInterface.createEvent(device, &eventCreateInfo, allocationCallbacks, &event));
1247
1248 return vk::check<VkEvent>(event);
1249 }
1250
testEvents(Context & context)1251 tcu::TestStatus testEvents (Context& context)
1252 {
1253 TestLog& log = context.getTestContext().getLog();
1254 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1255 VkDevice device = context.getDevice();
1256 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
1257 Allocator& allocator = context.getDefaultAllocator();
1258 VkQueue queue = context.getUniversalQueue();
1259 VkResult testStatus;
1260 VkResult eventStatus;
1261 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), allocator);
1262 Unique<VkEvent> event (createEvent(deviceInterface, device, (VkAllocationCallbacks*)DE_NULL), Deleter<VkEvent>(deviceInterface, device, DE_NULL));
1263 VkSubmitInfo submitInfo;
1264 VkMappedMemoryRange range;
1265 void* resultImage;
1266
1267 const tcu::Vec4 vertices1[] =
1268 {
1269 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1270 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1271 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1272 };
1273
1274 testContext.vertices = vertices1;
1275 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1276 testContext.renderDimension = tcu::IVec2(256, 256);
1277 testContext.waitEvent = true;
1278 testContext.event = event.get();
1279 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1280
1281 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1282 generateWork(testContext);
1283
1284 initSubmitInfo(&submitInfo, 1);
1285 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1286
1287 // 6.3 An event is initially in the unsignaled state
1288 eventStatus = deviceInterface.getEventStatus(device, event.get());
1289 if (eventStatus != VK_EVENT_RESET)
1290 {
1291 log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << getResultName(eventStatus) << TestLog::EndMessage;
1292 return tcu::TestStatus::fail("Event in incorrect status");
1293 }
1294
1295 // The recorded command buffer should wait at the top of the graphics pipe for an event signaled by the host and so should not
1296 // make forward progress as long as the event is not signaled
1297 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1298
1299 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 1);
1300 if (testStatus != VK_TIMEOUT)
1301 {
1302 log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set event from host." << TestLog::EndMessage;
1303 return tcu::TestStatus::fail("failed to wait for event set from host");
1304 }
1305
1306 // Should allow the recorded command buffer to finally make progress
1307 VK_CHECK(deviceInterface.setEvent(device, event.get()));
1308 eventStatus = deviceInterface.getEventStatus(device, event.get());
1309 if (eventStatus != VK_EVENT_SET)
1310 {
1311 log << TestLog::Message << "testEvents failed to transition event to signaled state via setEvent call from host" << TestLog::EndMessage;
1312 return tcu::TestStatus::fail("failed to signal event from host");
1313 }
1314
1315 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, ~(0ull));
1316 if (testStatus != VK_SUCCESS)
1317 {
1318 log << TestLog::Message << "testSynchronizationPrimitives failed to proceed after set event from host." << TestLog::EndMessage;
1319 return tcu::TestStatus::fail("failed to proceed after event set from host");
1320 }
1321
1322 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1323 range.pNext = DE_NULL;
1324 range.memory = testContext.renderReadBuffer->getMemory();
1325 range.offset = 0;
1326 range.size = testContext.renderSize;
1327 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range));
1328 resultImage = testContext.renderReadBuffer->getHostPtr();
1329
1330 log << TestLog::Image( "result",
1331 "result",
1332 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1333 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1334 testContext.renderDimension.x(),
1335 testContext.renderDimension.y(),
1336 1,
1337 resultImage));
1338
1339 return tcu::TestStatus::pass("synchronization-events passed");
1340 }
1341
1342 } // anonymous
1343
createSynchronizationTests(tcu::TestContext & textCtx)1344 tcu::TestCaseGroup* createSynchronizationTests (tcu::TestContext& textCtx)
1345 {
1346 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "synchronization", "Vulkan Synchronization Tests"));
1347
1348 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
1349 addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores);
1350 addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
1351
1352 return synchTests.release();
1353 }
1354
1355
1356 }; // vkt
1357