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