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