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