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