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