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