Add possibility to run tests in separate process (Vulkan SC only)
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCommandBuffersTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2015 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*--------------------------------------------------------------------*/
22
23 #include "vkDefs.hpp"
24 #include "vktTestCaseUtil.hpp"
25 #include "vkBuilderUtil.hpp"
26 #include "vkPlatform.hpp"
27 #include "vkRefUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkAllocationCallbackUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkBarrierUtil.hpp"
40 #include "vkBufferWithMemory.hpp"
41 #include "vkImageWithMemory.hpp"
42 #include "vktApiCommandBuffersTests.hpp"
43 #include "vktApiBufferComputeInstance.hpp"
44 #include "vktApiComputeInstanceResultBuffer.hpp"
45 #include "deSharedPtr.hpp"
46 #include "deRandom.hpp"
47 #include <sstream>
48 #include <limits>
49
50 namespace vkt
51 {
52 namespace api
53 {
54 namespace
55 {
56
57 using namespace vk;
58
59 typedef de::SharedPtr<vk::Unique<vk::VkEvent> > VkEventSp;
60
61 // Global variables
62 const deUint64                                                          INFINITE_TIMEOUT                = ~(deUint64)0u;
63
64
65 template <deUint32 NumBuffers>
66 class CommandBufferBareTestEnvironment
67 {
68 public:
69                                                                                         CommandBufferBareTestEnvironment        (Context&                                               context,
70                                                                                                                                                                  VkCommandPoolCreateFlags               commandPoolCreateFlags);
71
72         VkCommandPool                                                   getCommandPool                                          (void) const                                    { return *m_commandPool; }
73         VkCommandBuffer                                                 getCommandBuffer                                        (deUint32 bufferIndex) const;
74
75 protected:
76         Context&                                                                m_context;
77         const VkDevice                                                  m_device;
78         const DeviceInterface&                                  m_vkd;
79         const VkQueue                                                   m_queue;
80         const deUint32                                                  m_queueFamilyIndex;
81         Allocator&                                                              m_allocator;
82
83         // \note All VkCommandBuffers are allocated from m_commandPool so there is no need
84         //       to free them separately as the auto-generated dtor will do that through
85         //       destroying the pool.
86         Move<VkCommandPool>                                             m_commandPool;
87         VkCommandBuffer                                                 m_primaryCommandBuffers[NumBuffers];
88 };
89
90 template <deUint32 NumBuffers>
91 CommandBufferBareTestEnvironment<NumBuffers>::CommandBufferBareTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags)
92         : m_context                                                             (context)
93         , m_device                                                              (context.getDevice())
94         , m_vkd                                                                 (context.getDeviceInterface())
95         , m_queue                                                               (context.getUniversalQueue())
96         , m_queueFamilyIndex                                    (context.getUniversalQueueFamilyIndex())
97         , m_allocator                                                   (context.getDefaultAllocator())
98 {
99         m_commandPool = createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex);
100
101         const VkCommandBufferAllocateInfo               cmdBufferAllocateInfo   =
102         {
103                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // VkStructureType             sType;
104                 DE_NULL,                                                                                                        // const void*                 pNext;
105                 *m_commandPool,                                                                                         // VkCommandPool               commandPool;
106                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // VkCommandBufferLevel        level;
107                 NumBuffers                                                                                              // deUint32                    commandBufferCount;
108         };
109
110         VK_CHECK(m_vkd.allocateCommandBuffers(m_device, &cmdBufferAllocateInfo, m_primaryCommandBuffers));
111 }
112
113 template <deUint32 NumBuffers>
114 VkCommandBuffer CommandBufferBareTestEnvironment<NumBuffers>::getCommandBuffer(deUint32 bufferIndex) const
115 {
116         DE_ASSERT(bufferIndex < NumBuffers);
117         return m_primaryCommandBuffers[bufferIndex];
118 }
119
120 class CommandBufferRenderPassTestEnvironment : public CommandBufferBareTestEnvironment<1>
121 {
122 public:
123                                                                                         CommandBufferRenderPassTestEnvironment  (Context&                                               context,
124                                                                                                                                                                          VkCommandPoolCreateFlags               commandPoolCreateFlags);
125
126         VkRenderPass                                                    getRenderPass                                                   (void) const { return *m_renderPass; }
127         VkFramebuffer                                                   getFrameBuffer                                                  (void) const { return *m_frameBuffer; }
128         VkCommandBuffer                                                 getPrimaryCommandBuffer                                 (void) const { return getCommandBuffer(0); }
129         VkCommandBuffer                                                 getSecondaryCommandBuffer                               (void) const { return *m_secondaryCommandBuffer; }
130
131         void                                                                    beginPrimaryCommandBuffer                               (VkCommandBufferUsageFlags usageFlags);
132         void                                                                    beginSecondaryCommandBuffer                             (VkCommandBufferUsageFlags usageFlags, bool framebufferHint);
133         void                                                                    beginRenderPass                                                 (VkSubpassContents content);
134         void                                                                    submitPrimaryCommandBuffer                              (void);
135         de::MovePtr<tcu::TextureLevel>                  readColorAttachment                                             (void);
136
137         static const VkImageType                                DEFAULT_IMAGE_TYPE;
138         static const VkFormat                                   DEFAULT_IMAGE_FORMAT;
139         static const VkExtent3D                                 DEFAULT_IMAGE_SIZE;
140         static const VkRect2D                                   DEFAULT_IMAGE_AREA;
141
142 protected:
143
144         Move<VkImage>                                                   m_colorImage;
145         Move<VkImageView>                                               m_colorImageView;
146         Move<VkRenderPass>                                              m_renderPass;
147         Move<VkFramebuffer>                                             m_frameBuffer;
148         de::MovePtr<Allocation>                                 m_colorImageMemory;
149         Move<VkCommandBuffer>                                   m_secondaryCommandBuffer;
150
151 };
152
153 const VkImageType               CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_TYPE              = VK_IMAGE_TYPE_2D;
154 const VkFormat                  CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_FORMAT    = VK_FORMAT_R8G8B8A8_UINT;
155 const VkExtent3D                CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE              = {255, 255, 1};
156 const VkRect2D                  CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA              =
157 {
158         { 0u, 0u, },                                                                                            //      VkOffset2D      offset;
159         { DEFAULT_IMAGE_SIZE.width,     DEFAULT_IMAGE_SIZE.height },    //      VkExtent2D      extent;
160 };
161
162 CommandBufferRenderPassTestEnvironment::CommandBufferRenderPassTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags)
163         : CommandBufferBareTestEnvironment<1>           (context, commandPoolCreateFlags)
164 {
165         m_renderPass = makeRenderPass(m_vkd, m_device, DEFAULT_IMAGE_FORMAT);
166
167         {
168                 const VkImageCreateInfo                                 imageCreateInfo                 =
169                 {
170                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
171                         DE_NULL,                                                                        // const void*                          pNext;
172                         0u,                                                                                     // VkImageCreateFlags           flags;
173                         DEFAULT_IMAGE_TYPE,                                                     // VkImageType                          imageType;
174                         DEFAULT_IMAGE_FORMAT,                                           // VkFormat                                     format;
175                         DEFAULT_IMAGE_SIZE,                                                     // VkExtent3D                           extent;
176                         1,                                                                                      // deUint32                                     mipLevels;
177                         1,                                                                                      // deUint32                                     arrayLayers;
178                         VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits        samples;
179                         VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
180                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
181                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
182                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,                        // VkImageUsageFlags            usage;
183                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
184                         1,                                                                                      // deUint32                                     queueFamilyIndexCount;
185                         &m_queueFamilyIndex,                                            // const deUint32*                      pQueueFamilyIndices;
186                         VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
187                 };
188
189                 m_colorImage = createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
190         }
191
192         m_colorImageMemory = m_allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, *m_colorImage), MemoryRequirement::Any);
193         VK_CHECK(m_vkd.bindImageMemory(m_device, *m_colorImage, m_colorImageMemory->getMemory(), m_colorImageMemory->getOffset()));
194
195         {
196                 const VkImageViewCreateInfo                             imageViewCreateInfo             =
197                 {
198                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
199                         DE_NULL,                                                                        // const void*                                  pNext;
200                         0u,                                                                                     // VkImageViewCreateFlags               flags;
201                         *m_colorImage,                                                          // VkImage                                              image;
202                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
203                         DEFAULT_IMAGE_FORMAT,                                           // VkFormat                                             format;
204                         {
205                                 VK_COMPONENT_SWIZZLE_R,
206                                 VK_COMPONENT_SWIZZLE_G,
207                                 VK_COMPONENT_SWIZZLE_B,
208                                 VK_COMPONENT_SWIZZLE_A
209                         },                                                                                      // VkComponentMapping                   components;
210                         {
211                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
212                                 0u,                                                                                     // deUint32                                             baseMipLevel;
213                                 1u,                                                                                     // deUint32                                             mipLevels;
214                                 0u,                                                                                     // deUint32                                             baseArrayLayer;
215                                 1u,                                                                                     // deUint32                                             arraySize;
216                         },                                                                                      // VkImageSubresourceRange              subresourceRange;
217                 };
218
219                 m_colorImageView = createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL);
220         }
221
222         {
223                 const VkImageView                                               attachmentViews[1]              =
224                 {
225                         *m_colorImageView
226                 };
227
228                 const VkFramebufferCreateInfo                   framebufferCreateInfo   =
229                 {
230                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
231                         DE_NULL,                                                                        // const void*                          pNext;
232                         0u,                                                                                     // VkFramebufferCreateFlags     flags;
233                         *m_renderPass,                                                          // VkRenderPass                         renderPass;
234                         1,                                                                                      // deUint32                                     attachmentCount;
235                         attachmentViews,                                                        // const VkImageView*           pAttachments;
236                         DEFAULT_IMAGE_SIZE.width,                                       // deUint32                                     width;
237                         DEFAULT_IMAGE_SIZE.height,                                      // deUint32                                     height;
238                         1u,                                                                                     // deUint32                                     layers;
239                 };
240
241                 m_frameBuffer = createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL);
242         }
243
244         {
245                 const VkCommandBufferAllocateInfo               cmdBufferAllocateInfo   =
246                 {
247                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // VkStructureType             sType;
248                         DE_NULL,                                                                                                        // const void*                 pNext;
249                         *m_commandPool,                                                                                         // VkCommandPool               commandPool;
250                         VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      // VkCommandBufferLevel        level;
251                         1u                                                                                                                      // deUint32                    commandBufferCount;
252                 };
253
254                 m_secondaryCommandBuffer = allocateCommandBuffer(m_vkd, m_device, &cmdBufferAllocateInfo);
255
256         }
257 }
258
259 void CommandBufferRenderPassTestEnvironment::beginRenderPass(VkSubpassContents content)
260 {
261         vk::beginRenderPass(m_vkd, m_primaryCommandBuffers[0], *m_renderPass, *m_frameBuffer, DEFAULT_IMAGE_AREA, tcu::UVec4(17, 59, 163, 251), content);
262 }
263
264 void CommandBufferRenderPassTestEnvironment::beginPrimaryCommandBuffer(VkCommandBufferUsageFlags usageFlags)
265 {
266         beginCommandBuffer(m_vkd, m_primaryCommandBuffers[0], usageFlags);
267 }
268
269 void CommandBufferRenderPassTestEnvironment::beginSecondaryCommandBuffer(VkCommandBufferUsageFlags usageFlags, bool framebufferHint)
270 {
271         const VkCommandBufferInheritanceInfo    commandBufferInheritanceInfo =
272         {
273                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,              // VkStructureType                  sType;
274                 DE_NULL,                                                                                                // const void*                      pNext;
275                 *m_renderPass,                                                                                  // VkRenderPass                     renderPass;
276                 0u,                                                                                                             // deUint32                         subpass;
277                 (framebufferHint ? *m_frameBuffer : DE_NULL),                   // VkFramebuffer                    framebuffer;
278                 VK_FALSE,                                                                                               // VkBool32                         occlusionQueryEnable;
279                 0u,                                                                                                             // VkQueryControlFlags              queryFlags;
280                 0u                                                                                                              // VkQueryPipelineStatisticFlags    pipelineStatistics;
281         };
282
283         const VkCommandBufferBeginInfo                  commandBufferBeginInfo  =
284         {
285                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                          sType;
286                 DE_NULL,                                                                                                // const void*                              pNext;
287                 usageFlags,                                                                                             // VkCommandBufferUsageFlags                flags;
288                 &commandBufferInheritanceInfo                                                   // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
289         };
290
291         VK_CHECK(m_vkd.beginCommandBuffer(*m_secondaryCommandBuffer, &commandBufferBeginInfo));
292
293 }
294
295 void CommandBufferRenderPassTestEnvironment::submitPrimaryCommandBuffer(void)
296 {
297         submitCommandsAndWait(m_vkd, m_device, m_queue, *m_primaryCommandBuffers);
298 }
299
300 de::MovePtr<tcu::TextureLevel> CommandBufferRenderPassTestEnvironment::readColorAttachment ()
301 {
302         Move<VkBuffer>                                  buffer;
303         de::MovePtr<Allocation>                 bufferAlloc;
304         const tcu::TextureFormat                tcuFormat               = mapVkFormat(DEFAULT_IMAGE_FORMAT);
305         const VkDeviceSize                              pixelDataSize   = DEFAULT_IMAGE_SIZE.height * DEFAULT_IMAGE_SIZE.height * tcuFormat.getPixelSize();
306         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(tcuFormat, DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height));
307
308         // Create destination buffer
309         {
310                 const VkBufferCreateInfo bufferParams =
311                 {
312                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
313                         DE_NULL,                                                                        // const void*                  pNext;
314                         0u,                                                                                     // VkBufferCreateFlags  flags;
315                         pixelDataSize,                                                          // VkDeviceSize                 size;
316                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
317                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
318                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
319                         DE_NULL                                                                         // const deUint32*              pQueueFamilyIndices;
320                 };
321
322                 buffer          = createBuffer(m_vkd, m_device, &bufferParams);
323                 bufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, *buffer), MemoryRequirement::HostVisible);
324                 VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
325         }
326
327         // Copy image to buffer
328         beginPrimaryCommandBuffer(0);
329         copyImageToBuffer(m_vkd, m_primaryCommandBuffers[0], *m_colorImage, *buffer, tcu::IVec2(DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height));
330         endCommandBuffer(m_vkd, m_primaryCommandBuffers[0]);
331
332         submitPrimaryCommandBuffer();
333
334         // Read buffer data
335         invalidateAlloc(m_vkd, m_device, *bufferAlloc);
336         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
337
338         return resultLevel;
339 }
340
341
342 // Testcases
343 /********* 19.1. Command Pools (5.1 in VK 1.0 Spec) ***************************/
344 tcu::TestStatus createPoolNullParamsTest(Context& context)
345 {
346         const VkDevice                                                  vkDevice                                = context.getDevice();
347         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
348         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
349
350         createCommandPool(vk, vkDevice, 0u, queueFamilyIndex);
351
352         return tcu::TestStatus::pass("Command Pool allocated correctly.");
353 }
354
355 tcu::TestStatus createPoolNonNullAllocatorTest(Context& context)
356 {
357         const VkDevice                                                  vkDevice                                = context.getDevice();
358         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
359         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
360         const VkAllocationCallbacks*                    allocationCallbacks             = getSystemAllocator();
361
362         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
363         {
364                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
365                 DE_NULL,                                                                                                        // pNext;
366                 0u,                                                                                                                     // flags;
367                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
368         };
369
370         createCommandPool(vk, vkDevice, &cmdPoolParams, allocationCallbacks);
371
372         return tcu::TestStatus::pass("Command Pool allocated correctly.");
373 }
374
375 tcu::TestStatus createPoolTransientBitTest(Context& context)
376 {
377         const VkDevice                                                  vkDevice                                = context.getDevice();
378         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
379         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
380
381         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
382         {
383                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
384                 DE_NULL,                                                                                                        // pNext;
385                 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                                           // flags;
386                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
387         };
388
389         createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
390
391         return tcu::TestStatus::pass("Command Pool allocated correctly.");
392 }
393
394 tcu::TestStatus createPoolResetBitTest(Context& context)
395 {
396         const VkDevice                                                  vkDevice                                = context.getDevice();
397         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
398         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
399
400         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
401         {
402                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
403                 DE_NULL,                                                                                                        // pNext;
404                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
405                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
406         };
407
408         createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
409
410         return tcu::TestStatus::pass("Command Pool allocated correctly.");
411 }
412
413 tcu::TestStatus resetPoolReleaseResourcesBitTest(Context& context)
414 {
415         const VkDevice                                                  vkDevice                                = context.getDevice();
416         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
417         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
418
419         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
420         {
421                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
422                 DE_NULL,                                                                                                        // pNext;
423                 0u,                                                                                                                     // flags;
424                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
425         };
426
427         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
428
429         VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT));
430
431         return tcu::TestStatus::pass("Command Pool allocated correctly.");
432 }
433
434 tcu::TestStatus resetPoolNoFlagsTest(Context& context)
435 {
436         const VkDevice                                                  vkDevice                                = context.getDevice();
437         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
438         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
439
440         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
441         {
442                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
443                 DE_NULL,                                                                                                        // pNext;
444                 0u,                                                                                                                     // flags;
445                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
446         };
447
448         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
449
450         VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, 0u));
451
452         return tcu::TestStatus::pass("Command Pool allocated correctly.");
453 }
454
455 bool executeCommandBuffer (const VkDevice                       device,
456                                                    const DeviceInterface&       vk,
457                                                    const VkQueue                        queue,
458                                                    const VkCommandBuffer        commandBuffer,
459                                                    const bool                           exitBeforeEndCommandBuffer = false)
460 {
461         const Unique<VkEvent>                   event                                   (createEvent(vk, device));
462         beginCommandBuffer(vk, commandBuffer, 0u);
463         {
464                 const VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
465                 vk.cmdSetEvent(commandBuffer, *event, stageMask);
466                 if (exitBeforeEndCommandBuffer)
467                         return exitBeforeEndCommandBuffer;
468         }
469         endCommandBuffer(vk, commandBuffer);
470
471         submitCommandsAndWait(vk, device, queue, commandBuffer);
472
473         // check if buffer has been executed
474         const VkResult result = vk.getEventStatus(device, *event);
475         return result == VK_EVENT_SET;
476 }
477
478 tcu::TestStatus resetPoolReuseTest (Context& context)
479 {
480         const VkDevice                                          vkDevice                        = context.getDevice();
481         const DeviceInterface&                          vk                                      = context.getDeviceInterface();
482         const deUint32                                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
483         const VkQueue                                           queue                           = context.getUniversalQueue();
484
485         const VkCommandPoolCreateInfo           cmdPoolParams           =
486         {
487                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,     // sType;
488                 DE_NULL,                                                                        // pNext;
489                 0u,                                                                                     // flags;
490                 queueFamilyIndex                                                        // queueFamilyIndex;
491         };
492         const Unique<VkCommandPool>                     cmdPool                         (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
493         const VkCommandBufferAllocateInfo       cmdBufParams            =
494         {
495                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
496                 DE_NULL,                                                                                // pNext;
497                 *cmdPool,                                                                               // commandPool;
498                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // level;
499                 1u                                                                                              // bufferCount;
500         };
501         const Move<VkCommandBuffer>                     commandBuffers[]        =
502         {
503                 allocateCommandBuffer(vk, vkDevice, &cmdBufParams),
504                 allocateCommandBuffer(vk, vkDevice, &cmdBufParams)
505         };
506
507         if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[0])))
508                 return tcu::TestStatus::fail("Failed");
509         if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[1]), true))
510                 return tcu::TestStatus::fail("Failed");
511
512         VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT));
513
514         if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[0])))
515                 return tcu::TestStatus::fail("Failed");
516         if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[1])))
517                 return tcu::TestStatus::fail("Failed");
518
519         {
520                 const Unique<VkCommandBuffer> afterResetCommandBuffers(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
521                 if (!executeCommandBuffer(vkDevice, vk, queue, *afterResetCommandBuffers))
522                         return tcu::TestStatus::fail("Failed");
523         }
524
525         return tcu::TestStatus::pass("Passed");
526 }
527
528 /******** 19.2. Command Buffer Lifetime (5.2 in VK 1.0 Spec) ******************/
529 tcu::TestStatus allocatePrimaryBufferTest(Context& context)
530 {
531         const VkDevice                                                  vkDevice                                = context.getDevice();
532         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
533         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
534
535         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
536         {
537                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
538                 DE_NULL,                                                                                                        // pNext;
539                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
540                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
541         };
542         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
543
544         // Command buffer
545         const VkCommandBufferAllocateInfo               cmdBufParams                    =
546         {
547                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
548                 DE_NULL,                                                                                                        // pNext;
549                 *cmdPool,                                                                                                       // commandPool;
550                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
551                 1u,                                                                                                                     // bufferCount;
552         };
553         const Unique<VkCommandBuffer>                   cmdBuf                                  (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
554
555         return tcu::TestStatus::pass("Buffer was created correctly.");
556 }
557
558 tcu::TestStatus allocateManyPrimaryBuffersTest(Context& context)
559 {
560
561         const VkDevice                                                  vkDevice                                = context.getDevice();
562         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
563         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
564
565         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
566         {
567                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
568                 DE_NULL,                                                                                                        //      const void*                                     pNext;
569                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
570                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
571         };
572         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
573
574         // \todo Determining the minimum number of command buffers should be a function of available system memory and driver capabilities.
575 #if (DE_PTR_SIZE == 4)
576         const unsigned minCommandBuffer = 1024;
577 #else
578         const unsigned minCommandBuffer = 10000;
579 #endif
580
581         // Command buffer
582         const VkCommandBufferAllocateInfo               cmdBufParams                    =
583         {
584                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
585                 DE_NULL,                                                                                                        //      const void*                                     pNext;
586                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
587                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
588                 minCommandBuffer,                                                                                       //      uint32_t                                        bufferCount;
589         };
590
591         // do not keep the handles to buffers, as they will be freed with command pool
592
593         // allocate the minimum required amount of buffers
594         VkCommandBuffer cmdBuffers[minCommandBuffer];
595         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
596
597         std::ostringstream out;
598         out << "allocateManyPrimaryBuffersTest succeded: created " << minCommandBuffer << " command buffers";
599
600         return tcu::TestStatus::pass(out.str());
601 }
602
603 tcu::TestStatus allocateSecondaryBufferTest(Context& context)
604 {
605         const VkDevice                                                  vkDevice                                = context.getDevice();
606         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
607         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
608
609         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
610         {
611                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
612                 DE_NULL,                                                                                                        // pNext;
613                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
614                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
615         };
616         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
617
618         // Command buffer
619         const VkCommandBufferAllocateInfo               cmdBufParams                    =
620         {
621                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
622                 DE_NULL,                                                                                                        // pNext;
623                 *cmdPool,                                                                                                       // commandPool;
624                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      // level;
625                 1u,                                                                                                                     // bufferCount;
626         };
627         const Unique<VkCommandBuffer>                   cmdBuf                                  (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
628
629         return tcu::TestStatus::pass("Buffer was created correctly.");
630 }
631
632 tcu::TestStatus allocateManySecondaryBuffersTest(Context& context)
633 {
634
635         const VkDevice                                                  vkDevice                                = context.getDevice();
636         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
637         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
638
639         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
640         {
641                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
642                 DE_NULL,                                                                                                        //      const void*                                     pNext;
643                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
644                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
645         };
646         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
647
648         // \todo Determining the minimum number of command buffers should be a function of available system memory and driver capabilities.
649 #if (DE_PTR_SIZE == 4)
650         const unsigned minCommandBuffer = 1024;
651 #else
652         const unsigned minCommandBuffer = 10000;
653 #endif
654
655         // Command buffer
656         const VkCommandBufferAllocateInfo               cmdBufParams                    =
657         {
658                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
659                 DE_NULL,                                                                                                        //      const void*                                     pNext;
660                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
661                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
662                 minCommandBuffer,                                                                                       //      uint32_t                                        bufferCount;
663         };
664
665         // do not keep the handles to buffers, as they will be freed with command pool
666
667         // allocate the minimum required amount of buffers
668         VkCommandBuffer cmdBuffers[minCommandBuffer];
669         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
670
671         std::ostringstream out;
672         out << "allocateManySecondaryBuffersTest succeded: created " << minCommandBuffer << " command buffers";
673
674         return tcu::TestStatus::pass(out.str());
675 }
676
677 tcu::TestStatus executePrimaryBufferTest(Context& context)
678 {
679         const VkDevice                                                  vkDevice                                = context.getDevice();
680         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
681         const VkQueue                                                   queue                                   = context.getUniversalQueue();
682         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
683
684         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
685         {
686                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
687                 DE_NULL,                                                                                                        //      const void*                                     pNext;
688                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
689                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
690         };
691         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
692
693         // Command buffer
694         const VkCommandBufferAllocateInfo               cmdBufParams                    =
695         {
696                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
697                 DE_NULL,                                                                                                        //      const void*                                     pNext;
698                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
699                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
700                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
701         };
702         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
703
704         // create event that will be used to check if secondary command buffer has been executed
705         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
706
707         // reset event
708         VK_CHECK(vk.resetEvent(vkDevice, *event));
709
710         // record primary command buffer
711         beginCommandBuffer(vk, *primCmdBuf, 0u);
712         {
713                 // allow execution of event during every stage of pipeline
714                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
715
716                 // record setting event
717                 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
718         }
719         endCommandBuffer(vk, *primCmdBuf);
720
721         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
722
723         // check if buffer has been executed
724         VkResult result = vk.getEventStatus(vkDevice,*event);
725         if (result == VK_EVENT_SET)
726                 return tcu::TestStatus::pass("Execute Primary Command Buffer succeeded");
727
728         return tcu::TestStatus::fail("Execute Primary Command Buffer FAILED");
729 }
730
731 tcu::TestStatus executeLargePrimaryBufferTest(Context& context)
732 {
733         const VkDevice                                                  vkDevice                                = context.getDevice();
734         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
735         const VkQueue                                                   queue                                   = context.getUniversalQueue();
736         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
737         const deUint32                                                  LARGE_BUFFER_SIZE               = 10000;
738
739         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
740         {
741                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
742                 DE_NULL,                                                                                                        //      const void*                                     pNext;
743                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
744                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
745         };
746         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
747
748         // Command buffer
749         const VkCommandBufferAllocateInfo               cmdBufParams                    =
750         {
751                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
752                 DE_NULL,                                                                                                        //      const void*                                     pNext;
753                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
754                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
755                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
756         };
757         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
758
759         std::vector<VkEventSp>                                  events;
760         for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
761                 events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
762
763         // record primary command buffer
764         beginCommandBuffer(vk, *primCmdBuf, 0u);
765         {
766                 // set all the events
767                 for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
768                 {
769                         vk.cmdSetEvent(*primCmdBuf, events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
770                 }
771         }
772         endCommandBuffer(vk, *primCmdBuf);
773
774         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
775
776         // check if the buffer was executed correctly - all events had their status
777         // changed
778         tcu::TestStatus testResult = tcu::TestStatus::incomplete();
779
780         for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
781         {
782                 if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
783                 {
784                         testResult = tcu::TestStatus::fail("An event was not set.");
785                         break;
786                 }
787         }
788
789         if (!testResult.isComplete())
790                 testResult = tcu::TestStatus::pass("All events set correctly.");
791
792         return testResult;
793 }
794
795 tcu::TestStatus resetBufferImplicitlyTest(Context& context)
796 {
797         const VkDevice                                                  vkDevice                                = context.getDevice();
798         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
799         const VkQueue                                                   queue                                   = context.getUniversalQueue();
800         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
801
802         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
803         {
804                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
805                 DE_NULL,                                                                                                        // pNext;
806                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
807                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
808         };
809         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
810
811         // Command buffer
812         const VkCommandBufferAllocateInfo               cmdBufParams                    =
813         {
814                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
815                 DE_NULL,                                                                                                        // pNext;
816                 *cmdPool,                                                                                                       // pool;
817                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
818                 1u,                                                                                                                     // bufferCount;
819         };
820         const Unique<VkCommandBuffer>                   cmdBuf                                          (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
821
822         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
823
824         // Put the command buffer in recording state.
825         beginCommandBuffer(vk, *cmdBuf, 0u);
826         {
827                 // Set the event
828                 vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
829         }
830         endCommandBuffer(vk, *cmdBuf);
831
832         submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
833
834         // Check if the buffer was executed
835         if (vk.getEventStatus(vkDevice, *event) != VK_EVENT_SET)
836                 return tcu::TestStatus::fail("Failed to set the event.");
837
838         // Reset the event
839         vk.resetEvent(vkDevice, *event);
840         if(vk.getEventStatus(vkDevice, *event) != VK_EVENT_RESET)
841                 return tcu::TestStatus::fail("Failed to reset the event.");
842
843         // Reset the command buffer by putting it in recording state again. This
844         // should empty the command buffer.
845         beginCommandBuffer(vk, *cmdBuf, 0u);
846         endCommandBuffer(vk, *cmdBuf);
847
848         // Submit the command buffer after resetting. It should have no commands
849         // recorded, so the event should remain unsignaled.
850         submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
851
852         // Check if the event remained unset.
853         if(vk.getEventStatus(vkDevice, *event) == VK_EVENT_RESET)
854                 return tcu::TestStatus::pass("Buffer was reset correctly.");
855         else
856                 return tcu::TestStatus::fail("Buffer was not reset correctly.");
857 }
858
859 using  de::SharedPtr;
860 typedef SharedPtr<Unique<VkEvent> >                     VkEventShared;
861
862 template<typename T>
863 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
864 {
865         return SharedPtr<Unique<T> >(new Unique<T>(move));
866 }
867
868 bool submitAndCheck (Context& context, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events)
869 {
870         const VkDevice                                          vkDevice        = context.getDevice();
871         const DeviceInterface&                          vk                      = context.getDeviceInterface();
872         const VkQueue                                           queue           = context.getUniversalQueue();
873         const Unique<VkFence>                           fence           (createFence(vk, vkDevice));
874
875         const VkSubmitInfo                                      submitInfo      =
876         {
877                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                          // sType
878                 DE_NULL,                                                                        // pNext
879                 0u,                                                                                     // waitSemaphoreCount
880                 DE_NULL,                                                                        // pWaitSemaphores
881                 (const VkPipelineStageFlags*)DE_NULL,           // pWaitDstStageMask
882                 static_cast<deUint32>(cmdBuffers.size()),       // commandBufferCount
883                 &cmdBuffers[0],                                                         // pCommandBuffers
884                 0u,                                                                                     // signalSemaphoreCount
885                 DE_NULL,                                                                        // pSignalSemaphores
886         };
887
888         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
889         VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT));
890
891         for(int eventNdx = 0; eventNdx < static_cast<int>(events.size()); ++eventNdx)
892         {
893                 if (vk.getEventStatus(vkDevice, **events[eventNdx]) != VK_EVENT_SET)
894                         return false;
895                 vk.resetEvent(vkDevice, **events[eventNdx]);
896         }
897
898         return true;
899 }
900
901 void createCommadBuffers (const DeviceInterface&                vk,
902                                                   const VkDevice                                vkDevice,
903                                                   deUint32                                              bufferCount,
904                                                   VkCommandPool                                 pool,
905                                                   const VkCommandBufferLevel    cmdBufferLevel,
906                                                   VkCommandBuffer*                              pCommandBuffers)
907 {
908         const VkCommandBufferAllocateInfo               cmdBufParams    =
909         {
910                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, //      VkStructureType                         sType;
911                 DE_NULL,                                                                                //      const void*                                     pNext;
912                 pool,                                                                                   //      VkCommandPool                           pool;
913                 cmdBufferLevel,                                                                 //      VkCommandBufferLevel            level;
914                 bufferCount,                                                                    //      uint32_t                                        bufferCount;
915         };
916         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, pCommandBuffers));
917 }
918
919 void addCommandsToBuffer (const DeviceInterface& vk, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events)
920 {
921         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
922         {
923                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
924                 DE_NULL,
925                 (VkRenderPass)0u,                                                               // renderPass
926                 0u,                                                                                             // subpass
927                 (VkFramebuffer)0u,                                                              // framebuffer
928                 VK_FALSE,                                                                               // occlusionQueryEnable
929                 (VkQueryControlFlags)0u,                                                // queryFlags
930                 (VkQueryPipelineStatisticFlags)0u,                              // pipelineStatistics
931         };
932
933         const VkCommandBufferBeginInfo          cmdBufBeginInfo =
934         {
935                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // sType
936                 DE_NULL,                                                                                // pNext
937                 0u,                                                                                             // flags
938                 &secCmdBufInheritInfo,                                                  // pInheritanceInfo;
939         };
940
941         for(int bufferNdx = 0; bufferNdx < static_cast<int>(cmdBuffers.size()); ++bufferNdx)
942         {
943                 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[bufferNdx], &cmdBufBeginInfo));
944                 vk.cmdSetEvent(cmdBuffers[bufferNdx], **events[bufferNdx % events.size()], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
945                 endCommandBuffer(vk, cmdBuffers[bufferNdx]);
946         }
947 }
948
949 bool executeSecondaryCmdBuffer (Context&                                                context,
950                                                                 VkCommandPool                                   pool,
951                                                                 std::vector<VkCommandBuffer>&   cmdBuffersSecondary,
952                                                                 std::vector <VkEventShared>&    events)
953 {
954         const VkDevice                                  vkDevice                = context.getDevice();
955         const DeviceInterface&                  vk                              = context.getDeviceInterface();
956         std::vector<VkCommandBuffer>    cmdBuffer               (1);
957
958         createCommadBuffers(vk, vkDevice, 1u, pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, &cmdBuffer[0]);
959         beginCommandBuffer(vk, cmdBuffer[0], 0u);
960         vk.cmdExecuteCommands(cmdBuffer[0], static_cast<deUint32>(cmdBuffersSecondary.size()), &cmdBuffersSecondary[0]);
961         endCommandBuffer(vk, cmdBuffer[0]);
962
963         bool returnValue = submitAndCheck(context, cmdBuffer, events);
964         vk.freeCommandBuffers(vkDevice, pool, 1u, &cmdBuffer[0]);
965         return returnValue;
966 }
967
968 #ifndef CTS_USES_VULKANSC
969
970 tcu::TestStatus trimCommandPoolTest (Context& context, const VkCommandBufferLevel cmdBufferLevel)
971 {
972         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
973                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
974
975         const VkDevice                                                  vkDevice                                = context.getDevice();
976         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
977         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
978
979         //test parameters
980         const deUint32                                                  cmdBufferIterationCount = 300u;
981         const deUint32                                                  cmdBufferCount                  = 10u;
982
983         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
984         {
985                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
986                 DE_NULL,                                                                                                        // pNext;
987                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
988                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
989         };
990         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
991
992         std::vector <VkEventShared>                             events;
993         for (deUint32 ndx = 0u; ndx < cmdBufferCount; ++ndx)
994                 events.push_back(makeSharedPtr(createEvent(vk, vkDevice)));
995
996         {
997                 std::vector<VkCommandBuffer> cmdBuffers(cmdBufferCount);
998                 createCommadBuffers(vk, vkDevice, cmdBufferCount, *cmdPool, cmdBufferLevel, &cmdBuffers[0]);
999
1000                 for (deUint32 cmdBufferIterationrNdx = 0; cmdBufferIterationrNdx < cmdBufferIterationCount; ++cmdBufferIterationrNdx)
1001                 {
1002                         addCommandsToBuffer(vk, cmdBuffers, events);
1003
1004                         //Peak, situation when we use a lot more command buffers
1005                         if (cmdBufferIterationrNdx % 10u == 0)
1006                         {
1007                                 std::vector<VkCommandBuffer> cmdBuffersPeak(cmdBufferCount * 10u);
1008                                 createCommadBuffers(vk, vkDevice, static_cast<deUint32>(cmdBuffersPeak.size()), *cmdPool, cmdBufferLevel, &cmdBuffersPeak[0]);
1009                                 addCommandsToBuffer(vk, cmdBuffersPeak, events);
1010
1011                                 switch(cmdBufferLevel)
1012                                 {
1013                                         case VK_COMMAND_BUFFER_LEVEL_PRIMARY:
1014                                                 if (!submitAndCheck(context, cmdBuffersPeak, events))
1015                                                         return tcu::TestStatus::fail("Fail");
1016                                                 break;
1017                                         case VK_COMMAND_BUFFER_LEVEL_SECONDARY:
1018                                                 if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffersPeak, events))
1019                                                         return tcu::TestStatus::fail("Fail");
1020                                                 break;
1021                                         default:
1022                                                 DE_ASSERT(0);
1023                                 }
1024                                 vk.freeCommandBuffers(vkDevice, *cmdPool, static_cast<deUint32>(cmdBuffersPeak.size()), &cmdBuffersPeak[0]);
1025                         }
1026
1027                         vk.trimCommandPool(vkDevice, *cmdPool, (VkCommandPoolTrimFlags)0);
1028
1029                         switch(cmdBufferLevel)
1030                         {
1031                                 case VK_COMMAND_BUFFER_LEVEL_PRIMARY:
1032                                         if (!submitAndCheck(context, cmdBuffers, events))
1033                                                 return tcu::TestStatus::fail("Fail");
1034                                         break;
1035                                 case VK_COMMAND_BUFFER_LEVEL_SECONDARY:
1036                                         if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffers, events))
1037                                                 return tcu::TestStatus::fail("Fail");
1038                                         break;
1039                                 default:
1040                                         DE_ASSERT(0);
1041                         }
1042
1043                         for (deUint32 bufferNdx = cmdBufferIterationrNdx % 3u; bufferNdx < cmdBufferCount; bufferNdx+=2u)
1044                         {
1045                                 vk.freeCommandBuffers(vkDevice, *cmdPool, 1u, &cmdBuffers[bufferNdx]);
1046                                 createCommadBuffers(vk, vkDevice, 1u, *cmdPool, cmdBufferLevel, &cmdBuffers[bufferNdx]);
1047                         }
1048                 }
1049         }
1050
1051         return tcu::TestStatus::pass("Pass");
1052 }
1053
1054 #endif // CTS_USES_VULKANSC
1055
1056 /******** 19.3. Command Buffer Recording (5.3 in VK 1.0 Spec) *****************/
1057 tcu::TestStatus recordSinglePrimaryBufferTest(Context& context)
1058 {
1059         const VkDevice                                                  vkDevice                                = context.getDevice();
1060         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1061         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1062
1063         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1064         {
1065                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1066                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1067                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1068                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1069         };
1070         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1071
1072         // Command buffer
1073         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1074         {
1075                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1076                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1077                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1078                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1079                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1080         };
1081         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1082
1083         // create event that will be used to check if secondary command buffer has been executed
1084         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1085
1086         // record primary command buffer
1087         beginCommandBuffer(vk, *primCmdBuf, 0u);
1088         {
1089                 // record setting event
1090                 vk.cmdSetEvent(*primCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1091         }
1092         endCommandBuffer(vk, *primCmdBuf);
1093
1094         return tcu::TestStatus::pass("Primary buffer recorded successfully.");
1095 }
1096
1097 tcu::TestStatus recordLargePrimaryBufferTest(Context &context)
1098 {
1099         const VkDevice                                                  vkDevice                                = context.getDevice();
1100         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1101         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1102         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1103
1104         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1105         {
1106                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1107                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1108                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1109                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1110         };
1111         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1112
1113         // Command buffer
1114         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1115         {
1116                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1117                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1118                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1119                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1120                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1121         };
1122         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1123
1124         // create event that will be used to check if secondary command buffer has been executed
1125         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1126
1127         // reset event
1128         VK_CHECK(vk.resetEvent(vkDevice, *event));
1129
1130         // record primary command buffer
1131         beginCommandBuffer(vk, *primCmdBuf, 0u);
1132         {
1133                 // allow execution of event during every stage of pipeline
1134                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1135
1136                 // define minimal amount of commands to accept
1137                 const long long unsigned minNumCommands = 10000llu;
1138
1139                 for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands )
1140                 {
1141                         // record setting event
1142                         vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1143
1144                         // record resetting event
1145                         vk.cmdResetEvent(*primCmdBuf, *event,stageMask);
1146                 };
1147
1148         }
1149         endCommandBuffer(vk, *primCmdBuf);
1150
1151         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1152
1153         return tcu::TestStatus::pass("hugeTest succeeded");
1154 }
1155
1156 tcu::TestStatus recordSingleSecondaryBufferTest(Context& context)
1157 {
1158         const VkDevice                                                  vkDevice                                = context.getDevice();
1159         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1160         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1161
1162         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1163         {
1164                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1165                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1166                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1167                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1168         };
1169         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1170
1171         // Command buffer
1172         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1173         {
1174                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1175                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1176                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1177                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
1178                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1179         };
1180         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1181
1182         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
1183         {
1184                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1185                 DE_NULL,
1186                 (VkRenderPass)0u,                                                                                       // renderPass
1187                 0u,                                                                                                                     // subpass
1188                 (VkFramebuffer)0u,                                                                                      // framebuffer
1189                 VK_FALSE,                                                                                                       // occlusionQueryEnable
1190                 (VkQueryControlFlags)0u,                                                                        // queryFlags
1191                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
1192         };
1193         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
1194         {
1195                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1196                 DE_NULL,
1197                 0,                                                                                                                      // flags
1198                 &secCmdBufInheritInfo,
1199         };
1200
1201         // create event that will be used to check if secondary command buffer has been executed
1202         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1203
1204         // record primary command buffer
1205         VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1206         {
1207                 // record setting event
1208                 vk.cmdSetEvent(*secCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1209         }
1210         endCommandBuffer(vk, *secCmdBuf);
1211
1212         return tcu::TestStatus::pass("Secondary buffer recorded successfully.");
1213 }
1214
1215 tcu::TestStatus recordLargeSecondaryBufferTest(Context &context)
1216 {
1217         const VkDevice                                                  vkDevice                                = context.getDevice();
1218         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1219         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1220         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1221
1222         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1223         {
1224                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1225                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1226                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1227                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1228         };
1229         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1230
1231         // Command buffer
1232         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1233         {
1234                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1235                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1236                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1237                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1238                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1239         };
1240         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1241
1242         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
1243         {
1244                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1245                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1246                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1247                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
1248                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1249         };
1250         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1251
1252         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
1253         {
1254                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1255                 DE_NULL,
1256                 (VkRenderPass)0u,                                                                                       // renderPass
1257                 0u,                                                                                                                     // subpass
1258                 (VkFramebuffer)0u,                                                                                      // framebuffer
1259                 VK_FALSE,                                                                                                       // occlusionQueryEnable
1260                 (VkQueryControlFlags)0u,                                                                        // queryFlags
1261                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
1262         };
1263         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
1264         {
1265                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1266                 DE_NULL,
1267                 0,                                                                                                                      // flags
1268                 &secCmdBufInheritInfo,
1269         };
1270
1271         // create event that will be used to check if secondary command buffer has been executed
1272         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1273
1274         // reset event
1275         VK_CHECK(vk.resetEvent(vkDevice, *event));
1276
1277         // record primary command buffer
1278         beginCommandBuffer(vk, *primCmdBuf, 0u);
1279         {
1280                 // record secondary command buffer
1281                 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1282                 {
1283                         // allow execution of event during every stage of pipeline
1284                         VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1285
1286                         // define minimal amount of commands to accept
1287                         const long long unsigned minNumCommands = 10000llu;
1288
1289                         for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands )
1290                         {
1291                                 // record setting event
1292                                 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1293
1294                                 // record resetting event
1295                                 vk.cmdResetEvent(*primCmdBuf, *event,stageMask);
1296                         };
1297                 }
1298
1299                 // end recording of secondary buffers
1300                 endCommandBuffer(vk, *secCmdBuf);
1301
1302                 // execute secondary buffer
1303                 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
1304         }
1305         endCommandBuffer(vk, *primCmdBuf);
1306
1307         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1308
1309         return tcu::TestStatus::pass("hugeTest succeeded");
1310 }
1311
1312 tcu::TestStatus submitPrimaryBufferTwiceTest(Context& context)
1313 {
1314         const VkDevice                                                  vkDevice                                = context.getDevice();
1315         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1316         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1317         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1318
1319         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1320         {
1321                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1322                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1323                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1324                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1325         };
1326         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1327
1328         // Command buffer
1329         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1330         {
1331                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1332                 DE_NULL,                                                                                                        //      const void*                             pNext;
1333                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1334                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1335                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1336         };
1337         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1338
1339         // create event that will be used to check if secondary command buffer has been executed
1340         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1341
1342         // reset event
1343         VK_CHECK(vk.resetEvent(vkDevice, *event));
1344
1345         // record primary command buffer
1346         beginCommandBuffer(vk, *primCmdBuf, 0u);
1347         {
1348                 // allow execution of event during every stage of pipeline
1349                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1350
1351                 // record setting event
1352                 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1353         }
1354         endCommandBuffer(vk, *primCmdBuf);
1355
1356         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1357
1358         // check if buffer has been executed
1359         VkResult result = vk.getEventStatus(vkDevice,*event);
1360         if (result != VK_EVENT_SET)
1361                 return tcu::TestStatus::fail("Submit Twice Test FAILED");
1362
1363         // reset event
1364         VK_CHECK(vk.resetEvent(vkDevice, *event));
1365
1366         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1367
1368         // check if buffer has been executed
1369         result = vk.getEventStatus(vkDevice,*event);
1370         if (result != VK_EVENT_SET)
1371                 return tcu::TestStatus::fail("Submit Twice Test FAILED");
1372         else
1373                 return tcu::TestStatus::pass("Submit Twice Test succeeded");
1374 }
1375
1376 tcu::TestStatus submitSecondaryBufferTwiceTest(Context& context)
1377 {
1378         const VkDevice                                                  vkDevice                                = context.getDevice();
1379         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1380         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1381         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1382
1383         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1384         {
1385                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1386                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1387                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1388                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1389         };
1390
1391         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1392
1393         // Command buffer
1394         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1395         {
1396                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1397                 DE_NULL,                                                                                                        //      const void*                             pNext;
1398                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1399                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1400                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1401         };
1402
1403         const Unique<VkCommandBuffer>                   primCmdBuf1                             (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1404         const Unique<VkCommandBuffer>                   primCmdBuf2                             (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1405
1406         // Secondary Command buffer
1407         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
1408         {
1409                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1410                 DE_NULL,                                                                                                        //      const void*                             pNext;
1411                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1412                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
1413                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1414         };
1415         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1416
1417         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
1418         {
1419                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1420                 DE_NULL,
1421                 (VkRenderPass)0u,                                                                                       // renderPass
1422                 0u,                                                                                                                     // subpass
1423                 (VkFramebuffer)0u,                                                                                      // framebuffer
1424                 VK_FALSE,                                                                                                       // occlusionQueryEnable
1425                 (VkQueryControlFlags)0u,                                                                        // queryFlags
1426                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
1427         };
1428         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
1429         {
1430                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1431                 DE_NULL,
1432                 0u,                                                                                                                     // flags
1433                 &secCmdBufInheritInfo,
1434         };
1435
1436         // create event that will be used to check if secondary command buffer has been executed
1437         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1438
1439         // reset event
1440         VK_CHECK(vk.resetEvent(vkDevice, *event));
1441
1442         // record first primary command buffer
1443         beginCommandBuffer(vk, *primCmdBuf1, 0u);
1444         {
1445                 // record secondary command buffer
1446                 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1447                 {
1448                         // allow execution of event during every stage of pipeline
1449                         VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1450
1451                         // record setting event
1452                         vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1453                 }
1454
1455                 // end recording of secondary buffers
1456                 endCommandBuffer(vk, *secCmdBuf);
1457
1458                 // execute secondary buffer
1459                 vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get());
1460         }
1461         endCommandBuffer(vk, *primCmdBuf1);
1462
1463         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf1.get());
1464
1465         // check if secondary buffer has been executed
1466         VkResult result = vk.getEventStatus(vkDevice,*event);
1467         if (result != VK_EVENT_SET)
1468                 return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED");
1469
1470         // reset first primary buffer
1471         vk.resetCommandBuffer( *primCmdBuf1, 0u);
1472
1473         // reset event to allow receiving it again
1474         VK_CHECK(vk.resetEvent(vkDevice, *event));
1475
1476         // record second primary command buffer
1477         beginCommandBuffer(vk, *primCmdBuf2, 0u);
1478         {
1479                 // execute secondary buffer
1480                 vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get());
1481         }
1482         // end recording
1483         endCommandBuffer(vk, *primCmdBuf2);
1484
1485         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf2.get());
1486
1487         // check if secondary buffer has been executed
1488         result = vk.getEventStatus(vkDevice,*event);
1489         if (result != VK_EVENT_SET)
1490                 return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED");
1491         else
1492                 return tcu::TestStatus::pass("Submit Twice Secondary Command Buffer succeeded");
1493 }
1494
1495 tcu::TestStatus oneTimeSubmitFlagPrimaryBufferTest(Context& context)
1496 {
1497         const VkDevice                                                  vkDevice                                = context.getDevice();
1498         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1499         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1500         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1501
1502         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1503         {
1504                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1505                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1506                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1507                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1508         };
1509         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1510
1511         // Command buffer
1512         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1513         {
1514                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1515                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1516                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1517                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1518                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1519         };
1520         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1521
1522         // create event that will be used to check if secondary command buffer has been executed
1523         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1524
1525         // reset event
1526         VK_CHECK(vk.resetEvent(vkDevice, *event));
1527
1528         // record primary command buffer
1529         beginCommandBuffer(vk, *primCmdBuf);
1530         {
1531                 // allow execution of event during every stage of pipeline
1532                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1533
1534                 // record setting event
1535                 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1536         }
1537         endCommandBuffer(vk, *primCmdBuf);
1538
1539         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1540
1541         // check if buffer has been executed
1542         VkResult result = vk.getEventStatus(vkDevice,*event);
1543         if (result != VK_EVENT_SET)
1544                 return tcu::TestStatus::fail("oneTimeSubmitFlagPrimaryBufferTest FAILED");
1545
1546         // record primary command buffer again - implicit reset because of VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
1547         beginCommandBuffer(vk, *primCmdBuf);
1548         {
1549                 // allow execution of event during every stage of pipeline
1550                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1551
1552                 // record setting event
1553                 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1554         }
1555         endCommandBuffer(vk, *primCmdBuf);
1556
1557         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1558
1559         // check if buffer has been executed
1560         result = vk.getEventStatus(vkDevice,*event);
1561         if (result != VK_EVENT_SET)
1562                 return tcu::TestStatus::fail("oneTimeSubmitFlagPrimaryBufferTest FAILED");
1563         else
1564                 return tcu::TestStatus::pass("oneTimeSubmitFlagPrimaryBufferTest succeeded");
1565 }
1566
1567 tcu::TestStatus oneTimeSubmitFlagSecondaryBufferTest(Context& context)
1568 {
1569         const VkDevice                                                  vkDevice                                = context.getDevice();
1570         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1571         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1572         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1573
1574         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1575         {
1576                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1577                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1578                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1579                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1580         };
1581
1582         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1583
1584         // Command buffer
1585         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1586         {
1587                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1588                 DE_NULL,                                                                                                        //      const void*                             pNext;
1589                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1590                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1591                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1592         };
1593
1594         const Unique<VkCommandBuffer>                   primCmdBuf1                             (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1595         const Unique<VkCommandBuffer>                   primCmdBuf2                             (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1596
1597         // Secondary Command buffer
1598         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
1599         {
1600                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1601                 DE_NULL,                                                                                                        //      const void*                             pNext;
1602                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1603                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
1604                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1605         };
1606         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1607
1608         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
1609         {
1610                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1611                 DE_NULL,
1612                 (VkRenderPass)0u,                                                                                       // renderPass
1613                 0u,                                                                                                                     // subpass
1614                 (VkFramebuffer)0u,                                                                                      // framebuffer
1615                 VK_FALSE,                                                                                                       // occlusionQueryEnable
1616                 (VkQueryControlFlags)0u,                                                                        // queryFlags
1617                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
1618         };
1619         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
1620         {
1621                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1622                 DE_NULL,
1623                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                            // flags
1624                 &secCmdBufInheritInfo,
1625         };
1626
1627         // create event that will be used to check if secondary command buffer has been executed
1628         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
1629
1630         // reset event
1631         VK_CHECK(vk.resetEvent(vkDevice, *event));
1632
1633         // record first primary command buffer
1634         beginCommandBuffer(vk, *primCmdBuf1, 0u);
1635         {
1636                 // record secondary command buffer
1637                 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1638                 {
1639                         // allow execution of event during every stage of pipeline
1640                         VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1641
1642                         // record setting event
1643                         vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1644                 }
1645
1646                 // end recording of secondary buffers
1647                 endCommandBuffer(vk, *secCmdBuf);
1648
1649                 // execute secondary buffer
1650                 vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get());
1651         }
1652         endCommandBuffer(vk, *primCmdBuf1);
1653
1654         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf1.get());
1655
1656         // check if secondary buffer has been executed
1657         VkResult result = vk.getEventStatus(vkDevice,*event);
1658         if (result != VK_EVENT_SET)
1659                 return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED");
1660
1661         // reset first primary buffer
1662         vk.resetCommandBuffer( *primCmdBuf1, 0u);
1663
1664         // reset event to allow receiving it again
1665         VK_CHECK(vk.resetEvent(vkDevice, *event));
1666
1667         // record secondary command buffer again
1668         VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1669         {
1670                 // allow execution of event during every stage of pipeline
1671                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1672
1673                 // record setting event
1674                 vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1675         }
1676         // end recording of secondary buffers
1677         endCommandBuffer(vk, *secCmdBuf);
1678
1679         // record second primary command buffer
1680         beginCommandBuffer(vk, *primCmdBuf2, 0u);
1681         {
1682                 // execute secondary buffer
1683                 vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get());
1684         }
1685         // end recording
1686         endCommandBuffer(vk, *primCmdBuf2);
1687
1688         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf2.get());
1689
1690         // check if secondary buffer has been executed
1691         result = vk.getEventStatus(vkDevice,*event);
1692         if (result != VK_EVENT_SET)
1693                 return tcu::TestStatus::fail("oneTimeSubmitFlagSecondaryBufferTest FAILED");
1694         else
1695                 return tcu::TestStatus::pass("oneTimeSubmitFlagSecondaryBufferTest succeeded");
1696 }
1697
1698 tcu::TestStatus renderPassContinueTest(Context& context, bool framebufferHint)
1699 {
1700         const DeviceInterface&                                  vkd                                             = context.getDeviceInterface();
1701         CommandBufferRenderPassTestEnvironment  env                                             (context, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
1702
1703         VkCommandBuffer                                                 primaryCommandBuffer    = env.getPrimaryCommandBuffer();
1704         VkCommandBuffer                                                 secondaryCommandBuffer  = env.getSecondaryCommandBuffer();
1705         const deUint32                                                  clearColor[4]                   = { 2, 47, 131, 211 };
1706
1707         const VkClearAttachment                                 clearAttachment                 =
1708         {
1709                 VK_IMAGE_ASPECT_COLOR_BIT,                                                                      // VkImageAspectFlags   aspectMask;
1710                 0,                                                                                                                      // deUint32                             colorAttachment;
1711                 makeClearValueColorU32(clearColor[0],
1712                                                            clearColor[1],
1713                                                            clearColor[2],
1714                                                            clearColor[3])                                               // VkClearValue                 clearValue;
1715         };
1716
1717         const VkClearRect                                               clearRect                               =
1718         {
1719                 CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA,     // VkRect2D     rect;
1720                 0u,                                                                                                                     // deUint32     baseArrayLayer;
1721                 1u                                                                                                                      // deUint32     layerCount;
1722         };
1723
1724         env.beginSecondaryCommandBuffer(VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, framebufferHint);
1725         vkd.cmdClearAttachments(secondaryCommandBuffer, 1, &clearAttachment, 1, &clearRect);
1726         endCommandBuffer(vkd, secondaryCommandBuffer);
1727
1728
1729         env.beginPrimaryCommandBuffer(0);
1730         env.beginRenderPass(VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1731         vkd.cmdExecuteCommands(primaryCommandBuffer, 1, &secondaryCommandBuffer);
1732         endRenderPass(vkd, primaryCommandBuffer);
1733
1734         endCommandBuffer(vkd, primaryCommandBuffer);
1735
1736         env.submitPrimaryCommandBuffer();
1737
1738         de::MovePtr<tcu::TextureLevel>                  result                                  = env.readColorAttachment();
1739         tcu::PixelBufferAccess                                  pixelBufferAccess               = result->getAccess();
1740
1741         for (deUint32 i = 0; i < (CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.width * CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.height); ++i)
1742         {
1743                 deUint8* colorData = reinterpret_cast<deUint8*>(pixelBufferAccess.getDataPtr());
1744                 for (int colorComponent = 0; colorComponent < 4; ++colorComponent)
1745                         if (colorData[i * 4 + colorComponent] != clearColor[colorComponent])
1746                                 return tcu::TestStatus::fail("clear value mismatch");
1747         }
1748
1749         return tcu::TestStatus::pass("render pass continue test passed");
1750 }
1751
1752 tcu::TestStatus simultaneousUsePrimaryBufferTest(Context& context)
1753 {
1754         const VkDevice                                                  vkDevice                                = context.getDevice();
1755         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1756         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1757         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1758
1759         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1760         {
1761                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1762                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1763                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1764                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1765         };
1766         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1767
1768         // Command buffer
1769         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1770         {
1771                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                         sType;
1772                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1773                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1774                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1775                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1776         };
1777         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1778
1779         // create event that will be used to check if secondary command buffer has been executed
1780         const Unique<VkEvent>                                   eventOne                                (createEvent(vk, vkDevice));
1781         const Unique<VkEvent>                                   eventTwo                                (createEvent(vk, vkDevice));
1782
1783         // reset event
1784         VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
1785
1786         // record primary command buffer
1787         beginCommandBuffer(vk, *primCmdBuf, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
1788         {
1789                 // wait for event
1790                 vk.cmdWaitEvents(*primCmdBuf, 1u, &eventOne.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
1791
1792                 // Set the second event
1793                 vk.cmdSetEvent(*primCmdBuf, eventTwo.get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1794         }
1795         endCommandBuffer(vk, *primCmdBuf);
1796
1797         // create fence to wait for execution of queue
1798         const Unique<VkFence>                                   fence1                                  (createFence(vk, vkDevice));
1799         const Unique<VkFence>                                   fence2                                  (createFence(vk, vkDevice));
1800
1801         const VkSubmitInfo                                              submitInfo                              =
1802         {
1803                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
1804                 DE_NULL,                                                                                                        // pNext
1805                 0u,                                                                                                                     // waitSemaphoreCount
1806                 DE_NULL,                                                                                                        // pWaitSemaphores
1807                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
1808                 1,                                                                                                                      // commandBufferCount
1809                 &primCmdBuf.get(),                                                                                      // pCommandBuffers
1810                 0u,                                                                                                                     // signalSemaphoreCount
1811                 DE_NULL,                                                                                                        // pSignalSemaphores
1812         };
1813
1814         // submit first buffer
1815         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence1));
1816
1817         // submit second buffer
1818         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence2));
1819
1820         // wait for both buffer to stop at event for 100 microseconds
1821         vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, 100000);
1822         vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, 100000);
1823
1824         // set event
1825         VK_CHECK(vk.setEvent(vkDevice, *eventOne));
1826
1827         // wait for end of execution of the first buffer
1828         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, INFINITE_TIMEOUT));
1829         // wait for end of execution of the second buffer
1830         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, INFINITE_TIMEOUT));
1831
1832         // TODO: this will be true if the command buffer was executed only once
1833         // TODO: add some test that will say if it was executed twice
1834
1835         // check if buffer has been executed
1836         VkResult result = vk.getEventStatus(vkDevice, *eventTwo);
1837         if (result == VK_EVENT_SET)
1838                 return tcu::TestStatus::pass("simultaneous use - primary buffers test succeeded");
1839         else
1840                 return tcu::TestStatus::fail("simultaneous use - primary buffers test FAILED");
1841 }
1842
1843 tcu::TestStatus simultaneousUseSecondaryBufferTest(Context& context)
1844 {
1845         const VkDevice                                                  vkDevice                                = context.getDevice();
1846         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
1847         const VkQueue                                                   queue                                   = context.getUniversalQueue();
1848         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1849
1850         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
1851         {
1852                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1853                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1854                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1855                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1856         };
1857         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
1858
1859         // Command buffer
1860         const VkCommandBufferAllocateInfo               cmdBufParams                    =
1861         {
1862                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1863                 DE_NULL,                                                                                                        //      const void*                             pNext;
1864                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1865                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1866                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1867         };
1868         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1869
1870         // Secondary Command buffer params
1871         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
1872         {
1873                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1874                 DE_NULL,                                                                                                        //      const void*                             pNext;
1875                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1876                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
1877                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1878         };
1879         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1880
1881         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
1882         {
1883                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1884                 DE_NULL,
1885                 (VkRenderPass)0u,                                                                                       // renderPass
1886                 0u,                                                                                                                     // subpass
1887                 (VkFramebuffer)0u,                                                                                      // framebuffer
1888                 VK_FALSE,                                                                                                       // occlusionQueryEnable
1889                 (VkQueryControlFlags)0u,                                                                        // queryFlags
1890                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
1891         };
1892         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
1893         {
1894                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1895                 DE_NULL,
1896                 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,                           // flags
1897                 &secCmdBufInheritInfo,
1898         };
1899
1900         // create event that will be used to check if secondary command buffer has been executed
1901         const Unique<VkEvent>                                   eventOne                                (createEvent(vk, vkDevice));
1902         const Unique<VkEvent>                                   eventTwo                                (createEvent(vk, vkDevice));
1903
1904         // reset event
1905         VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
1906         VK_CHECK(vk.resetEvent(vkDevice, *eventTwo));
1907
1908         // record secondary command buffer
1909         VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1910         {
1911                 // allow execution of event during every stage of pipeline
1912                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1913
1914                 // wait for event
1915                 vk.cmdWaitEvents(*secCmdBuf, 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
1916
1917                 // reset event
1918                 vk.cmdSetEvent(*secCmdBuf, *eventTwo, stageMask);
1919         }
1920         // end recording of secondary buffers
1921         endCommandBuffer(vk, *secCmdBuf);
1922
1923         // record primary command buffer
1924         beginCommandBuffer(vk, *primCmdBuf, 0u);
1925         {
1926                 // execute secondary buffer
1927                 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
1928         }
1929         endCommandBuffer(vk, *primCmdBuf);
1930
1931         // create fence to wait for execution of queue
1932         const Unique<VkFence>                                   fence                                   (createFence(vk, vkDevice));
1933
1934         const VkSubmitInfo                                              submitInfo                              =
1935         {
1936                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
1937                 DE_NULL,                                                                                                        // pNext
1938                 0u,                                                                                                                     // waitSemaphoreCount
1939                 DE_NULL,                                                                                                        // pWaitSemaphores
1940                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
1941                 1,                                                                                                                      // commandBufferCount
1942                 &primCmdBuf.get(),                                                                                      // pCommandBuffers
1943                 0u,                                                                                                                     // signalSemaphoreCount
1944                 DE_NULL,                                                                                                        // pSignalSemaphores
1945         };
1946
1947         // submit primary buffer, the secondary should be executed too
1948         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1949
1950         // wait for both buffers to stop at event for 100 microseconds
1951         vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 100000);
1952
1953         // set event
1954         VK_CHECK(vk.setEvent(vkDevice, *eventOne));
1955
1956         // wait for end of execution of queue
1957         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
1958
1959         // TODO: this will be true if the command buffer was executed only once
1960         // TODO: add some test that will say if it was executed twice
1961
1962         // check if secondary buffer has been executed
1963         VkResult result = vk.getEventStatus(vkDevice,*eventTwo);
1964         if (result == VK_EVENT_SET)
1965                 return tcu::TestStatus::pass("Simultaneous Secondary Command Buffer Execution succeeded");
1966         else
1967                 return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
1968 }
1969
1970 tcu::TestStatus simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& context)
1971 {
1972         const VkDevice                                                  vkDevice = context.getDevice();
1973         const DeviceInterface&                                  vk = context.getDeviceInterface();
1974         const VkQueue                                                   queue = context.getUniversalQueue();
1975         const deUint32                                                  queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1976         Allocator&                                                              allocator = context.getDefaultAllocator();
1977         const ComputeInstanceResultBuffer               result(vk, vkDevice, allocator, 0.0f);
1978
1979         const VkCommandPoolCreateInfo                   cmdPoolParams =
1980         {
1981                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
1982                 DE_NULL,                                                                                                        //      const void*                                     pNext;
1983                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
1984                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
1985         };
1986         const Unique<VkCommandPool>                             cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
1987
1988         // Command buffer
1989         const VkCommandBufferAllocateInfo               cmdBufParams =
1990         {
1991                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
1992                 DE_NULL,                                                                                                        //      const void*                             pNext;
1993                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
1994                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
1995                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
1996         };
1997         const Unique<VkCommandBuffer>                   primCmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1998
1999         // Secondary Command buffer params
2000         const VkCommandBufferAllocateInfo               secCmdBufParams =
2001         {
2002                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
2003                 DE_NULL,                                                                                                        //      const void*                             pNext;
2004                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
2005                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
2006                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
2007         };
2008         const Unique<VkCommandBuffer>                   secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2009
2010         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo =
2011         {
2012                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2013                 DE_NULL,
2014                 (VkRenderPass)0u,
2015                 0u,                                                                                                                     // subpass
2016                 (VkFramebuffer)0u,
2017                 VK_FALSE,                                                                                                       // occlusionQueryEnable
2018                 (VkQueryControlFlags)0u,
2019                 (VkQueryPipelineStatisticFlags)0u,
2020         };
2021         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo =
2022         {
2023                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2024                 DE_NULL,
2025                 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,                           // flags
2026                 &secCmdBufInheritInfo,
2027         };
2028
2029         const deUint32                                                  offset = (0u);
2030         const deUint32                                                  addressableSize = 256;
2031         const deUint32                                                  dataSize = 8;
2032         de::MovePtr<Allocation>                                 bufferMem;
2033         const Unique<VkBuffer>                                  buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2034         // Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute
2035         const Unique<VkDescriptorSetLayout>             descriptorSetLayout(createDescriptorSetLayout(context));
2036         const Unique<VkDescriptorPool>                  descriptorPool(createDescriptorPool(context));
2037         const Unique<VkDescriptorSet>                   descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2038         const VkDescriptorSet                                   descriptorSets[] = { *descriptorSet };
2039         const int                                                               numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2040
2041         const VkPipelineLayoutCreateInfo layoutCreateInfo =
2042         {
2043                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
2044                 DE_NULL,                                                                                                        // pNext
2045                 (VkPipelineLayoutCreateFlags)0,
2046                 numDescriptorSets,                                                                                      // setLayoutCount
2047                 &descriptorSetLayout.get(),                                                                     // pSetLayouts
2048                 0u,                                                                                                                     // pushConstantRangeCount
2049                 DE_NULL,                                                                                                        // pPushConstantRanges
2050         };
2051         Unique<VkPipelineLayout>                                pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2052
2053         const Unique<VkShaderModule>                    computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2054
2055         const VkPipelineShaderStageCreateInfo   shaderCreateInfo =
2056         {
2057                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2058                 DE_NULL,
2059                 (VkPipelineShaderStageCreateFlags)0,
2060                 VK_SHADER_STAGE_COMPUTE_BIT,                                                            // stage
2061                 *computeModule,                                                                                         // shader
2062                 "main",
2063                 DE_NULL,                                                                                                        // pSpecializationInfo
2064         };
2065
2066         const VkComputePipelineCreateInfo               pipelineCreateInfo =
2067         {
2068                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2069                 DE_NULL,
2070                 0u,                                                                                                                     // flags
2071                 shaderCreateInfo,                                                                                       // cs
2072                 *pipelineLayout,                                                                                        // layout
2073                 (vk::VkPipeline)0,                                                                                      // basePipelineHandle
2074                 0u,                                                                                                                     // basePipelineIndex
2075         };
2076
2077         const VkBufferMemoryBarrier                             bufferBarrier =
2078         {
2079                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                                        // sType
2080                 DE_NULL,                                                                                                        // pNext
2081                 VK_ACCESS_SHADER_WRITE_BIT,                                                                     // srcAccessMask
2082                 VK_ACCESS_HOST_READ_BIT,                                                                        // dstAccessMask
2083                 VK_QUEUE_FAMILY_IGNORED,                                                                        // srcQueueFamilyIndex
2084                 VK_QUEUE_FAMILY_IGNORED,                                                                        // destQueueFamilyIndex
2085                 *buffer,                                                                                                        // buffer
2086                 (VkDeviceSize)0u,                                                                                       // offset
2087                 (VkDeviceSize)VK_WHOLE_SIZE,                                                            // size
2088         };
2089
2090         const Unique<VkPipeline>                                pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2091
2092         // record secondary command buffer
2093         VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2094         {
2095                 vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2096                 vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2097                 vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
2098                 vk.cmdPipelineBarrier(*secCmdBuf, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
2099                                                   0, (const VkMemoryBarrier*)DE_NULL,
2100                                                   1, &bufferBarrier,
2101                                                   0, (const VkImageMemoryBarrier*)DE_NULL);
2102         }
2103         // end recording of secondary buffer
2104         endCommandBuffer(vk, *secCmdBuf);
2105
2106         // record primary command buffer
2107         beginCommandBuffer(vk, *primCmdBuf, 0u);
2108         {
2109                 // execute secondary buffer twice in same primary
2110                 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2111                 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2112         }
2113         endCommandBuffer(vk, *primCmdBuf);
2114
2115         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
2116
2117         deUint32 resultCount;
2118         result.readResultContentsTo(&resultCount);
2119         // check if secondary buffer has been executed
2120         if (resultCount == 2)
2121                 return tcu::TestStatus::pass("Simultaneous Secondary Command Buffer Execution succeeded");
2122         else
2123                 return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2124 }
2125
2126 enum class BadInheritanceInfoCase
2127 {
2128         RANDOM_PTR = 0,
2129         RANDOM_PTR_CONTINUATION,
2130         RANDOM_DATA_PTR,
2131         INVALID_STRUCTURE_TYPE,
2132         VALID_NONSENSE_TYPE,
2133 };
2134
2135 tcu::TestStatus badInheritanceInfoTest (Context& context, BadInheritanceInfoCase testCase)
2136 {
2137         const auto&                                                     vkd                                     = context.getDeviceInterface();
2138         const auto                                                      device                          = context.getDevice();
2139         const auto                                                      queue                           = context.getUniversalQueue();
2140         const auto                                                      queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2141         auto&                                                           allocator                       = context.getDefaultAllocator();
2142         const ComputeInstanceResultBuffer       result                          (vkd, device, allocator, 0.0f);
2143
2144         // Command pool and command buffer.
2145         const auto                                                      cmdPool                 = makeCommandPool(vkd, device, queueFamilyIndex);
2146         const auto                                                      cmdBufferPtr    = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2147         const auto                                                      cmdBuffer               = cmdBufferPtr.get();
2148
2149         // Buffers, descriptor set layouts and descriptor sets.
2150         const deUint32                                                  offset                  = 0u;
2151         const deUint32                                                  addressableSize = 256u;
2152         const deUint32                                                  dataSize                = 8u;
2153
2154         // The uniform buffer will not be used by the shader but is needed by auxiliar functions here.
2155         de::MovePtr<Allocation>                                 bufferMem;
2156         const Unique<VkBuffer>                                  buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2157
2158         const Unique<VkDescriptorSetLayout>             descriptorSetLayout     (createDescriptorSetLayout(context));
2159         const Unique<VkDescriptorPool>                  descriptorPool          (createDescriptorPool(context));
2160         const Unique<VkDescriptorSet>                   descriptorSet           (createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2161         const VkDescriptorSet                                   descriptorSets[]        = { *descriptorSet };
2162         const int                                                               numDescriptorSets       = DE_LENGTH_OF_ARRAY(descriptorSets);
2163
2164         // Pipeline layout.
2165         const auto                                                              pipelineLayout          = makePipelineLayout(vkd, device, descriptorSetLayout.get());
2166
2167         // Compute shader module.
2168         const Unique<VkShaderModule>                    computeModule           (createShaderModule(vkd, device, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2169
2170         const VkPipelineShaderStageCreateInfo   shaderCreateInfo        =
2171         {
2172                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2173                 DE_NULL,
2174                 (VkPipelineShaderStageCreateFlags)0,
2175                 VK_SHADER_STAGE_COMPUTE_BIT,                                                            // stage
2176                 *computeModule,                                                                                         // shader
2177                 "main",
2178                 DE_NULL,                                                                                                        // pSpecializationInfo
2179         };
2180
2181         const VkComputePipelineCreateInfo               pipelineCreateInfo      =
2182         {
2183                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2184                 DE_NULL,
2185                 0u,                                                                                                                     // flags
2186                 shaderCreateInfo,                                                                                       // cs
2187                 *pipelineLayout,                                                                                        // layout
2188                 (vk::VkPipeline)0,                                                                                      // basePipelineHandle
2189                 0u,                                                                                                                     // basePipelineIndex
2190         };
2191
2192         const Unique<VkPipeline>                                pipeline                        (createComputePipeline(vkd, device, (VkPipelineCache)0u, &pipelineCreateInfo));
2193
2194         // Compute to host barrier to read result.
2195         const VkBufferMemoryBarrier                             bufferBarrier           =
2196         {
2197                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                                        // sType
2198                 DE_NULL,                                                                                                        // pNext
2199                 VK_ACCESS_SHADER_WRITE_BIT,                                                                     // srcAccessMask
2200                 VK_ACCESS_HOST_READ_BIT,                                                                        // dstAccessMask
2201                 VK_QUEUE_FAMILY_IGNORED,                                                                        // srcQueueFamilyIndex
2202                 VK_QUEUE_FAMILY_IGNORED,                                                                        // destQueueFamilyIndex
2203                 *buffer,                                                                                                        // buffer
2204                 (VkDeviceSize)0u,                                                                                       // offset
2205                 (VkDeviceSize)VK_WHOLE_SIZE,                                                            // size
2206         };
2207
2208         // Record command buffer and submit it.
2209         VkCommandBufferBeginInfo                                beginInfo                       =
2210         {
2211                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    //      VkStructureType                                                 sType;
2212                 nullptr,                                                                                //      const void*                                                             pNext;
2213                 0u,                                                                                             //      VkCommandBufferUsageFlags                               flags;
2214                 nullptr,                                                                                //      const VkCommandBufferInheritanceInfo*   pInheritanceInfo;
2215         };
2216
2217         // Structures used in different test types.
2218         VkCommandBufferInheritanceInfo                  inheritanceInfo;
2219         VkBufferCreateInfo                                              validNonsenseStructure;
2220         struct
2221         {
2222                 VkStructureType sType;
2223                 void*                   pNext;
2224         } invalidStructure;
2225
2226         if (testCase == BadInheritanceInfoCase::RANDOM_PTR || testCase == BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION)
2227         {
2228                 de::Random                                              rnd             (1602600778u);
2229                 VkCommandBufferInheritanceInfo* info;
2230                 auto                                                    ptrData = reinterpret_cast<deUint8*>(&info);
2231
2232                 // Fill pointer value with pseudorandom garbage.
2233                 for (size_t i = 0; i < sizeof(info); ++i)
2234                         *ptrData++ = rnd.getUint8();
2235
2236                 beginInfo.pInheritanceInfo = info;
2237
2238                 // Try to trick the implementation into reading pInheritanceInfo one more way.
2239                 if (testCase == BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION)
2240                         beginInfo.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2241
2242         }
2243         else if (testCase == BadInheritanceInfoCase::RANDOM_DATA_PTR)
2244         {
2245                 de::Random              rnd     (1602601141u);
2246                 auto                    itr     = reinterpret_cast<deUint8*>(&inheritanceInfo);
2247
2248                 // Fill inheritance info data structure with random data.
2249                 for (size_t i = 0; i < sizeof(inheritanceInfo); ++i)
2250                         *itr++ = rnd.getUint8();
2251
2252                 beginInfo.pInheritanceInfo = &inheritanceInfo;
2253         }
2254         else if (testCase == BadInheritanceInfoCase::INVALID_STRUCTURE_TYPE)
2255         {
2256                 de::Random      rnd                     (1602658515u);
2257                 auto            ptrData         = reinterpret_cast<deUint8*>(&(invalidStructure.pNext));
2258                 invalidStructure.sType  = VK_STRUCTURE_TYPE_MAX_ENUM;
2259
2260                 // Fill pNext pointer with random data.
2261                 for (size_t i = 0; i < sizeof(invalidStructure.pNext); ++i)
2262                         *ptrData++ = rnd.getUint8();
2263
2264                 beginInfo.pInheritanceInfo = reinterpret_cast<VkCommandBufferInheritanceInfo*>(&invalidStructure);
2265         }
2266         else if (testCase == BadInheritanceInfoCase::VALID_NONSENSE_TYPE)
2267         {
2268                 validNonsenseStructure.sType                                    = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2269                 validNonsenseStructure.pNext                                    = nullptr;
2270                 validNonsenseStructure.flags                                    = 0u;
2271                 validNonsenseStructure.size                                             = 1024u;
2272                 validNonsenseStructure.usage                                    = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2273                 validNonsenseStructure.sharingMode                              = VK_SHARING_MODE_EXCLUSIVE;
2274                 validNonsenseStructure.queueFamilyIndexCount    = 0u;
2275                 validNonsenseStructure.pQueueFamilyIndices              = nullptr;
2276
2277                 beginInfo.pInheritanceInfo                                              = reinterpret_cast<VkCommandBufferInheritanceInfo*>(&validNonsenseStructure);
2278         }
2279         else
2280         {
2281                 DE_ASSERT(false);
2282         }
2283
2284         VK_CHECK(vkd.beginCommandBuffer(cmdBuffer, &beginInfo));
2285         {
2286                 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2287                 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2288                 vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u);
2289                 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
2290                                                            0, (const VkMemoryBarrier*)DE_NULL,
2291                                                            1, &bufferBarrier,
2292                                                            0, (const VkImageMemoryBarrier*)DE_NULL);
2293         }
2294         endCommandBuffer(vkd, cmdBuffer);
2295         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
2296
2297         deUint32 resultCount;
2298         result.readResultContentsTo(&resultCount);
2299
2300         // Make sure the command buffer was run.
2301         if (resultCount != 1u)
2302         {
2303                 std::ostringstream msg;
2304                 msg << "Invalid value found in results buffer (expected value 1u but found " << resultCount << ")";
2305                 return tcu::TestStatus::fail(msg.str());
2306         }
2307
2308         return tcu::TestStatus::pass("Pass");
2309 }
2310
2311 tcu::TestStatus simultaneousUseSecondaryBufferTwoPrimaryBuffersTest(Context& context)
2312 {
2313         const VkDevice                                                  vkDevice = context.getDevice();
2314         const DeviceInterface&                                  vk = context.getDeviceInterface();
2315         const VkQueue                                                   queue = context.getUniversalQueue();
2316         const deUint32                                                  queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2317         Allocator&                                                              allocator = context.getDefaultAllocator();
2318         const ComputeInstanceResultBuffer               result(vk, vkDevice, allocator, 0.0f);
2319
2320         const VkCommandPoolCreateInfo                   cmdPoolParams =
2321         {
2322                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
2323                 DE_NULL,                                                                                                        //      const void*                                     pNext;
2324                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
2325                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
2326         };
2327         const Unique<VkCommandPool>                             cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
2328
2329         // Command buffer
2330         const VkCommandBufferAllocateInfo               cmdBufParams =
2331         {
2332                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
2333                 DE_NULL,                                                                                                        //      const void*                             pNext;
2334                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
2335                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
2336                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
2337         };
2338         // Two separate primary cmd buffers that will be executed with the same secondary cmd buffer
2339         const deUint32 numPrimCmdBufs = 2;
2340         const Unique<VkCommandBuffer>                   primCmdBufOne(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2341         const Unique<VkCommandBuffer>                   primCmdBufTwo(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2342         VkCommandBuffer primCmdBufs[numPrimCmdBufs];
2343         primCmdBufs[0] = primCmdBufOne.get();
2344         primCmdBufs[1] = primCmdBufTwo.get();
2345
2346         // Secondary Command buffer params
2347         const VkCommandBufferAllocateInfo               secCmdBufParams =
2348         {
2349                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
2350                 DE_NULL,                                                                                                        //      const void*                             pNext;
2351                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
2352                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
2353                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
2354         };
2355         const Unique<VkCommandBuffer>                   secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2356
2357         const VkCommandBufferBeginInfo                  primCmdBufBeginInfo =
2358         {
2359                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2360                 DE_NULL,
2361                 0,                                                                                                                      // flags
2362                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2363         };
2364
2365         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo =
2366         {
2367                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2368                 DE_NULL,
2369                 (VkRenderPass)0u,                                                                                       // renderPass
2370                 0u,                                                                                                                     // subpass
2371                 (VkFramebuffer)0u,                                                                                      // framebuffer
2372                 VK_FALSE,                                                                                                       // occlusionQueryEnable
2373                 (VkQueryControlFlags)0u,                                                                        // queryFlags
2374                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
2375         };
2376         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo =
2377         {
2378                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2379                 DE_NULL,
2380                 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,                           // flags
2381                 &secCmdBufInheritInfo,
2382         };
2383
2384         const deUint32                                                  offset = (0u);
2385         const deUint32                                                  addressableSize = 256;
2386         const deUint32                                                  dataSize = 8;
2387         de::MovePtr<Allocation>                                 bufferMem;
2388         const Unique<VkBuffer>                                  buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
2389         // Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute
2390         const Unique<VkDescriptorSetLayout>             descriptorSetLayout(createDescriptorSetLayout(context));
2391         const Unique<VkDescriptorPool>                  descriptorPool(createDescriptorPool(context));
2392         const Unique<VkDescriptorSet>                   descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
2393         const VkDescriptorSet                                   descriptorSets[] = { *descriptorSet };
2394         const int                                                               numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2395
2396         const VkPipelineLayoutCreateInfo layoutCreateInfo =
2397         {
2398                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
2399                 DE_NULL,                                                                                                        // pNext
2400                 (VkPipelineLayoutCreateFlags)0,
2401                 numDescriptorSets,                                                                                      // setLayoutCount
2402                 &descriptorSetLayout.get(),                                                                     // pSetLayouts
2403                 0u,                                                                                                                     // pushConstantRangeCount
2404                 DE_NULL,                                                                                                        // pPushConstantRanges
2405         };
2406         Unique<VkPipelineLayout>                                pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2407
2408         const Unique<VkShaderModule>                    computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2409
2410         const VkPipelineShaderStageCreateInfo   shaderCreateInfo =
2411         {
2412                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2413                 DE_NULL,
2414                 (VkPipelineShaderStageCreateFlags)0,
2415                 VK_SHADER_STAGE_COMPUTE_BIT,                                                            // stage
2416                 *computeModule,                                                                                         // shader
2417                 "main",
2418                 DE_NULL,                                                                                                        // pSpecializationInfo
2419         };
2420
2421         const VkComputePipelineCreateInfo               pipelineCreateInfo =
2422         {
2423                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2424                 DE_NULL,
2425                 0u,                                                                                                                     // flags
2426                 shaderCreateInfo,                                                                                       // cs
2427                 *pipelineLayout,                                                                                        // layout
2428                 (vk::VkPipeline)0,                                                                                      // basePipelineHandle
2429                 0u,                                                                                                                     // basePipelineIndex
2430         };
2431
2432         const Unique<VkPipeline>                                pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2433
2434         // record secondary command buffer
2435         VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
2436         {
2437                 vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
2438                 vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0);
2439                 vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u);
2440         }
2441         // end recording of secondary buffer
2442         endCommandBuffer(vk, *secCmdBuf);
2443
2444         // record primary command buffers
2445         // Insert one instance of same secondary command buffer into two separate primary command buffers
2446         VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
2447         {
2448                 vk.cmdExecuteCommands(*primCmdBufOne, 1, &secCmdBuf.get());
2449         }
2450         endCommandBuffer(vk, *primCmdBufOne);
2451
2452         VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
2453         {
2454                 vk.cmdExecuteCommands(*primCmdBufTwo, 1, &secCmdBuf.get());
2455         }
2456         endCommandBuffer(vk, *primCmdBufTwo);
2457
2458         // create fence to wait for execution of queue
2459         const Unique<VkFence>                                   fence(createFence(vk, vkDevice));
2460
2461         const VkSubmitInfo                                              submitInfo =
2462         {
2463                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
2464                 DE_NULL,                                                                                                        // pNext
2465                 0u,                                                                                                                     // waitSemaphoreCount
2466                 DE_NULL,                                                                                                        // pWaitSemaphores
2467                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
2468                 numPrimCmdBufs,                                                                                         // commandBufferCount
2469                 primCmdBufs,                                                                                            // pCommandBuffers
2470                 0u,                                                                                                                     // signalSemaphoreCount
2471                 DE_NULL,                                                                                                        // pSignalSemaphores
2472         };
2473
2474         // submit primary buffers, the secondary should be executed too
2475         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2476
2477         // wait for end of execution of queue
2478         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
2479
2480         deUint32 resultCount;
2481         result.readResultContentsTo(&resultCount);
2482         // check if secondary buffer has been executed
2483         if (resultCount == 2)
2484                 return tcu::TestStatus::pass("Simultaneous Secondary Command Buffer Execution succeeded");
2485         else
2486                 return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2487 }
2488
2489 tcu::TestStatus recordBufferQueryPreciseWithFlagTest(Context& context)
2490 {
2491         const VkDevice                                                  vkDevice                                = context.getDevice();
2492         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
2493         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2494
2495         if (!context.getDeviceFeatures().inheritedQueries)
2496                 TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2497
2498         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
2499         {
2500                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
2501                 DE_NULL,                                                                                                        // pNext;
2502                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
2503                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
2504         };
2505         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
2506
2507         // Command buffer
2508         const VkCommandBufferAllocateInfo               primCmdBufParams                =
2509         {
2510                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2511                 DE_NULL,                                                                                                        // pNext;
2512                 *cmdPool,                                                                                                       // pool;
2513                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
2514                 1u,                                                                                                                     // flags;
2515         };
2516         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2517
2518         // Secondary Command buffer params
2519         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
2520         {
2521                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2522                 DE_NULL,                                                                                                        // pNext;
2523                 *cmdPool,                                                                                                       // pool;
2524                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      // level;
2525                 1u,                                                                                                                     // flags;
2526         };
2527         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2528
2529         const VkCommandBufferBeginInfo                  primBufferBeginInfo             =
2530         {
2531                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2532                 DE_NULL,                                                                                                        // pNext
2533                 0u,                                                                                                                     // flags
2534                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2535         };
2536
2537         const VkCommandBufferInheritanceInfo    secBufferInheritInfo    =
2538         {
2539                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2540                 DE_NULL,
2541                 0u,                                                                                                                     // renderPass
2542                 0u,                                                                                                                     // subpass
2543                 0u,                                                                                                                     // framebuffer
2544                 VK_TRUE,                                                                                                        // occlusionQueryEnable
2545                 VK_QUERY_CONTROL_PRECISE_BIT,                                                           // queryFlags
2546                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
2547         };
2548         const VkCommandBufferBeginInfo                  secBufferBeginInfo              =
2549         {
2550                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2551                 DE_NULL,                                                                                                        // pNext
2552                 0u,                                                                                                                     // flags
2553                 &secBufferInheritInfo,
2554         };
2555
2556         const VkQueryPoolCreateInfo                             queryPoolCreateInfo             =
2557         {
2558                 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,                                       // sType
2559                 DE_NULL,                                                                                                        // pNext
2560                 (VkQueryPoolCreateFlags)0,                                                                      // flags
2561                 VK_QUERY_TYPE_OCCLUSION,                                                                        // queryType
2562                 1u,                                                                                                                     // entryCount
2563                 0u,                                                                                                                     // pipelineStatistics
2564         };
2565         Unique<VkQueryPool>                                             queryPool                               (createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2566
2567         VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2568         endCommandBuffer(vk, secCmdBuf.get());
2569
2570         VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2571         {
2572                 vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2573                 vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2574                 {
2575                         vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2576                 }
2577                 vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2578         }
2579         endCommandBuffer(vk, primCmdBuf.get());
2580
2581         return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2582 }
2583
2584 tcu::TestStatus recordBufferQueryImpreciseWithFlagTest(Context& context)
2585 {
2586         const VkDevice                                                  vkDevice                                = context.getDevice();
2587         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
2588         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2589
2590         if (!context.getDeviceFeatures().inheritedQueries)
2591                 TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2592
2593         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
2594         {
2595                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
2596                 DE_NULL,                                                                                                        // pNext;
2597                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
2598                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
2599         };
2600         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
2601
2602         // Command buffer
2603         const VkCommandBufferAllocateInfo               primCmdBufParams                =
2604         {
2605                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2606                 DE_NULL,                                                                                                        // pNext;
2607                 *cmdPool,                                                                                                       // pool;
2608                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
2609                 1u,                                                                                                                     // flags;
2610         };
2611         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2612
2613         // Secondary Command buffer params
2614         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
2615         {
2616                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2617                 DE_NULL,                                                                                                        // pNext;
2618                 *cmdPool,                                                                                                       // pool;
2619                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      // level;
2620                 1u,                                                                                                                     // flags;
2621         };
2622         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2623
2624         const VkCommandBufferBeginInfo                  primBufferBeginInfo             =
2625         {
2626                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2627                 DE_NULL,                                                                                                        // pNext
2628                 0u,                                                                                                                     // flags
2629                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2630         };
2631
2632         const VkCommandBufferInheritanceInfo    secBufferInheritInfo    =
2633         {
2634                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2635                 DE_NULL,
2636                 0u,                                                                                                                     // renderPass
2637                 0u,                                                                                                                     // subpass
2638                 0u,                                                                                                                     // framebuffer
2639                 VK_TRUE,                                                                                                        // occlusionQueryEnable
2640                 VK_QUERY_CONTROL_PRECISE_BIT,                                                           // queryFlags
2641                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
2642         };
2643         const VkCommandBufferBeginInfo                  secBufferBeginInfo              =
2644         {
2645                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2646                 DE_NULL,                                                                                                        // pNext
2647                 0u,                                                                                                                     // flags
2648                 &secBufferInheritInfo,
2649         };
2650
2651         // Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set
2652         const VkQueryPoolCreateInfo                             queryPoolCreateInfo             =
2653         {
2654                 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,                                       // sType
2655                 DE_NULL,                                                                                                        // pNext
2656                 0u,                                                                                                                     // flags
2657                 VK_QUERY_TYPE_OCCLUSION,                                                                        // queryType
2658                 1u,                                                                                                                     // entryCount
2659                 0u,                                                                                                                     // pipelineStatistics
2660         };
2661         Unique<VkQueryPool>                                             queryPool                               (createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2662
2663         VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2664         endCommandBuffer(vk, secCmdBuf.get());
2665
2666         VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2667         {
2668                 vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2669                 vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2670                 {
2671                         vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2672                 }
2673                 vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2674         }
2675         endCommandBuffer(vk, primCmdBuf.get());
2676
2677         return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2678 }
2679
2680 tcu::TestStatus recordBufferQueryImpreciseWithoutFlagTest(Context& context)
2681 {
2682         const VkDevice                                                  vkDevice                                = context.getDevice();
2683         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
2684         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2685
2686         if (!context.getDeviceFeatures().inheritedQueries)
2687                 TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2688
2689         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
2690         {
2691                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
2692                 DE_NULL,                                                                                                        // pNext;
2693                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
2694                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
2695         };
2696         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
2697
2698         // Command buffer
2699         const VkCommandBufferAllocateInfo               primCmdBufParams                =
2700         {
2701                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2702                 DE_NULL,                                                                                                        // pNext;
2703                 *cmdPool,                                                                                                       // pool;
2704                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
2705                 1u,                                                                                                                     // flags;
2706         };
2707         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2708
2709         // Secondary Command buffer params
2710         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
2711         {
2712                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2713                 DE_NULL,                                                                                                        // pNext;
2714                 *cmdPool,                                                                                                       // pool;
2715                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      // level;
2716                 1u,                                                                                                                     // flags;
2717         };
2718         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2719
2720         const VkCommandBufferBeginInfo                  primBufferBeginInfo             =
2721         {
2722                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2723                 DE_NULL,                                                                                                        // pNext
2724                 0u,                                                                                                                     // flags
2725                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2726         };
2727
2728         const VkCommandBufferInheritanceInfo    secBufferInheritInfo    =
2729         {
2730                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2731                 DE_NULL,
2732                 0u,                                                                                                                     // renderPass
2733                 0u,                                                                                                                     // subpass
2734                 0u,                                                                                                                     // framebuffer
2735                 VK_TRUE,                                                                                                        // occlusionQueryEnable
2736                 0u,                                                                                                                     // queryFlags
2737                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
2738         };
2739         const VkCommandBufferBeginInfo                  secBufferBeginInfo              =
2740         {
2741                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2742                 DE_NULL,                                                                                                        // pNext
2743                 0u,                                                                                                                     // flags
2744                 &secBufferInheritInfo,
2745         };
2746
2747         // Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set
2748         const VkQueryPoolCreateInfo                             queryPoolCreateInfo             =
2749         {
2750                 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,                                       // sType
2751                 DE_NULL,                                                                                                        // pNext
2752                 (VkQueryPoolCreateFlags)0,
2753                 VK_QUERY_TYPE_OCCLUSION,
2754                 1u,
2755                 0u,
2756         };
2757         Unique<VkQueryPool>                                             queryPool                               (createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2758
2759         VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2760         endCommandBuffer(vk, secCmdBuf.get());
2761
2762         VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2763         {
2764                 vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2765                 vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2766                 {
2767                         vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2768                 }
2769                 vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2770         }
2771         endCommandBuffer(vk, primCmdBuf.get());
2772
2773         return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2774 }
2775
2776 /******** 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) ****************/
2777 tcu::TestStatus submitBufferCountNonZero(Context& context)
2778 {
2779         const VkDevice                                                  vkDevice                                = context.getDevice();
2780         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
2781         const VkQueue                                                   queue                                   = context.getUniversalQueue();
2782         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2783
2784         const deUint32                                                  BUFFER_COUNT                    = 5u;
2785
2786         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
2787         {
2788                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
2789                 DE_NULL,                                                                                                        // pNext;
2790                 0u,                                                                                                                     // flags;
2791                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
2792         };
2793         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
2794
2795         // Command buffer
2796         const VkCommandBufferAllocateInfo               cmdBufParams                    =
2797         {
2798                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2799                 DE_NULL,                                                                                                        // pNext;
2800                 *cmdPool,                                                                                                       // pool;
2801                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
2802                 BUFFER_COUNT,                                                                                           // bufferCount;
2803         };
2804         VkCommandBuffer cmdBuffers[BUFFER_COUNT];
2805         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
2806
2807         const VkCommandBufferBeginInfo                  cmdBufBeginInfo                 =
2808         {
2809                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2810                 DE_NULL,                                                                                                        // pNext
2811                 0u,                                                                                                                     // flags
2812                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2813         };
2814
2815         std::vector<VkEventSp>                                  events;
2816         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2817         {
2818                 events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
2819         }
2820
2821         // Record the command buffers
2822         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2823         {
2824                 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
2825                 {
2826                         vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2827                 }
2828                 endCommandBuffer(vk, cmdBuffers[ndx]);
2829         }
2830
2831         // We'll use a fence to wait for the execution of the queue
2832         const Unique<VkFence>                                   fence                                   (createFence(vk, vkDevice));
2833
2834         const VkSubmitInfo                                              submitInfo                              =
2835         {
2836                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
2837                 DE_NULL,                                                                                                        // pNext
2838                 0u,                                                                                                                     // waitSemaphoreCount
2839                 DE_NULL,                                                                                                        // pWaitSemaphores
2840                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
2841                 BUFFER_COUNT,                                                                                           // commandBufferCount
2842                 cmdBuffers,                                                                                                     // pCommandBuffers
2843                 0u,                                                                                                                     // signalSemaphoreCount
2844                 DE_NULL,                                                                                                        // pSignalSemaphores
2845         };
2846
2847         // Submit the alpha command buffer to the queue
2848         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
2849         // Wait for the queue
2850         VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
2851
2852         // Check if the buffers were executed
2853         tcu::TestStatus testResult = tcu::TestStatus::incomplete();
2854
2855         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2856         {
2857                 if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
2858                 {
2859                         testResult = tcu::TestStatus::fail("Failed to set the event.");
2860                         break;
2861                 }
2862         }
2863
2864         if (!testResult.isComplete())
2865                 testResult = tcu::TestStatus::pass("All buffers were submitted and executed correctly.");
2866
2867         return testResult;
2868 }
2869
2870 tcu::TestStatus submitBufferCountEqualZero(Context& context)
2871 {
2872         const VkDevice                                                  vkDevice                                = context.getDevice();
2873         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
2874         const VkQueue                                                   queue                                   = context.getUniversalQueue();
2875         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2876
2877         const deUint32                                                  BUFFER_COUNT                    = 2u;
2878
2879         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
2880         {
2881                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
2882                 DE_NULL,                                                                                                        // pNext;
2883                 0u,                                                                                                                     // flags;
2884                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
2885         };
2886         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
2887
2888         // Command buffer
2889         const VkCommandBufferAllocateInfo               cmdBufParams                    =
2890         {
2891                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
2892                 DE_NULL,                                                                                                        // pNext;
2893                 *cmdPool,                                                                                                       // pool;
2894                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
2895                 BUFFER_COUNT,                                                                                           // bufferCount;
2896         };
2897         VkCommandBuffer cmdBuffers[BUFFER_COUNT];
2898         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
2899
2900         const VkCommandBufferBeginInfo                  cmdBufBeginInfo                 =
2901         {
2902                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
2903                 DE_NULL,                                                                                                        // pNext
2904                 0u,                                                                                                                     // flags
2905                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2906         };
2907
2908         std::vector<VkEventSp>                                  events;
2909         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2910                 events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
2911
2912         // Record the command buffers
2913         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2914         {
2915                 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
2916                 {
2917                         vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2918                 }
2919                 endCommandBuffer(vk, cmdBuffers[ndx]);
2920         }
2921
2922         // We'll use a fence to wait for the execution of the queue
2923         const Unique<VkFence>                                   fenceZero                               (createFence(vk, vkDevice));
2924         const Unique<VkFence>                                   fenceOne                                (createFence(vk, vkDevice));
2925
2926         const VkSubmitInfo                                              submitInfoCountZero             =
2927         {
2928                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
2929                 DE_NULL,                                                                                                        // pNext
2930                 0u,                                                                                                                     // waitSemaphoreCount
2931                 DE_NULL,                                                                                                        // pWaitSemaphores
2932                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
2933                 1u,                                                                                                                     // commandBufferCount
2934                 &cmdBuffers[0],                                                                                         // pCommandBuffers
2935                 0u,                                                                                                                     // signalSemaphoreCount
2936                 DE_NULL,                                                                                                        // pSignalSemaphores
2937         };
2938
2939         const VkSubmitInfo                                              submitInfoCountOne              =
2940         {
2941                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
2942                 DE_NULL,                                                                                                        // pNext
2943                 0u,                                                                                                                     // waitSemaphoreCount
2944                 DE_NULL,                                                                                                        // pWaitSemaphores
2945                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
2946                 1u,                                                                                                                     // commandBufferCount
2947                 &cmdBuffers[1],                                                                                         // pCommandBuffers
2948                 0u,                                                                                                                     // signalSemaphoreCount
2949                 DE_NULL,                                                                                                        // pSignalSemaphores
2950         };
2951
2952         // Submit the command buffers to the queue
2953         // We're performing two submits to make sure that the first one has
2954         // a chance to be processed before we check the event's status
2955         VK_CHECK(vk.queueSubmit(queue, 0, &submitInfoCountZero, fenceZero.get()));
2956         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfoCountOne, fenceOne.get()));
2957
2958         const VkFence                                                   fences[]                                =
2959         {
2960                 fenceZero.get(),
2961                 fenceOne.get(),
2962         };
2963
2964         // Wait for the queue
2965         VK_CHECK(vk.waitForFences(vkDevice, (deUint32)DE_LENGTH_OF_ARRAY(fences), fences, VK_TRUE, INFINITE_TIMEOUT));
2966
2967         // Check if the first buffer was executed
2968         tcu::TestStatus testResult = tcu::TestStatus::incomplete();
2969
2970         if (vk.getEventStatus(vkDevice, events[0]->get()) == VK_EVENT_SET)
2971                 testResult = tcu::TestStatus::fail("The first event was signaled.");
2972         else
2973                 testResult = tcu::TestStatus::pass("The first submission was ignored.");
2974
2975         return testResult;
2976 }
2977
2978 tcu::TestStatus submitBufferWaitSingleSemaphore(Context& context)
2979 {
2980         const VkDevice                                                  vkDevice                                = context.getDevice();
2981         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
2982         const VkQueue                                                   queue                                   = context.getUniversalQueue();
2983         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2984
2985         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
2986         {
2987                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // VkStructureType                              sType;
2988                 DE_NULL,                                                                                                        // const void*                                  pNext;
2989                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // VkCommandPoolCreateFlags             flags;
2990                 queueFamilyIndex,                                                                                       // deUint32                                             queueFamilyIndex;
2991         };
2992         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
2993
2994         // Command buffer
2995         const VkCommandBufferAllocateInfo               cmdBufParams                    =
2996         {
2997                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // VkStructureType                              sType;
2998                 DE_NULL,                                                                                                        // const void*                                  pNext;
2999                 *cmdPool,                                                                                                       // VkCommandPool                                pool;
3000                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // VkCommandBufferLevel                 level;
3001                 1u,                                                                                                                     // uint32_t                                             bufferCount;
3002         };
3003
3004         // Create two command buffers
3005         const Unique<VkCommandBuffer>                   primCmdBuf1                             (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3006         const Unique<VkCommandBuffer>                   primCmdBuf2                             (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3007
3008         const VkCommandBufferBeginInfo                  primCmdBufBeginInfo             =
3009         {
3010                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
3011                 DE_NULL,                                                                                                        // pNext
3012                 0,                                                                                                                      // flags
3013                 DE_NULL                                                                                                         // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
3014         };
3015
3016         // create two events that will be used to check if command buffers has been executed
3017         const Unique<VkEvent>                                   event1                                  (createEvent(vk, vkDevice));
3018         const Unique<VkEvent>                                   event2                                  (createEvent(vk, vkDevice));
3019
3020         // reset events
3021         VK_CHECK(vk.resetEvent(vkDevice, *event1));
3022         VK_CHECK(vk.resetEvent(vkDevice, *event2));
3023
3024         // record first command buffer
3025         VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo));
3026         {
3027                 // allow execution of event during every stage of pipeline
3028                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3029
3030                 // record setting event
3031                 vk.cmdSetEvent(*primCmdBuf1, *event1,stageMask);
3032         }
3033         endCommandBuffer(vk, *primCmdBuf1);
3034
3035         // record second command buffer
3036         VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo));
3037         {
3038                 // allow execution of event during every stage of pipeline
3039                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3040
3041                 // record setting event
3042                 vk.cmdSetEvent(*primCmdBuf2, *event2,stageMask);
3043         }
3044         endCommandBuffer(vk, *primCmdBuf2);
3045
3046         // create fence to wait for execution of queue
3047         const Unique<VkFence>                                   fence                                   (createFence(vk, vkDevice));
3048
3049         // create semaphore for use in this test
3050         const Unique <VkSemaphore>                              semaphore                               (createSemaphore(vk, vkDevice));
3051
3052         // create submit info for first buffer - signalling semaphore
3053         const VkSubmitInfo                                              submitInfo1                             =
3054         {
3055                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
3056                 DE_NULL,                                                                                                        // pNext
3057                 0u,                                                                                                                     // waitSemaphoreCount
3058                 DE_NULL,                                                                                                        // pWaitSemaphores
3059                 DE_NULL,                                                                                                        // pWaitDstStageMask
3060                 1,                                                                                                                      // commandBufferCount
3061                 &primCmdBuf1.get(),                                                                                     // pCommandBuffers
3062                 1u,                                                                                                                     // signalSemaphoreCount
3063                 &semaphore.get(),                                                                                       // pSignalSemaphores
3064         };
3065
3066         // Submit the command buffer to the queue
3067         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3068
3069         // wait for end of execution of queue
3070         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3071
3072         // check if buffer has been executed
3073         VkResult result = vk.getEventStatus(vkDevice,*event1);
3074         if (result != VK_EVENT_SET)
3075                 return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED");
3076
3077         const VkPipelineStageFlags                              waitDstStageFlags               = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
3078
3079         // create submit info for second buffer - waiting for semaphore
3080         const VkSubmitInfo                                              submitInfo2                             =
3081         {
3082                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
3083                 DE_NULL,                                                                                                        // pNext
3084                 1u,                                                                                                                     // waitSemaphoreCount
3085                 &semaphore.get(),                                                                                       // pWaitSemaphores
3086                 &waitDstStageFlags,                                                                                     // pWaitDstStageMask
3087                 1,                                                                                                                      // commandBufferCount
3088                 &primCmdBuf2.get(),                                                                                     // pCommandBuffers
3089                 0u,                                                                                                                     // signalSemaphoreCount
3090                 DE_NULL,                                                                                                        // pSignalSemaphores
3091         };
3092
3093         // reset fence, so it can be used again
3094         VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3095
3096         // Submit the second command buffer to the queue
3097         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3098
3099         // wait for end of execution of queue
3100         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3101
3102         // check if second buffer has been executed
3103         // if it has been executed, it means that the semaphore was signalled - so test if passed
3104         result = vk.getEventStatus(vkDevice,*event1);
3105         if (result != VK_EVENT_SET)
3106                 return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED");
3107
3108         return tcu::TestStatus::pass("Submit Buffer and Wait for Single Semaphore Test succeeded");
3109 }
3110
3111 tcu::TestStatus submitBufferWaitManySemaphores(Context& context)
3112 {
3113         // This test will create numSemaphores semaphores, and signal them in NUM_SEMAPHORES submits to queue
3114         // After that the numSubmissions queue submissions will wait for each semaphore
3115
3116         const deUint32                                                  numSemaphores                   = 10u;  // it must be multiply of numSubmission
3117         const deUint32                                                  numSubmissions                  = 2u;
3118         const VkDevice                                                  vkDevice                                = context.getDevice();
3119         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
3120         const VkQueue                                                   queue                                   = context.getUniversalQueue();
3121         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
3122
3123         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
3124         {
3125                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // VkStructureType                              sType;
3126                 DE_NULL,                                                                                                        // const void*                                  pNext;
3127                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // VkCommandPoolCreateFlags             flags;
3128                 queueFamilyIndex,                                                                                       // deUint32                                             queueFamilyIndex;
3129         };
3130         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
3131
3132         // Command buffer
3133         const VkCommandBufferAllocateInfo               cmdBufParams                    =
3134         {
3135                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // VkStructureType                              sType;
3136                 DE_NULL,                                                                                                        // const void*                                  pNext;
3137                 *cmdPool,                                                                                                       // VkCommandPool                                pool;
3138                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // VkCommandBufferLevel                 level;
3139                 1u,                                                                                                                     // uint32_t                                             bufferCount;
3140         };
3141
3142         // Create command buffer
3143         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3144
3145         const VkCommandBufferBeginInfo                  primCmdBufBeginInfo             =
3146         {
3147                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
3148                 DE_NULL,                                                                                                        // pNext
3149                 0,                                                                                                                      // flags
3150                 DE_NULL                                                                                                         // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
3151         };
3152
3153         // create event that will be used to check if command buffers has been executed
3154         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
3155
3156         // reset event - at creation state is undefined
3157         VK_CHECK(vk.resetEvent(vkDevice, *event));
3158
3159         // record command buffer
3160         VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3161         {
3162                 // allow execution of event during every stage of pipeline
3163                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3164
3165                 // record setting event
3166                 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
3167         }
3168         endCommandBuffer(vk, *primCmdBuf);
3169
3170         // create fence to wait for execution of queue
3171         const Unique<VkFence>                                   fence                                   (createFence(vk, vkDevice));
3172
3173         // numSemaphores is declared const, so this array can be static
3174         // the semaphores will be destroyed automatically at end of scope
3175         Move <VkSemaphore>                                              semaphoreArray[numSemaphores];
3176         VkSemaphore                                                             semaphores[numSemaphores];
3177
3178         for (deUint32 idx = 0; idx < numSemaphores; ++idx) {
3179                 // create semaphores for use in this test
3180                 semaphoreArray[idx] = createSemaphore(vk, vkDevice);
3181                 semaphores[idx] = semaphoreArray[idx].get();
3182         };
3183
3184         {
3185                 // create submit info for buffer - signal semaphores
3186                 const VkSubmitInfo submitInfo1 =
3187                 {
3188                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                  // sType
3189                         DE_NULL,                                                                                                // pNext
3190                         0u,                                                                                                             // waitSemaphoreCount
3191                         DE_NULL,                                                                                                // pWaitSemaphores
3192                         DE_NULL,                                                                                                // pWaitDstStageMask
3193                         1,                                                                                                              // commandBufferCount
3194                         &primCmdBuf.get(),                                                                              // pCommandBuffers
3195                         numSemaphores,                                                                                  // signalSemaphoreCount
3196                         semaphores                                                                                              // pSignalSemaphores
3197                 };
3198                 // Submit the command buffer to the queue
3199                 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3200
3201                 // wait for end of execution of queue
3202                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
3203
3204                 // check if buffer has been executed
3205                 VkResult result = vk.getEventStatus(vkDevice,*event);
3206                 if (result != VK_EVENT_SET)
3207                         return tcu::TestStatus::fail("Submit Buffer and Wait for Many Semaphores Test FAILED");
3208
3209                 // reset event, so next buffers can set it again
3210                 VK_CHECK(vk.resetEvent(vkDevice, *event));
3211
3212                 // reset fence, so it can be used again
3213                 VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3214         }
3215
3216         const deUint32                                                  numberOfSemaphoresToBeWaitedByOneSubmission     = numSemaphores / numSubmissions;
3217         const std::vector<VkPipelineStageFlags> waitDstStageFlags                                                       (numberOfSemaphoresToBeWaitedByOneSubmission, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
3218
3219         // the following code waits for the semaphores set above - numSubmissions queues will wait for each semaphore from above
3220         for (deUint32 idxSubmission = 0; idxSubmission < numSubmissions; ++idxSubmission) {
3221
3222                 // create submit info for buffer - waiting for semaphore
3223                 const VkSubmitInfo                              submitInfo2                             =
3224                 {
3225                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                                                          // sType
3226                         DE_NULL,                                                                                                                                        // pNext
3227                         numberOfSemaphoresToBeWaitedByOneSubmission,                                                            // waitSemaphoreCount
3228                         semaphores + (numberOfSemaphoresToBeWaitedByOneSubmission * idxSubmission),     // pWaitSemaphores
3229                         waitDstStageFlags.data(),                                                                                                       // pWaitDstStageMask
3230                         1,                                                                                                                                                      // commandBufferCount
3231                         &primCmdBuf.get(),                                                                                                                      // pCommandBuffers
3232                         0u,                                                                                                                                                     // signalSemaphoreCount
3233                         DE_NULL,                                                                                                                                        // pSignalSemaphores
3234                 };
3235
3236                 // Submit the second command buffer to the queue
3237                 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3238
3239                 // wait for 1 second.
3240                 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 1000 * 1000 * 1000));
3241
3242                 // check if second buffer has been executed
3243                 // if it has been executed, it means that the semaphore was signalled - so test if passed
3244                 VkResult result = vk.getEventStatus(vkDevice,*event);
3245                 if (result != VK_EVENT_SET)
3246                         return tcu::TestStatus::fail("Submit Buffer and Wait for Many Semaphores Test FAILED");
3247
3248                 // reset fence, so it can be used again
3249                 VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3250
3251                 // reset event, so next buffers can set it again
3252                 VK_CHECK(vk.resetEvent(vkDevice, *event));
3253         }
3254
3255         return tcu::TestStatus::pass("Submit Buffer and Wait for Many Semaphores Test succeeded");
3256 }
3257
3258 tcu::TestStatus submitBufferNullFence(Context& context)
3259 {
3260         const VkDevice                                                  vkDevice                                = context.getDevice();
3261         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
3262         const VkQueue                                                   queue                                   = context.getUniversalQueue();
3263         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
3264
3265         const short                                                             BUFFER_COUNT                    = 2;
3266
3267         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
3268         {
3269                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
3270                 DE_NULL,                                                                                                        // pNext;
3271                 0u,                                                                                                                     // flags;
3272                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
3273         };
3274         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
3275
3276         // Command buffer
3277         const VkCommandBufferAllocateInfo               cmdBufParams                    =
3278         {
3279                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
3280                 DE_NULL,                                                                                                        // pNext;
3281                 *cmdPool,                                                                                                       // pool;
3282                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
3283                 1u,                                                                                                                     // bufferCount;
3284         };
3285         VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3286         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3287                 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffers[ndx]));
3288
3289         const VkCommandBufferBeginInfo                  cmdBufBeginInfo                 =
3290         {
3291                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
3292                 DE_NULL,                                                                                                        // pNext
3293                 0u,                                                                                                                     // flags
3294                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3295         };
3296
3297         std::vector<VkEventSp>                                  events;
3298         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3299                 events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
3300
3301         // Record the command buffers
3302         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3303         {
3304                 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3305                 {
3306                         vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3307                 }
3308                 endCommandBuffer(vk, cmdBuffers[ndx]);
3309         }
3310
3311         // We'll use a fence to wait for the execution of the queue
3312         const Unique<VkFence>                                   fence                                   (createFence(vk, vkDevice));
3313
3314         const VkSubmitInfo                                              submitInfoNullFence             =
3315         {
3316                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
3317                 DE_NULL,                                                                                                        // pNext
3318                 0u,                                                                                                                     // waitSemaphoreCount
3319                 DE_NULL,                                                                                                        // pWaitSemaphores
3320                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
3321                 1u,                                                                                                                     // commandBufferCount
3322                 &cmdBuffers[0],                                                                                         // pCommandBuffers
3323                 0u,                                                                                                                     // signalSemaphoreCount
3324                 DE_NULL,                                                                                                        // pSignalSemaphores
3325         };
3326
3327         const VkSubmitInfo                                              submitInfoNonNullFence  =
3328         {
3329                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
3330                 DE_NULL,                                                                                                        // pNext
3331                 0u,                                                                                                                     // waitSemaphoreCount
3332                 DE_NULL,                                                                                                        // pWaitSemaphores
3333                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
3334                 1u,                                                                                                                     // commandBufferCount
3335                 &cmdBuffers[1],                                                                                         // pCommandBuffers
3336                 0u,                                                                                                                     // signalSemaphoreCount
3337                 DE_NULL,                                                                                                        // pSignalSemaphores
3338         };
3339
3340         // Perform two submissions - one with no fence, the other one with a valid
3341         // fence Hoping submitting the other buffer will give the first one time to
3342         // execute
3343         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNullFence, DE_NULL));
3344         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNonNullFence, fence.get()));
3345
3346         // Wait for the queue
3347         VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3348
3349
3350         tcu::TestStatus testResult = tcu::TestStatus::incomplete();
3351
3352         //Fence guaranteed that all buffers submited before fence were executed
3353         if (vk.getEventStatus(vkDevice, events[0]->get()) != VK_EVENT_SET || vk.getEventStatus(vkDevice, events[1]->get()) != VK_EVENT_SET)
3354         {
3355                 testResult = tcu::TestStatus::fail("One of the buffers was not executed.");
3356         }
3357         else
3358         {
3359                 testResult = tcu::TestStatus::pass("Buffers have been submitted and executed correctly.");
3360         }
3361
3362         vk.queueWaitIdle(queue);
3363         return testResult;
3364 }
3365
3366 tcu::TestStatus submitTwoBuffersOneBufferNullWithFence(Context& context)
3367 {
3368         const VkDevice                                                  vkDevice                                = context.getDevice();
3369         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
3370         const VkQueue                                                   queue                                   = context.getUniversalQueue();
3371         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
3372         const deUint32                                                  BUFFER_COUNT                    = 2u;
3373
3374         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
3375         {
3376                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // sType;
3377                 DE_NULL,                                                                                        // pNext;
3378                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // flags;
3379                 queueFamilyIndex,                                                                       // queueFamilyIndex;
3380         };
3381         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
3382
3383         const VkCommandBufferAllocateInfo               cmdBufParams                    =
3384         {
3385                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
3386                 DE_NULL,                                                                                // pNext;
3387                 *cmdPool,                                                                               // pool;
3388                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // level;
3389                 BUFFER_COUNT,                                                                   // bufferCount;
3390         };
3391
3392         VkCommandBuffer                                                 cmdBuffers[BUFFER_COUNT];
3393         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
3394
3395         const VkCommandBufferBeginInfo                  cmdBufBeginInfo                 =
3396         {
3397                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // sType
3398                 DE_NULL,                                                                                // pNext
3399                 0u,                                                                                             // flags
3400                 (const VkCommandBufferInheritanceInfo*)DE_NULL, // pInheritanceInfo
3401         };
3402
3403         std::vector<VkEventSp>                                  events;
3404         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3405                 events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
3406
3407         // Record the command buffers
3408         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3409         {
3410                 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3411                 {
3412                         vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3413                 }
3414                 VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
3415         }
3416
3417         // First command buffer
3418         const VkSubmitInfo                                              submitInfoNonNullFirst  =
3419         {
3420                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                          // sType
3421                 DE_NULL,                                                                        // pNext
3422                 0u,                                                                                     // waitSemaphoreCount
3423                 DE_NULL,                                                                        // pWaitSemaphores
3424                 (const VkPipelineStageFlags*)DE_NULL,           // pWaitDstStageMask
3425                 1u,                                                                                     // commandBufferCount
3426                 &cmdBuffers[0],                                                         // pCommandBuffers
3427                 0u,                                                                                     // signalSemaphoreCount
3428                 DE_NULL,                                                                        // pSignalSemaphores
3429         };
3430
3431         // Second command buffer
3432         const VkSubmitInfo                                              submitInfoNonNullSecond =
3433         {
3434                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                          // sType
3435                 DE_NULL,                                                                        // pNext
3436                 0u,                                                                                     // waitSemaphoreCount
3437                 DE_NULL,                                                                        // pWaitSemaphores
3438                 (const VkPipelineStageFlags*)DE_NULL,           // pWaitDstStageMask
3439                 1u,                                                                                     // commandBufferCount
3440                 &cmdBuffers[1],                                                         // pCommandBuffers
3441                 0u,                                                                                     // signalSemaphoreCount
3442                 DE_NULL,                                                                        // pSignalSemaphores
3443         };
3444
3445         // Fence will be submitted with the null queue
3446         const Unique<VkFence>                                   fence                                   (createFence(vk, vkDevice));
3447
3448         // Perform two separate queueSubmit calls on the same queue followed
3449         // by a third call with no submitInfos and with a valid fence
3450         VK_CHECK(vk.queueSubmit(queue,  1u,     &submitInfoNonNullFirst,        DE_NULL));
3451         VK_CHECK(vk.queueSubmit(queue,  1u,     &submitInfoNonNullSecond,       DE_NULL));
3452         VK_CHECK(vk.queueSubmit(queue,  0u,     DE_NULL,                                        fence.get()));
3453
3454         // Wait for the queue
3455         VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3456
3457         return tcu::TestStatus::pass("Buffers have been submitted correctly");
3458 }
3459
3460 /******** 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) *******/
3461 tcu::TestStatus executeSecondaryBufferTest(Context& context)
3462 {
3463         const VkDevice                                                  vkDevice                                = context.getDevice();
3464         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
3465         const VkQueue                                                   queue                                   = context.getUniversalQueue();
3466         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
3467
3468         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
3469         {
3470                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
3471                 DE_NULL,                                                                                                        // pNext;
3472                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        // flags;
3473                 queueFamilyIndex,                                                                                       // queueFamilyIndex;
3474         };
3475         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
3476
3477         // Command buffer
3478         const VkCommandBufferAllocateInfo               cmdBufParams                    =
3479         {
3480                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
3481                 DE_NULL,                                                                                                        // pNext;
3482                 *cmdPool,                                                                                                       // commandPool;
3483                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level;
3484                 1u,                                                                                                                     // bufferCount;
3485         };
3486         const Unique<VkCommandBuffer>                   primCmdBuf                              (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3487
3488         // Secondary Command buffer
3489         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
3490         {
3491                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType;
3492                 DE_NULL,                                                                                                        // pNext;
3493                 *cmdPool,                                                                                                       // commandPool;
3494                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      // level;
3495                 1u,                                                                                                                     // bufferCount;
3496         };
3497         const Unique<VkCommandBuffer>                   secCmdBuf                               (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
3498
3499         const VkCommandBufferBeginInfo                  primCmdBufBeginInfo             =
3500         {
3501                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
3502                 DE_NULL,                                                                                                        // pNext
3503                 0u,                                                                                                                     // flags
3504                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3505         };
3506
3507         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
3508         {
3509                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3510                 DE_NULL,
3511                 DE_NULL,                                                                                                        // renderPass
3512                 0u,                                                                                                                     // subpass
3513                 DE_NULL,                                                                                                        // framebuffer
3514                 VK_FALSE,                                                                                                       // occlusionQueryEnable
3515                 (VkQueryControlFlags)0u,                                                                        // queryFlags
3516                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
3517         };
3518         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
3519         {
3520                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
3521                 DE_NULL,                                                                                                        // pNext
3522                 0u,                                                                                                                     // flags
3523                 &secCmdBufInheritInfo,
3524         };
3525
3526         // create event that will be used to check if secondary command buffer has been executed
3527         const Unique<VkEvent>                                   event                                   (createEvent(vk, vkDevice));
3528
3529         // reset event
3530         VK_CHECK(vk.resetEvent(vkDevice, *event));
3531
3532         // record secondary command buffer
3533         VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
3534         {
3535                 // allow execution of event during every stage of pipeline
3536                 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3537                 // record setting event
3538                 vk.cmdSetEvent(*secCmdBuf, *event, stageMask);
3539         }
3540         // end recording of the secondary buffer
3541         endCommandBuffer(vk, *secCmdBuf);
3542
3543         // record primary command buffer
3544         VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3545         {
3546                 // execute secondary buffer
3547                 vk.cmdExecuteCommands(*primCmdBuf, 1u, &secCmdBuf.get());
3548         }
3549         endCommandBuffer(vk, *primCmdBuf);
3550
3551         submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
3552
3553         // check if secondary buffer has been executed
3554         VkResult result = vk.getEventStatus(vkDevice, *event);
3555         if (result == VK_EVENT_SET)
3556                 return tcu::TestStatus::pass("executeSecondaryBufferTest succeeded");
3557
3558         return tcu::TestStatus::fail("executeSecondaryBufferTest FAILED");
3559 }
3560
3561 tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context)
3562 {
3563         const deUint32                                                  BUFFER_COUNT                    = 10u;
3564         const VkDevice                                                  vkDevice                                = context.getDevice();
3565         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
3566         const VkQueue                                                   queue                                   = context.getUniversalQueue();
3567         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
3568
3569         const VkCommandPoolCreateInfo                   cmdPoolParams                   =
3570         {
3571                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     //      VkStructureType                         sType;
3572                 DE_NULL,                                                                                                        //      const void*                                     pNext;
3573                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,                        //      VkCommandPoolCreateFlags        flags;
3574                 queueFamilyIndex,                                                                                       //      deUint32                                        queueFamilyIndex;
3575         };
3576         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, vkDevice, &cmdPoolParams));
3577
3578         // Command buffer
3579         const VkCommandBufferAllocateInfo               cmdBufParams                    =
3580         {
3581                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
3582                 DE_NULL,                                                                                                        //      const void*                             pNext;
3583                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
3584                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        //      VkCommandBufferLevel            level;
3585                 1u,                                                                                                                     //      uint32_t                                        bufferCount;
3586         };
3587         const Unique<VkCommandBuffer>                   primCmdBufOne                   (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3588         const Unique<VkCommandBuffer>                   primCmdBufTwo                   (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3589
3590         // Secondary Command buffers params
3591         const VkCommandBufferAllocateInfo               secCmdBufParams                 =
3592         {
3593                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         //      VkStructureType                 sType;
3594                 DE_NULL,                                                                                                        //      const void*                             pNext;
3595                 *cmdPool,                                                                                                       //      VkCommandPool                           pool;
3596                 VK_COMMAND_BUFFER_LEVEL_SECONDARY,                                                      //      VkCommandBufferLevel            level;
3597                 BUFFER_COUNT,                                                                                           //      uint32_t                                        bufferCount;
3598         };
3599         VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3600         VK_CHECK(vk.allocateCommandBuffers(vkDevice, &secCmdBufParams, cmdBuffers));
3601
3602         const VkCommandBufferBeginInfo                  primCmdBufBeginInfo             =
3603         {
3604                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3605                 DE_NULL,
3606                 0,                                                                                                                      // flags
3607                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3608         };
3609
3610         const VkCommandBufferInheritanceInfo    secCmdBufInheritInfo    =
3611         {
3612                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3613                 DE_NULL,
3614                 (VkRenderPass)0u,                                                                                       // renderPass
3615                 0u,                                                                                                                     // subpass
3616                 (VkFramebuffer)0u,                                                                                      // framebuffer
3617                 VK_FALSE,                                                                                                       // occlusionQueryEnable
3618                 (VkQueryControlFlags)0u,                                                                        // queryFlags
3619                 (VkQueryPipelineStatisticFlags)0u,                                                      // pipelineStatistics
3620         };
3621         const VkCommandBufferBeginInfo                  secCmdBufBeginInfo              =
3622         {
3623                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3624                 DE_NULL,
3625                 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,                           // flags
3626                 &secCmdBufInheritInfo,
3627         };
3628
3629         // create event that will be used to check if secondary command buffer has been executed
3630         const Unique<VkEvent>                                   eventOne                                (createEvent(vk, vkDevice));
3631
3632         // reset event
3633         VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
3634
3635         for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3636         {
3637                 // record secondary command buffer
3638                 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &secCmdBufBeginInfo));
3639                 {
3640                         // allow execution of event during every stage of pipeline
3641                         VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3642
3643                         // wait for event
3644                         vk.cmdWaitEvents(cmdBuffers[ndx], 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
3645                 }
3646                 // end recording of secondary buffers
3647                 endCommandBuffer(vk, cmdBuffers[ndx]);
3648         };
3649
3650         // record primary command buffer one
3651         VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
3652         {
3653                 // execute one secondary buffer
3654                 vk.cmdExecuteCommands(*primCmdBufOne, 1, cmdBuffers );
3655         }
3656         endCommandBuffer(vk, *primCmdBufOne);
3657
3658         // record primary command buffer two
3659         VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
3660         {
3661                 // execute one secondary buffer with all buffers
3662                 vk.cmdExecuteCommands(*primCmdBufTwo, BUFFER_COUNT, cmdBuffers );
3663         }
3664         endCommandBuffer(vk, *primCmdBufTwo);
3665
3666         // create fence to wait for execution of queue
3667         const Unique<VkFence>                                   fenceOne                                (createFence(vk, vkDevice));
3668         const Unique<VkFence>                                   fenceTwo                                (createFence(vk, vkDevice));
3669
3670         const VkSubmitInfo                                              submitInfoOne                   =
3671         {
3672                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
3673                 DE_NULL,                                                                                                        // pNext
3674                 0u,                                                                                                                     // waitSemaphoreCount
3675                 DE_NULL,                                                                                                        // pWaitSemaphores
3676                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
3677                 1,                                                                                                                      // commandBufferCount
3678                 &primCmdBufOne.get(),                                                                           // pCommandBuffers
3679                 0u,                                                                                                                     // signalSemaphoreCount
3680                 DE_NULL,                                                                                                        // pSignalSemaphores
3681         };
3682
3683         // submit primary buffer, the secondary should be executed too
3684         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoOne, *fenceOne));
3685
3686         // wait for buffer to stop at event for 100 microseconds
3687         vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
3688
3689         const VkSubmitInfo                                              submitInfoTwo                   =
3690         {
3691                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                          // sType
3692                 DE_NULL,                                                                                                        // pNext
3693                 0u,                                                                                                                     // waitSemaphoreCount
3694                 DE_NULL,                                                                                                        // pWaitSemaphores
3695                 (const VkPipelineStageFlags*)DE_NULL,                                           // pWaitDstStageMask
3696                 1,                                                                                                                      // commandBufferCount
3697                 &primCmdBufTwo.get(),                                                                           // pCommandBuffers
3698                 0u,                                                                                                                     // signalSemaphoreCount
3699                 DE_NULL,                                                                                                        // pSignalSemaphores
3700         };
3701
3702         // submit second primary buffer, the secondary should be executed too
3703         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoTwo, *fenceTwo));
3704
3705         // wait for all buffers to stop at event for 100 microseconds
3706         vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
3707
3708         // now all buffers are waiting at eventOne
3709         // set event eventOne
3710         VK_CHECK(vk.setEvent(vkDevice, *eventOne));
3711
3712         // wait for end of execution of fenceOne
3713         VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, INFINITE_TIMEOUT));
3714
3715         // wait for end of execution of second queue
3716         VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceTwo.get(), 0u, INFINITE_TIMEOUT));
3717
3718         return tcu::TestStatus::pass("executeSecondaryBufferTwiceTest succeeded");
3719 }
3720
3721 /******** 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) **/
3722 tcu::TestStatus orderBindPipelineTest(Context& context)
3723 {
3724         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
3725         const VkDevice                                                  device                                  = context.getDevice();
3726         const VkQueue                                                   queue                                   = context.getUniversalQueue();
3727         const deUint32                                                  queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
3728         Allocator&                                                              allocator                               = context.getDefaultAllocator();
3729         const ComputeInstanceResultBuffer               result                                  (vk, device, allocator);
3730
3731         enum
3732         {
3733                 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
3734         };
3735
3736         const tcu::Vec4                                                 colorA1                                 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
3737         const tcu::Vec4                                                 colorA2                                 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
3738         const tcu::Vec4                                                 colorB1                                 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
3739         const tcu::Vec4                                                 colorB2                                 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
3740
3741         const deUint32                                                  dataOffsetA                             = (0u);
3742         const deUint32                                                  dataOffsetB                             = (0u);
3743         const deUint32                                                  viewOffsetA                             = (0u);
3744         const deUint32                                                  viewOffsetB                             = (0u);
3745         const deUint32                                                  bufferSizeA                             = dataOffsetA + ADDRESSABLE_SIZE;
3746         const deUint32                                                  bufferSizeB                             = dataOffsetB + ADDRESSABLE_SIZE;
3747
3748         de::MovePtr<Allocation>                                 bufferMemA;
3749         const Unique<VkBuffer>                                  bufferA                                 (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA, context));
3750
3751         de::MovePtr<Allocation>                                 bufferMemB;
3752         const Unique<VkBuffer>                                  bufferB                                 (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB, context));
3753
3754         const Unique<VkDescriptorSetLayout>             descriptorSetLayout             (createDescriptorSetLayout(context));
3755         const Unique<VkDescriptorPool>                  descriptorPool                  (createDescriptorPool(context));
3756         const Unique<VkDescriptorSet>                   descriptorSet                   (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, result.getBuffer(), context));
3757         const VkDescriptorSet                                   descriptorSets[]                = { *descriptorSet };
3758         const int                                                               numDescriptorSets               = DE_LENGTH_OF_ARRAY(descriptorSets);
3759
3760         const VkPipelineLayoutCreateInfo layoutCreateInfo =
3761         {
3762                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // sType
3763                 DE_NULL,                                                                                                        // pNext
3764                 (VkPipelineLayoutCreateFlags)0,
3765                 numDescriptorSets,                                                                                      // setLayoutCount
3766                 &descriptorSetLayout.get(),                                                                     // pSetLayouts
3767                 0u,                                                                                                                     // pushConstantRangeCount
3768                 DE_NULL,                                                                                                        // pPushConstantRanges
3769         };
3770         Unique<VkPipelineLayout>                                pipelineLayout                  (createPipelineLayout(vk, device, &layoutCreateInfo));
3771
3772         const Unique<VkShaderModule>                    computeModuleGood               (createShaderModule(vk, device, context.getBinaryCollection().get("compute_good"), (VkShaderModuleCreateFlags)0u));
3773         const Unique<VkShaderModule>                    computeModuleBad                (createShaderModule(vk, device, context.getBinaryCollection().get("compute_bad"),  (VkShaderModuleCreateFlags)0u));
3774
3775         const VkPipelineShaderStageCreateInfo   shaderCreateInfoGood    =
3776         {
3777                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3778                 DE_NULL,
3779                 (VkPipelineShaderStageCreateFlags)0,
3780                 VK_SHADER_STAGE_COMPUTE_BIT,                                                            // stage
3781                 *computeModuleGood,                                                                                     // shader
3782                 "main",
3783                 DE_NULL,                                                                                                        // pSpecializationInfo
3784         };
3785
3786         const VkPipelineShaderStageCreateInfo   shaderCreateInfoBad     =
3787         {
3788                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3789                 DE_NULL,
3790                 (vk::VkPipelineShaderStageCreateFlags)0,
3791                 vk::VK_SHADER_STAGE_COMPUTE_BIT,                                                        // stage
3792                 *computeModuleBad,                                                                                      // shader
3793                 "main",
3794                 DE_NULL,                                                                                                        // pSpecializationInfo
3795         };
3796
3797         const VkComputePipelineCreateInfo               createInfoGood                  =
3798         {
3799                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3800                 DE_NULL,
3801                 0u,                                                                                                                     // flags
3802                 shaderCreateInfoGood,                                                                           // cs
3803                 *pipelineLayout,                                                                                        // layout
3804                 (vk::VkPipeline)0,                                                                                      // basePipelineHandle
3805                 0u,                                                                                                                     // basePipelineIndex
3806         };
3807
3808         const VkComputePipelineCreateInfo               createInfoBad                   =
3809         {
3810                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3811                 DE_NULL,
3812                 0u,                                                                                                                     // flags
3813                 shaderCreateInfoBad,                                                                            // cs
3814                 *pipelineLayout,                                                                                        // descriptorSetLayout.get()
3815                 (VkPipeline)0,                                                                                          // basePipelineHandle
3816                 0u,                                                                                                                     // basePipelineIndex
3817         };
3818
3819         const Unique<VkPipeline>                                pipelineGood                    (createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoGood));
3820         const Unique<VkPipeline>                                pipelineBad                             (createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoBad));
3821
3822         const VkAccessFlags                                             inputBit                                = (VK_ACCESS_UNIFORM_READ_BIT);
3823         const VkBufferMemoryBarrier                             bufferBarriers[]                =
3824         {
3825                 {
3826                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3827                         DE_NULL,
3828                         VK_ACCESS_HOST_WRITE_BIT,                                                                       // srcAccessMask
3829                         inputBit,                                                                                                       // dstAccessMask
3830                         VK_QUEUE_FAMILY_IGNORED,                                                                        // srcQueueFamilyIndex
3831                         VK_QUEUE_FAMILY_IGNORED,                                                                        // destQueueFamilyIndex
3832                         *bufferA,                                                                                                       // buffer
3833                         (VkDeviceSize)0u,                                                                                       // offset
3834                         (VkDeviceSize)bufferSizeA,                                                                      // size
3835                 },
3836                 {
3837                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3838                         DE_NULL,
3839                         VK_ACCESS_HOST_WRITE_BIT,                                                                       // srcAccessMask
3840                         inputBit,                                                                                                       // dstAccessMask
3841                         VK_QUEUE_FAMILY_IGNORED,                                                                        // srcQueueFamilyIndex
3842                         VK_QUEUE_FAMILY_IGNORED,                                                                        // destQueueFamilyIndex
3843                         *bufferB,                                                                                                       // buffer
3844                         (VkDeviceSize)0u,                                                                                       // offset
3845                         (VkDeviceSize)bufferSizeB,                                                                      // size
3846                 }
3847         };
3848
3849         const deUint32                                                  numSrcBuffers                   = 1u;
3850
3851         const deUint32* const                                   dynamicOffsets                  = (DE_NULL);
3852         const deUint32                                                  numDynamicOffsets               = (0);
3853         const int                                                               numPreBarriers                  = numSrcBuffers;
3854         const vk::VkBufferMemoryBarrier* const  postBarriers                    = result.getResultReadBarrier();
3855         const int                                                               numPostBarriers                 = 1;
3856         const tcu::Vec4                                                 refQuadrantValue14              = (colorA2);
3857         const tcu::Vec4                                                 refQuadrantValue23              = (colorA1);
3858         const tcu::Vec4                                                 references[4]                   =
3859         {
3860                 refQuadrantValue14,
3861                 refQuadrantValue23,
3862                 refQuadrantValue23,
3863                 refQuadrantValue14,
3864         };
3865         tcu::Vec4                                                               results[4];
3866
3867         // submit and wait begin
3868
3869         const tcu::UVec3 numWorkGroups = tcu::UVec3(4, 1u, 1);
3870
3871         const VkCommandPoolCreateInfo                   cmdPoolCreateInfo               =
3872         {
3873                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                                     // sType;
3874                 DE_NULL,                                                                                                        // pNext
3875                 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                                           // flags
3876                 queueFamilyIndex,                                                                                       // queueFamilyIndex
3877         };
3878         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool(vk, device, &cmdPoolCreateInfo));
3879         const VkCommandBufferAllocateInfo               cmdBufCreateInfo                =
3880         {
3881                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,                         // sType
3882                 DE_NULL,                                                                                                        // pNext
3883                 *cmdPool,                                                                                                       // commandPool
3884                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                                        // level
3885                 1u,                                                                                                                     // bufferCount;
3886         };
3887
3888         const VkCommandBufferBeginInfo                  cmdBufBeginInfo                 =
3889         {
3890                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                            // sType
3891                 DE_NULL,                                                                                                        // pNext
3892                 0u,                                                                                                                     // flags
3893                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3894         };
3895
3896         const Unique<VkCommandBuffer>                   cmd                                             (allocateCommandBuffer(vk, device, &cmdBufCreateInfo));
3897
3898         VK_CHECK(vk.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3899
3900         vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineBad);
3901         vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineGood);
3902         vk.cmdBindDescriptorSets(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, numDynamicOffsets, dynamicOffsets);
3903
3904         if (numPreBarriers)
3905                 vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0,
3906                                                           0, (const VkMemoryBarrier*)DE_NULL,
3907                                                           numPreBarriers, bufferBarriers,
3908                                                           0, (const VkImageMemoryBarrier*)DE_NULL);
3909
3910         vk.cmdDispatch(*cmd, numWorkGroups.x(), numWorkGroups.y(), numWorkGroups.z());
3911         vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
3912                                                   0, (const VkMemoryBarrier*)DE_NULL,
3913                                                   numPostBarriers, postBarriers,
3914                                                   0, (const VkImageMemoryBarrier*)DE_NULL);
3915         endCommandBuffer(vk, *cmd);
3916
3917         // run
3918         // submit second primary buffer, the secondary should be executed too
3919         submitCommandsAndWait(vk, device, queue, cmd.get());
3920
3921         // submit and wait end
3922         result.readResultContentsTo(&results);
3923
3924         // verify
3925         if (results[0] == references[0] &&
3926                 results[1] == references[1] &&
3927                 results[2] == references[2] &&
3928                 results[3] == references[3])
3929         {
3930                 return tcu::TestStatus::pass("Pass");
3931         }
3932         else if (results[0] == tcu::Vec4(-1.0f) &&
3933                          results[1] == tcu::Vec4(-1.0f) &&
3934                          results[2] == tcu::Vec4(-1.0f) &&
3935                          results[3] == tcu::Vec4(-1.0f))
3936         {
3937                 context.getTestContext().getLog()
3938                 << tcu::TestLog::Message
3939                 << "Result buffer was not written to."
3940                 << tcu::TestLog::EndMessage;
3941                 return tcu::TestStatus::fail("Result buffer was not written to");
3942         }
3943         else
3944         {
3945                 context.getTestContext().getLog()
3946                 << tcu::TestLog::Message
3947                 << "Error expected ["
3948                 << references[0] << ", "
3949                 << references[1] << ", "
3950                 << references[2] << ", "
3951                 << references[3] << "], got ["
3952                 << results[0] << ", "
3953                 << results[1] << ", "
3954                 << results[2] << ", "
3955                 << results[3] << "]"
3956                 << tcu::TestLog::EndMessage;
3957                 return tcu::TestStatus::fail("Invalid result values");
3958         }
3959 }
3960
3961 enum StateTransitionTest
3962 {
3963         STT_RECORDING_TO_INITIAL        = 0,
3964         STT_EXECUTABLE_TO_INITIAL,
3965         STT_RECORDING_TO_INVALID,
3966         STT_EXECUTABLE_TO_INVALID,
3967 };
3968
3969 tcu::TestStatus executeStateTransitionTest(Context& context, StateTransitionTest type)
3970 {
3971         const VkDevice                                  vkDevice                        = context.getDevice();
3972         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
3973         const VkQueue                                   queue                           = context.getUniversalQueue();
3974         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
3975         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
3976         const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3977         const Unique<VkEvent>                   globalEvent                     (createEvent(vk, vkDevice));
3978
3979         VK_CHECK(vk.resetEvent(vkDevice, *globalEvent));
3980
3981         switch (type)
3982         {
3983                 case STT_RECORDING_TO_INITIAL:
3984                 {
3985                         beginCommandBuffer(vk, *cmdBuffer, 0u);
3986                         vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3987                         break;
3988                         // command buffer is still in recording state
3989                 }
3990                 case STT_EXECUTABLE_TO_INITIAL:
3991                 {
3992                         beginCommandBuffer(vk, *cmdBuffer, 0u);
3993                         vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3994                         endCommandBuffer(vk, *cmdBuffer);
3995                         break;
3996                         // command buffer is still in executable state
3997                 }
3998                 case STT_RECORDING_TO_INVALID:
3999                 {
4000                         VkSubpassDescription subpassDescription;
4001                         deMemset(&subpassDescription, 0, sizeof(VkSubpassDescription));
4002                         subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4003
4004                         VkRenderPassCreateInfo renderPassCreateInfo
4005                         {
4006                                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
4007                                 DE_NULL, 0, 0, DE_NULL,
4008                                 1, &subpassDescription, 0, DE_NULL
4009                         };
4010
4011                         // Error here - renderpass and framebuffer were created localy
4012                         Move <VkRenderPass> renderPass = createRenderPass(vk, vkDevice, &renderPassCreateInfo);
4013
4014                         VkFramebufferCreateInfo framebufferCreateInfo
4015                         {
4016                                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, DE_NULL,
4017                                 0, *renderPass, 0, DE_NULL, 16, 16, 1
4018                         };
4019                         Move <VkFramebuffer> framebuffer = createFramebuffer(vk, vkDevice, &framebufferCreateInfo);
4020
4021                         VkRenderPassBeginInfo renderPassBeginInfo =
4022                         {
4023                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4024                                 DE_NULL, *renderPass, *framebuffer, { { 0, 0 }, { 16, 16 } },
4025                                 0, DE_NULL
4026                         };
4027
4028                         beginCommandBuffer(vk, *cmdBuffer, 0u);
4029                         vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
4030                         vk.cmdEndRenderPass(*cmdBuffer);
4031
4032                         // not executing endCommandBuffer(vk, *cmdBuffer);
4033                         // command buffer is still in recording state
4034                         break;
4035                         // renderpass and framebuffer are destroyed; command buffer should be now in invalid state
4036                 }
4037                 case STT_EXECUTABLE_TO_INVALID:
4038                 {
4039                         // create event that will be used to check if command buffer has been executed
4040                         const Unique<VkEvent> localEvent(createEvent(vk, vkDevice));
4041                         VK_CHECK(vk.resetEvent(vkDevice, *localEvent));
4042
4043                         beginCommandBuffer(vk, *cmdBuffer, 0u);
4044                         vk.cmdSetEvent(*cmdBuffer, *localEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4045                         endCommandBuffer(vk, *cmdBuffer);
4046                         // command buffer is in executable state
4047                         break;
4048                         // localEvent is destroyed; command buffer should be now in invalid state
4049                 }
4050         }
4051
4052         VK_CHECK(vk.resetEvent(vkDevice, *globalEvent));
4053
4054         vk.resetCommandBuffer(*cmdBuffer, 0u);
4055         // command buffer should now be back in initial state
4056
4057         // verify commandBuffer
4058         beginCommandBuffer(vk, *cmdBuffer, 0u);
4059         vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4060         endCommandBuffer(vk, *cmdBuffer);
4061         submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
4062
4063         // check if buffer has been executed
4064         VkResult result = vk.getEventStatus(vkDevice, *globalEvent);
4065         if (result != VK_EVENT_SET)
4066                 return tcu::TestStatus::fail("Submit failed");
4067
4068         return tcu::TestStatus::pass("Pass");
4069 }
4070
4071 // Shaders
4072 void genComputeSource (SourceCollections& programCollection)
4073 {
4074         const char* const                                               versionDecl                             = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4075         std::ostringstream                                              bufGood;
4076
4077         bufGood << versionDecl << "\n"
4078         << ""
4079         << "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4080         << "layout(set = 0, binding = 1u, std140) uniform BufferName\n"
4081         << "{\n"
4082         << "    highp vec4 colorA;\n"
4083         << "    highp vec4 colorB;\n"
4084         << "} b_instance;\n"
4085         << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
4086         << "{\n"
4087         << "    highp vec4 read_colors[4];\n"
4088         << "} b_out;\n"
4089         << "void main(void)\n"
4090         << "{\n"
4091         << "    highp int quadrant_id = int(gl_WorkGroupID.x);\n"
4092         << "    highp vec4 result_color;\n"
4093         << "    if (quadrant_id == 1 || quadrant_id == 2)\n"
4094         << "            result_color = b_instance.colorA;\n"
4095         << "    else\n"
4096         << "            result_color = b_instance.colorB;\n"
4097         << "    b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
4098         << "}\n";
4099
4100         programCollection.glslSources.add("compute_good") << glu::ComputeSource(bufGood.str());
4101
4102         std::ostringstream      bufBad;
4103
4104         bufBad  << versionDecl << "\n"
4105         << ""
4106         << "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4107         << "layout(set = 0, binding = 1u, std140) uniform BufferName\n"
4108         << "{\n"
4109         << "    highp vec4 colorA;\n"
4110         << "    highp vec4 colorB;\n"
4111         << "} b_instance;\n"
4112         << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
4113         << "{\n"
4114         << "    highp vec4 read_colors[4];\n"
4115         << "} b_out;\n"
4116         << "void main(void)\n"
4117         << "{\n"
4118         << "    highp int quadrant_id = int(gl_WorkGroupID.x);\n"
4119         << "    highp vec4 result_color;\n"
4120         << "    if (quadrant_id == 1 || quadrant_id == 2)\n"
4121         << "            result_color = b_instance.colorA;\n"
4122         << "    else\n"
4123         << "            result_color = b_instance.colorB;\n"
4124         << "    b_out.read_colors[gl_WorkGroupID.x] = vec4(0.0, 0.0, 0.0, 0.0);\n"
4125         << "}\n";
4126
4127         programCollection.glslSources.add("compute_bad") << glu::ComputeSource(bufBad.str());
4128 }
4129
4130 void genComputeIncrementSource (SourceCollections& programCollection)
4131 {
4132         const char* const                                               versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4133         std::ostringstream                                              bufIncrement;
4134
4135         bufIncrement << versionDecl << "\n"
4136                 << ""
4137                 << "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
4138                 << "layout(set = 0, binding = 0, std140) buffer InOutBuf\n"
4139                 << "{\n"
4140                 << "    coherent uint count;\n"
4141                 << "} b_in_out;\n"
4142                 << "void main(void)\n"
4143                 << "{\n"
4144                 << "    atomicAdd(b_in_out.count, 1u);\n"
4145                 << "}\n";
4146
4147         programCollection.glslSources.add("compute_increment") << glu::ComputeSource(bufIncrement.str());
4148 }
4149
4150 void genComputeIncrementSourceBadInheritance(SourceCollections& programCollection, BadInheritanceInfoCase testCase)
4151 {
4152         DE_UNREF(testCase);
4153         return genComputeIncrementSource(programCollection);
4154 }
4155
4156 void checkEventSupport (Context& context)
4157 {
4158 #ifndef CTS_USES_VULKANSC
4159         if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getPortabilitySubsetFeatures().events)
4160                 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation");
4161 #else
4162         DE_UNREF(context);
4163 #endif // CTS_USES_VULKANSC
4164 }
4165
4166 void checkEventSupport (Context& context, const VkCommandBufferLevel)
4167 {
4168         checkEventSupport(context);
4169 }
4170
4171 struct ManyDrawsParams
4172 {
4173         VkCommandBufferLevel    level;
4174         VkExtent3D                              imageExtent;
4175         deUint32                                seed;
4176
4177         ManyDrawsParams(VkCommandBufferLevel level_, const VkExtent3D& extent_, deUint32 seed_)
4178                 : level                 (level_)
4179                 , imageExtent   (extent_)
4180                 , seed                  (seed_)
4181         {}
4182 };
4183
4184 struct ManyDrawsVertex
4185 {
4186         using Color = tcu::Vector<deUint8, 4>;
4187
4188         tcu::Vec2       coords;
4189         Color           color;
4190
4191         ManyDrawsVertex (const tcu::Vec2& coords_, const Color& color_) : coords(coords_), color(color_) {}
4192 };
4193
4194 VkFormat getSupportedDepthStencilFormat (const InstanceInterface& vki, VkPhysicalDevice physDev)
4195 {
4196         const VkFormat                          formatList[]    = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
4197         const VkFormatFeatureFlags      requirements    = (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
4198
4199         for (int i = 0; i < DE_LENGTH_OF_ARRAY(formatList); ++i)
4200         {
4201                 const auto properties = getPhysicalDeviceFormatProperties(vki, physDev, formatList[i]);
4202                 if ((properties.optimalTilingFeatures & requirements) == requirements)
4203                         return formatList[i];
4204         }
4205
4206         TCU_THROW(NotSupportedError, "No suitable depth/stencil format support");
4207         return VK_FORMAT_UNDEFINED;
4208 }
4209
4210 class ManyDrawsCase : public TestCase
4211 {
4212 public:
4213                                                         ManyDrawsCase                   (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const ManyDrawsParams& params);
4214         virtual                                 ~ManyDrawsCase                  (void) {}
4215
4216         virtual void                    checkSupport                    (Context& context) const;
4217         virtual void                    initPrograms                    (vk::SourceCollections& programCollection) const;
4218         virtual TestInstance*   createInstance                  (Context& context) const;
4219
4220         static VkFormat                 getColorFormat                  (void) { return VK_FORMAT_R8G8B8A8_UINT; }
4221
4222 protected:
4223         ManyDrawsParams                 m_params;
4224 };
4225
4226 class ManyDrawsInstance : public TestInstance
4227 {
4228 public:
4229                                                                 ManyDrawsInstance       (Context& context, const ManyDrawsParams& params);
4230         virtual                                         ~ManyDrawsInstance      (void) {}
4231
4232         virtual tcu::TestStatus         iterate                         (void);
4233
4234 protected:
4235         ManyDrawsParams                         m_params;
4236 };
4237
4238 using BufferPtr = de::MovePtr<BufferWithMemory>;
4239 using ImagePtr = de::MovePtr<ImageWithMemory>;
4240
4241 struct ManyDrawsVertexBuffers
4242 {
4243         BufferPtr stagingBuffer;
4244         BufferPtr vertexBuffer;
4245 };
4246
4247 struct ManyDrawsAllocatedData
4248 {
4249         ManyDrawsVertexBuffers  frontBuffers;
4250         ManyDrawsVertexBuffers  backBuffers;
4251         ImagePtr                                colorAttachment;
4252         ImagePtr                                dsAttachment;
4253         BufferPtr                               colorCheckBuffer;
4254         BufferPtr                               stencilCheckBuffer;
4255
4256         static deUint32 calcNumPixels (const VkExtent3D& extent)
4257         {
4258                 DE_ASSERT(extent.depth == 1u);
4259                 return (extent.width * extent.height);
4260         }
4261         static deUint32 calcNumVertices (const VkExtent3D& extent)
4262         {
4263                 // One triangle (3 vertices) per output image pixel.
4264                 return (calcNumPixels(extent) * 3u);
4265         }
4266
4267         static VkDeviceSize calcVertexBufferSize (const VkExtent3D& extent)
4268         {
4269                 return calcNumVertices(extent) * sizeof(ManyDrawsVertex);
4270         }
4271
4272         static void makeVertexBuffers (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkDeviceSize size, ManyDrawsVertexBuffers& buffers)
4273         {
4274                 const auto stagingBufferInfo    = makeBufferCreateInfo(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
4275                 const auto vertexBufferInfo             = makeBufferCreateInfo(size, (VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
4276
4277                 buffers.stagingBuffer   = BufferPtr(new BufferWithMemory(vkd, device, alloc, stagingBufferInfo, MemoryRequirement::HostVisible));
4278                 buffers.vertexBuffer    = BufferPtr(new BufferWithMemory(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::Any));
4279         }
4280
4281         ManyDrawsAllocatedData (const DeviceInterface &vkd, VkDevice device, Allocator &alloc, const VkExtent3D& imageExtent, VkFormat colorFormat, VkFormat dsFormat)
4282         {
4283                 const auto numPixels            = calcNumPixels(imageExtent);
4284                 const auto vertexBufferSize     = calcVertexBufferSize(imageExtent);
4285
4286                 makeVertexBuffers(vkd, device, alloc, vertexBufferSize, frontBuffers);
4287                 makeVertexBuffers(vkd, device, alloc, vertexBufferSize, backBuffers);
4288
4289                 const auto colorUsage   = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
4290                 const auto dsUsage              = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4291
4292                 const VkImageCreateInfo colorAttachmentInfo =
4293                 {
4294                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    //      VkStructureType                 sType;
4295                         nullptr,                                                                //      const void*                             pNext;
4296                         0u,                                                                             //      VkImageCreateFlags              flags;
4297                         VK_IMAGE_TYPE_2D,                                               //      VkImageType                             imageType;
4298                         colorFormat,                                                    //      VkFormat                                format;
4299                         imageExtent,                                                    //      VkExtent3D                              extent;
4300                         1u,                                                                             //      deUint32                                mipLevels;
4301                         1u,                                                                             //      deUint32                                arrayLayers;
4302                         VK_SAMPLE_COUNT_1_BIT,                                  //      VkSampleCountFlagBits   samples;
4303                         VK_IMAGE_TILING_OPTIMAL,                                //      VkImageTiling                   tiling;
4304                         colorUsage,                                                             //      VkImageUsageFlags               usage;
4305                         VK_SHARING_MODE_EXCLUSIVE,                              //      VkSharingMode                   sharingMode;
4306                         0u,                                                                             //      deUint32                                queueFamilyIndexCount;
4307                         nullptr,                                                                //      const deUint32*                 pQueueFamilyIndices;
4308                         VK_IMAGE_LAYOUT_UNDEFINED,                              //      VkImageLayout                   initialLayout;
4309                 };
4310                 colorAttachment = ImagePtr(new ImageWithMemory(vkd, device, alloc, colorAttachmentInfo, MemoryRequirement::Any));
4311
4312                 const VkImageCreateInfo dsAttachmentInfo =
4313                 {
4314                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    //      VkStructureType                 sType;
4315                         nullptr,                                                                //      const void*                             pNext;
4316                         0u,                                                                             //      VkImageCreateFlags              flags;
4317                         VK_IMAGE_TYPE_2D,                                               //      VkImageType                             imageType;
4318                         dsFormat,                                                               //      VkFormat                                format;
4319                         imageExtent,                                                    //      VkExtent3D                              extent;
4320                         1u,                                                                             //      deUint32                                mipLevels;
4321                         1u,                                                                             //      deUint32                                arrayLayers;
4322                         VK_SAMPLE_COUNT_1_BIT,                                  //      VkSampleCountFlagBits   samples;
4323                         VK_IMAGE_TILING_OPTIMAL,                                //      VkImageTiling                   tiling;
4324                         dsUsage,                                                                //      VkImageUsageFlags               usage;
4325                         VK_SHARING_MODE_EXCLUSIVE,                              //      VkSharingMode                   sharingMode;
4326                         0u,                                                                             //      deUint32                                queueFamilyIndexCount;
4327                         nullptr,                                                                //      const deUint32*                 pQueueFamilyIndices;
4328                         VK_IMAGE_LAYOUT_UNDEFINED,                              //      VkImageLayout                   initialLayout;
4329                 };
4330                 dsAttachment = ImagePtr(new ImageWithMemory(vkd, device, alloc, dsAttachmentInfo, MemoryRequirement::Any));
4331
4332                 const auto colorCheckBufferSize         = static_cast<VkDeviceSize>(numPixels * tcu::getPixelSize(mapVkFormat(colorFormat)));
4333                 const auto colorCheckBufferInfo         = makeBufferCreateInfo(colorCheckBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
4334
4335                 colorCheckBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, colorCheckBufferInfo, MemoryRequirement::HostVisible));
4336
4337                 const auto stencilFormat                        = tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
4338                 const auto stencilCheckBufferSize       = static_cast<VkDeviceSize>(numPixels * tcu::getPixelSize(stencilFormat));
4339                 const auto stencilCheckBufferInfo       = makeBufferCreateInfo(stencilCheckBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
4340
4341                 stencilCheckBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, stencilCheckBufferInfo, MemoryRequirement::HostVisible));
4342         }
4343 };
4344
4345 ManyDrawsCase::ManyDrawsCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const ManyDrawsParams& params)
4346         : TestCase      (testCtx, name, description)
4347         , m_params      (params)
4348 {}
4349
4350 void ManyDrawsCase::checkSupport (Context& context) const
4351 {
4352         const auto& vki                 = context.getInstanceInterface();
4353         const auto      physDev         = context.getPhysicalDevice();
4354         const auto&     vkd                     = context.getDeviceInterface();
4355         const auto      device          = context.getDevice();
4356         auto&           alloc           = context.getDefaultAllocator();
4357         const auto      dsFormat        = getSupportedDepthStencilFormat(vki, physDev);
4358
4359         try
4360         {
4361                 ManyDrawsAllocatedData allocatedData(vkd, device, alloc, m_params.imageExtent, getColorFormat(), dsFormat);
4362         }
4363         catch (const vk::Error& err)
4364         {
4365                 const auto result = err.getError();
4366                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY || result == VK_ERROR_OUT_OF_DEVICE_MEMORY)
4367                         TCU_THROW(NotSupportedError, "Not enough memory to run this test");
4368                 throw;
4369         }
4370 }
4371
4372 void ManyDrawsCase::initPrograms (vk::SourceCollections& programCollection) const
4373 {
4374         std::ostringstream vert;
4375         vert
4376                 << "#version 450\n"
4377                 << "\n"
4378                 << "layout(location=0) in vec2 inCoords;\n"
4379                 << "layout(location=1) in uvec4 inColor;\n"
4380                 << "\n"
4381                 << "layout(location=0) out flat uvec4 outColor;\n"
4382                 << "\n"
4383                 << "void main()\n"
4384                 << "{\n"
4385                 << "    gl_Position = vec4(inCoords, 0.0, 1.0);\n"
4386                 << "    outColor = inColor;\n"
4387                 << "}\n"
4388                 ;
4389
4390         std::ostringstream frag;
4391         frag
4392                 << "#version 450\n"
4393                 << "\n"
4394                 << "layout(location=0) in flat uvec4 inColor;\n"
4395                 << "layout(location=0) out uvec4 outColor;\n"
4396                 << "\n"
4397                 << "void main()\n"
4398                 << "{\n"
4399                 << "    outColor = inColor;\n"
4400                 << "}\n"
4401                 ;
4402
4403         programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
4404         programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
4405 }
4406
4407 TestInstance* ManyDrawsCase::createInstance (Context& context) const
4408 {
4409         return new ManyDrawsInstance(context, m_params);
4410 }
4411
4412 ManyDrawsInstance::ManyDrawsInstance (Context& context, const ManyDrawsParams& params)
4413         : TestInstance  (context)
4414         , m_params              (params)
4415 {}
4416
4417 void copyAndFlush (const DeviceInterface& vkd, VkDevice device, BufferWithMemory& buffer, const std::vector<ManyDrawsVertex>& vertices)
4418 {
4419         auto& alloc             = buffer.getAllocation();
4420         void* hostPtr   = alloc.getHostPtr();
4421
4422         deMemcpy(hostPtr, vertices.data(), de::dataSize(vertices));
4423         flushAlloc(vkd, device, alloc);
4424 }
4425
4426 tcu::TestStatus ManyDrawsInstance::iterate (void)
4427 {
4428         const auto&     vki                                     = m_context.getInstanceInterface();
4429         const auto      physDev                         = m_context.getPhysicalDevice();
4430         const auto&     vkd                                     = m_context.getDeviceInterface();
4431         const auto      device                          = m_context.getDevice();
4432         auto&           alloc                           = m_context.getDefaultAllocator();
4433         const auto      qIndex                          = m_context.getUniversalQueueFamilyIndex();
4434         const auto      queue                           = m_context.getUniversalQueue();
4435
4436         const auto      colorFormat                     = ManyDrawsCase::getColorFormat();
4437         const auto      dsFormat                        = getSupportedDepthStencilFormat(vki, physDev);
4438         const auto      vertexBufferSize        = ManyDrawsAllocatedData::calcVertexBufferSize(m_params.imageExtent);
4439         const auto      vertexBufferOffset      = static_cast<VkDeviceSize>(0);
4440         const auto      numPixels                       = ManyDrawsAllocatedData::calcNumPixels(m_params.imageExtent);
4441         const auto      numVertices                     = ManyDrawsAllocatedData::calcNumVertices(m_params.imageExtent);
4442         const auto      alphaValue                      = std::numeric_limits<deUint8>::max();
4443         const auto      pixelWidth                      = 2.0f / static_cast<float>(m_params.imageExtent.width);        // Normalized size.
4444         const auto      pixelWidthHalf          = pixelWidth / 2.0f;                                                                            // Normalized size.
4445         const auto      pixelHeight                     = 2.0f / static_cast<float>(m_params.imageExtent.height);       // Normalized size.
4446         const auto      useSecondary            = (m_params.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4447
4448         // Allocate all needed data up front.
4449         ManyDrawsAllocatedData testData(vkd, device, alloc, m_params.imageExtent, colorFormat, dsFormat);
4450
4451         // Generate random colors.
4452         de::Random                                                      rnd(m_params.seed);
4453         std::vector<ManyDrawsVertex::Color>     colors;
4454
4455         colors.reserve(numPixels);
4456         for (deUint32 i = 0; i < numPixels; ++i)
4457         {
4458 #if 0
4459                 const deUint8 red       = ((i      ) & 0xFFu);
4460                 const deUint8 green     = ((i >>  8) & 0xFFu);
4461                 const deUint8 blue      = ((i >> 16) & 0xFFu);
4462                 colors.push_back(ManyDrawsVertex::Color(red, green, blue, alphaValue));
4463 #else
4464                 colors.push_back(ManyDrawsVertex::Color(rnd.getUint8(), rnd.getUint8(), rnd.getUint8(), alphaValue));
4465 #endif
4466         }
4467
4468         // Fill vertex data. One triangle per pixel, front and back.
4469         std::vector<ManyDrawsVertex> frontVector;
4470         std::vector<ManyDrawsVertex> backVector;
4471         frontVector.reserve(numVertices);
4472         backVector.reserve(numVertices);
4473
4474         for (deUint32 y = 0; y < m_params.imageExtent.height; ++y)
4475         for (deUint32 x = 0; x < m_params.imageExtent.width; ++x)
4476         {
4477                 float x_left    = static_cast<float>(x) * pixelWidth - 1.0f;
4478                 float x_mid             = x_left + pixelWidthHalf;
4479                 float x_right   = x_left + pixelWidth;
4480                 float y_top             = static_cast<float>(y) * pixelHeight - 1.0f;
4481                 float y_bottom  = y_top + pixelHeight;
4482
4483                 // Triangles in the "back" mesh will have different colors.
4484                 const auto              colorIdx                = y * m_params.imageExtent.width + x;
4485                 const auto&             frontColor              = colors[colorIdx];
4486                 const auto&             backColor               = colors[colors.size() - 1u - colorIdx];
4487
4488                 const tcu::Vec2 triangle[3u]    =
4489                 {
4490                         tcu::Vec2(x_left, y_top),
4491                         tcu::Vec2(x_right, y_top),
4492                         tcu::Vec2(x_mid, y_bottom),
4493                 };
4494
4495                 frontVector.emplace_back(triangle[0], frontColor);
4496                 frontVector.emplace_back(triangle[1], frontColor);
4497                 frontVector.emplace_back(triangle[2], frontColor);
4498
4499                 backVector.emplace_back(triangle[0], backColor);
4500                 backVector.emplace_back(triangle[1], backColor);
4501                 backVector.emplace_back(triangle[2], backColor);
4502         }
4503
4504         // Copy vertex data to staging buffers.
4505         copyAndFlush(vkd, device, *testData.frontBuffers.stagingBuffer, frontVector);
4506         copyAndFlush(vkd, device, *testData.backBuffers.stagingBuffer, backVector);
4507
4508         // Color attachment view.
4509         const auto              colorResourceRange      = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4510         const auto              colorAttachmentView     = makeImageView(vkd, device, testData.colorAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorResourceRange);
4511
4512         // Depth/stencil attachment view.
4513         const auto              dsResourceRange         = makeImageSubresourceRange((VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT), 0u, 1u, 0u, 1u);
4514         const auto              dsAttachmentView        = makeImageView(vkd, device, testData.dsAttachment->get(), VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsResourceRange);
4515
4516         const VkImageView       attachmentArray[]       = { colorAttachmentView.get(), dsAttachmentView.get() };
4517         const auto                      numAttachments          = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(attachmentArray));
4518
4519         const auto renderPass   = makeRenderPass(vkd, device, colorFormat, dsFormat);
4520         const auto framebuffer  = makeFramebuffer(vkd, device, renderPass.get(), numAttachments, attachmentArray, m_params.imageExtent.width, m_params.imageExtent.height);
4521
4522         const auto vertModule   = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
4523         const auto fragModule   = createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
4524
4525         const std::vector<VkViewport>   viewports       (1u, makeViewport(m_params.imageExtent));
4526         const std::vector<VkRect2D>             scissors        (1u, makeRect2D(m_params.imageExtent));
4527
4528         const auto descriptorSetLayout  = DescriptorSetLayoutBuilder().build(vkd, device);
4529         const auto pipelineLayout               = makePipelineLayout(vkd, device, descriptorSetLayout.get());
4530
4531         const VkVertexInputBindingDescription bindings[] =
4532         {
4533                 makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(ManyDrawsVertex)), VK_VERTEX_INPUT_RATE_VERTEX),
4534         };
4535
4536         const VkVertexInputAttributeDescription attributes[] =
4537         {
4538                 makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32_SFLOAT, static_cast<deUint32>(offsetof(ManyDrawsVertex, coords))),
4539                 makeVertexInputAttributeDescription(1u, 0u, VK_FORMAT_R8G8B8A8_UINT, static_cast<deUint32>(offsetof(ManyDrawsVertex, color))),
4540         };
4541
4542         const VkPipelineVertexInputStateCreateInfo inputState =
4543         {
4544                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      //      VkStructureType                                                         sType;
4545                 nullptr,                                                                                                        //      const void*                                                                     pNext;
4546                 0u,                                                                                                                     //      VkPipelineVertexInputStateCreateFlags           flags;
4547                 static_cast<deUint32>(DE_LENGTH_OF_ARRAY(bindings)),            //      deUint32                                                                        vertexBindingDescriptionCount;
4548                 bindings,                                                                                                       //      const VkVertexInputBindingDescription*          pVertexBindingDescriptions;
4549                 static_cast<deUint32>(DE_LENGTH_OF_ARRAY(attributes)),          //      deUint32                                                                        vertexAttributeDescriptionCount;
4550                 attributes,                                                                                                     //      const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions;
4551         };
4552
4553         // Stencil state: this is key for checking and obtaining the right results. The stencil buffer will be cleared to 0. The first
4554         // set of draws ("front" set of triangles) will pass the test and increment the stencil value to 1. The second set of draws
4555         // ("back" set of triangles, not really in the back because all of them have depth 0.0) will not pass the stencil test then, but
4556         // still increment the stencil value to 2.
4557         //
4558         // At the end of the test, if every draw command was executed correctly in the expected order, the color buffer will have the
4559         // colors of the front set, and the stencil buffer will be full of 2s.
4560         const auto stencilOpState = makeStencilOpState(VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_KEEP,
4561                 VK_COMPARE_OP_EQUAL, 0xFFu, 0xFFu, 0u);
4562
4563         const VkPipelineDepthStencilStateCreateInfo dsState =
4564         {
4565                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                          sType
4566                 nullptr,                                                                                                        // const void*                              pNext
4567                 0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags   flags
4568                 VK_FALSE,                                                                                                       // VkBool32                                 depthTestEnable
4569                 VK_FALSE,                                                                                                       // VkBool32                                 depthWriteEnable
4570                 VK_COMPARE_OP_NEVER,                                                                            // VkCompareOp                              depthCompareOp
4571                 VK_FALSE,                                                                                                       // VkBool32                                 depthBoundsTestEnable
4572                 VK_TRUE,                                                                                                        // VkBool32                                 stencilTestEnable
4573                 stencilOpState,                                                                                         // VkStencilOpState                         front
4574                 stencilOpState,                                                                                         // VkStencilOpState                         back
4575                 0.0f,                                                                                                           // float                                    minDepthBounds
4576                 1.0f,                                                                                                           // float                                    maxDepthBounds
4577         };
4578
4579         const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
4580                         vertModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(),
4581                         renderPass.get(), viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, 0u,
4582                         &inputState, nullptr, nullptr, &dsState);
4583
4584         // Command pool and buffers.
4585         using CmdBufferPtr = Move<VkCommandBuffer>;
4586         const auto cmdPool = makeCommandPool(vkd, device, qIndex);
4587
4588         CmdBufferPtr    primaryCmdBufferPtr;
4589         CmdBufferPtr    secondaryCmdBufferPtr;
4590         VkCommandBuffer primaryCmdBuffer;
4591         VkCommandBuffer secondaryCmdBuffer;
4592         VkCommandBuffer drawsCmdBuffer;
4593
4594         primaryCmdBufferPtr             = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4595         primaryCmdBuffer                = primaryCmdBufferPtr.get();
4596         drawsCmdBuffer                  = primaryCmdBuffer;
4597         beginCommandBuffer(vkd, primaryCmdBuffer);
4598
4599         // Clear values.
4600         std::vector<VkClearValue> clearValues(2u);
4601         clearValues[0] = makeClearValueColorU32(0u, 0u, 0u, 0u);
4602         clearValues[1] = makeClearValueDepthStencil(1.0f, 0u);
4603
4604         // Copy staging buffers to vertex buffers.
4605         const auto copyRegion = makeBufferCopy(0ull, 0ull, vertexBufferSize);
4606         vkd.cmdCopyBuffer(primaryCmdBuffer, testData.frontBuffers.stagingBuffer->get(), testData.frontBuffers.vertexBuffer->get(), 1u, &copyRegion);
4607         vkd.cmdCopyBuffer(primaryCmdBuffer, testData.backBuffers.stagingBuffer->get(), testData.backBuffers.vertexBuffer->get(), 1u, &copyRegion);
4608
4609         // Use barrier for vertex reads.
4610         const auto vertexBarier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
4611         vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0u, 1u, &vertexBarier, 0u, nullptr, 0u, nullptr);
4612
4613         // Change depth/stencil attachment layout.
4614         const auto dsBarrier = makeImageMemoryBarrier(0, (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, testData.dsAttachment->get(), dsResourceRange);
4615         vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT), 0u, 0u, nullptr, 0u, nullptr, 1u, &dsBarrier);
4616
4617         beginRenderPass(vkd, primaryCmdBuffer, renderPass.get(), framebuffer.get(),
4618                 scissors[0], static_cast<deUint32>(clearValues.size()), clearValues.data(),
4619                 (useSecondary ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE));
4620
4621         if (useSecondary)
4622         {
4623                 secondaryCmdBufferPtr   = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4624                 secondaryCmdBuffer              = secondaryCmdBufferPtr.get();
4625                 drawsCmdBuffer                  = secondaryCmdBuffer;
4626
4627                 const VkCommandBufferInheritanceInfo inheritanceInfo =
4628                 {
4629                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,      //      VkStructureType                                 sType;
4630                         nullptr,                                                                                        //      const void*                                             pNext;
4631                         renderPass.get(),                                                                       //      VkRenderPass                                    renderPass;
4632                         0u,                                                                                                     //      deUint32                                                subpass;
4633                         framebuffer.get(),                                                                      //      VkFramebuffer                                   framebuffer;
4634                         0u,                                                                                                     //      VkBool32                                                occlusionQueryEnable;
4635                         0u,                                                                                                     //      VkQueryControlFlags                             queryFlags;
4636                         0u,                                                                                                     //      VkQueryPipelineStatisticFlags   pipelineStatistics;
4637                 };
4638
4639                 const VkCommandBufferUsageFlags usageFlags      = (VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
4640                 const VkCommandBufferBeginInfo  beginInfo       =
4641                 {
4642                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4643                         nullptr,
4644                         usageFlags,                                                                             //      VkCommandBufferUsageFlags                               flags;
4645                         &inheritanceInfo,                                                               //      const VkCommandBufferInheritanceInfo*   pInheritanceInfo;
4646                 };
4647
4648                 VK_CHECK(vkd.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
4649         }
4650
4651         // Bind pipeline.
4652         vkd.cmdBindPipeline(drawsCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
4653
4654         // Draw triangles in front.
4655         vkd.cmdBindVertexBuffers(drawsCmdBuffer, 0u, 1u, &testData.frontBuffers.vertexBuffer->get(), &vertexBufferOffset);
4656         for (deUint32 i = 0; i < numPixels; ++i)
4657                 vkd.cmdDraw(drawsCmdBuffer, 3u, 1u, i*3u, 0u);
4658
4659         // Draw triangles in the "back". This should have no effect due to the stencil test.
4660         vkd.cmdBindVertexBuffers(drawsCmdBuffer, 0u, 1u, &testData.backBuffers.vertexBuffer->get(), &vertexBufferOffset);
4661         for (deUint32 i = 0; i < numPixels; ++i)
4662                 vkd.cmdDraw(drawsCmdBuffer, 3u, 1u, i*3u, 0u);
4663
4664         if (useSecondary)
4665         {
4666                 endCommandBuffer(vkd, secondaryCmdBuffer);
4667                 vkd.cmdExecuteCommands(primaryCmdBuffer, 1u, &secondaryCmdBuffer);
4668         }
4669
4670         endRenderPass(vkd, primaryCmdBuffer);
4671
4672         // Copy color and depth/stencil attachments to verification buffers.
4673         const auto colorAttachmentBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, testData.colorAttachment->get(), colorResourceRange);
4674         vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &colorAttachmentBarrier);
4675
4676         const auto colorResourceLayers  = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
4677         const auto colorCopyRegion              = makeBufferImageCopy(m_params.imageExtent, colorResourceLayers);
4678         vkd.cmdCopyImageToBuffer(primaryCmdBuffer, testData.colorAttachment->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, testData.colorCheckBuffer->get(), 1u, &colorCopyRegion);
4679
4680         const auto stencilAttachmentBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, testData.dsAttachment->get(), dsResourceRange);
4681         vkd.cmdPipelineBarrier(primaryCmdBuffer, (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT), VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &stencilAttachmentBarrier);
4682
4683         const auto stencilResourceLayers        = makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u);
4684         const auto stencilCopyRegion            = makeBufferImageCopy(m_params.imageExtent, stencilResourceLayers);
4685         vkd.cmdCopyImageToBuffer(primaryCmdBuffer, testData.dsAttachment->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, testData.stencilCheckBuffer->get(), 1u, &stencilCopyRegion);
4686
4687         const auto verificationBuffersBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
4688         vkd.cmdPipelineBarrier(primaryCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &verificationBuffersBarrier, 0u, nullptr, 0u, nullptr);
4689
4690         endCommandBuffer(vkd, primaryCmdBuffer);
4691         submitCommandsAndWait(vkd, device, queue, primaryCmdBuffer);
4692
4693         // Check buffer contents.
4694         auto& colorCheckBufferAlloc     = testData.colorCheckBuffer->getAllocation();
4695         void* colorCheckBufferData      = colorCheckBufferAlloc.getHostPtr();
4696         invalidateAlloc(vkd, device, colorCheckBufferAlloc);
4697
4698         auto& stencilCheckBufferAlloc   = testData.stencilCheckBuffer->getAllocation();
4699         void* stencilCheckBufferData    = stencilCheckBufferAlloc.getHostPtr();
4700         invalidateAlloc(vkd, device, stencilCheckBufferAlloc);
4701
4702         const auto iWidth                       = static_cast<int>(m_params.imageExtent.width);
4703         const auto iHeight                      = static_cast<int>(m_params.imageExtent.height);
4704         const auto colorTcuFormat       = mapVkFormat(colorFormat);
4705         const auto stencilTcuFormat     = tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
4706
4707         tcu::TextureLevel                       referenceLevel          (colorTcuFormat, iWidth, iHeight);
4708         tcu::PixelBufferAccess          referenceAccess         = referenceLevel.getAccess();
4709         tcu::TextureLevel                       colorErrorLevel         (mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), iWidth, iHeight);
4710         tcu::PixelBufferAccess          colorErrorAccess        = colorErrorLevel.getAccess();
4711         tcu::TextureLevel                       stencilErrorLevel       (mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), iWidth, iHeight);
4712         tcu::PixelBufferAccess          stencilErrorAccess      = stencilErrorLevel.getAccess();
4713         tcu::ConstPixelBufferAccess     colorAccess                     (colorTcuFormat, iWidth, iHeight, 1, colorCheckBufferData);
4714         tcu::ConstPixelBufferAccess     stencilAccess           (stencilTcuFormat, iWidth, iHeight, 1, stencilCheckBufferData);
4715         const tcu::Vec4                         green                           (0.0f, 1.0f, 0.0f, 1.0f);
4716         const tcu::Vec4                         red                                     (1.0f, 0.0f, 0.0f, 1.0f);
4717         const int                                       expectedStencil         = 2;
4718         bool                                            colorFail                       = false;
4719         bool                                            stencilFail                     = false;
4720
4721         for (int y = 0; y < iHeight; ++y)
4722         for (int x = 0; x < iWidth; ++x)
4723         {
4724                 const tcu::UVec4        colorValue              = colorAccess.getPixelUint(x, y);
4725                 const auto                      expectedPixel   = colors[y * iWidth + x];
4726                 const tcu::UVec4        expectedValue   (expectedPixel.x(), expectedPixel.y(), expectedPixel.z(), expectedPixel.w());
4727                 const bool                      colorMismatch   = (colorValue != expectedValue);
4728
4729                 const auto                      stencilValue    = stencilAccess.getPixStencil(x, y);
4730                 const bool                      stencilMismatch = (stencilValue != expectedStencil);
4731
4732                 referenceAccess.setPixel(expectedValue, x, y);
4733                 colorErrorAccess.setPixel((colorMismatch ? red : green), x, y);
4734                 stencilErrorAccess.setPixel((stencilMismatch ? red : green), x, y);
4735
4736                 if (stencilMismatch)
4737                         stencilFail = true;
4738
4739                 if (colorMismatch)
4740                         colorFail = true;
4741         }
4742
4743         if (colorFail || stencilFail)
4744         {
4745                 auto& log = m_context.getTestContext().getLog();
4746                 log
4747                         << tcu::TestLog::ImageSet("Result", "")
4748                         << tcu::TestLog::Image("ColorOutput", "", colorAccess)
4749                         << tcu::TestLog::Image("ColorReference", "", referenceAccess)
4750                         << tcu::TestLog::Image("ColorError", "", colorErrorAccess)
4751                         << tcu::TestLog::Image("StencilError", "", stencilErrorAccess)
4752                         << tcu::TestLog::EndImageSet
4753                         ;
4754                 TCU_FAIL("Mismatched output and reference color or stencil; please check test log --");
4755         }
4756
4757         return tcu::TestStatus::pass("Pass");
4758 }
4759
4760 } // anonymous
4761
4762 tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx)
4763 {
4764         de::MovePtr<tcu::TestCaseGroup> commandBuffersTests     (new tcu::TestCaseGroup(testCtx, "command_buffers", "Command Buffers Tests"));
4765
4766         /* 19.1. Command Pools (5.1 in VK 1.0 Spec) */
4767         addFunctionCase                         (commandBuffersTests.get(), "pool_create_null_params",                  "",     createPoolNullParamsTest);
4768         addFunctionCase                         (commandBuffersTests.get(), "pool_create_non_null_allocator",   "",     createPoolNonNullAllocatorTest);
4769         addFunctionCase                         (commandBuffersTests.get(), "pool_create_transient_bit",                "",     createPoolTransientBitTest);
4770         addFunctionCase                         (commandBuffersTests.get(), "pool_create_reset_bit",                    "",     createPoolResetBitTest);
4771         addFunctionCase                         (commandBuffersTests.get(), "pool_reset_release_res",                   "",     resetPoolReleaseResourcesBitTest);
4772         addFunctionCase                         (commandBuffersTests.get(), "pool_reset_no_flags_res",                  "",     resetPoolNoFlagsTest);
4773         addFunctionCase                         (commandBuffersTests.get(), "pool_reset_reuse",                                 "",     checkEventSupport, resetPoolReuseTest);
4774         /* 19.2. Command Buffer Lifetime (5.2 in VK 1.0 Spec) */
4775         addFunctionCase                         (commandBuffersTests.get(), "allocate_single_primary",                  "", allocatePrimaryBufferTest);
4776         addFunctionCase                         (commandBuffersTests.get(), "allocate_many_primary",                    "",     allocateManyPrimaryBuffersTest);
4777         addFunctionCase                         (commandBuffersTests.get(), "allocate_single_secondary",                "", allocateSecondaryBufferTest);
4778         addFunctionCase                         (commandBuffersTests.get(), "allocate_many_secondary",                  "", allocateManySecondaryBuffersTest);
4779         addFunctionCase                         (commandBuffersTests.get(), "execute_small_primary",                    "",     checkEventSupport, executePrimaryBufferTest);
4780         addFunctionCase                         (commandBuffersTests.get(), "execute_large_primary",                    "",     checkEventSupport, executeLargePrimaryBufferTest);
4781         addFunctionCase                         (commandBuffersTests.get(), "reset_implicit",                                   "", checkEventSupport, resetBufferImplicitlyTest);
4782 #ifndef CTS_USES_VULKANSC
4783         addFunctionCase                         (commandBuffersTests.get(), "trim_command_pool",                                "", checkEventSupport, trimCommandPoolTest, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4784         addFunctionCase                         (commandBuffersTests.get(), "trim_command_pool_secondary",              "", checkEventSupport, trimCommandPoolTest, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4785 #endif
4786         /* 19.3. Command Buffer Recording (5.3 in VK 1.0 Spec) */
4787         addFunctionCase                         (commandBuffersTests.get(), "record_single_primary",                    "",     checkEventSupport, recordSinglePrimaryBufferTest);
4788         addFunctionCase                         (commandBuffersTests.get(), "record_many_primary",                              "", checkEventSupport, recordLargePrimaryBufferTest);
4789         addFunctionCase                         (commandBuffersTests.get(), "record_single_secondary",                  "",     checkEventSupport, recordSingleSecondaryBufferTest);
4790         addFunctionCase                         (commandBuffersTests.get(), "record_many_secondary",                    "", checkEventSupport, recordLargeSecondaryBufferTest);
4791         {
4792                 deUint32        seed            = 1614182419u;
4793                 const auto      smallExtent     = makeExtent3D(128u, 128u, 1u);
4794                 const auto      largeExtent     = makeExtent3D(512u, 512u, 1u);
4795
4796                 commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_primary_1",         "", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_PRIMARY,    smallExtent,    seed++)));
4797                 commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_primary_2",         "", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_PRIMARY,    largeExtent,    seed++)));
4798                 commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_secondary_1",       "", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_SECONDARY,  smallExtent,    seed++)));
4799                 commandBuffersTests->addChild(new ManyDrawsCase(testCtx, "record_many_draws_secondary_2",       "", ManyDrawsParams(VK_COMMAND_BUFFER_LEVEL_SECONDARY,  largeExtent,    seed++)));
4800         }
4801         addFunctionCase                         (commandBuffersTests.get(), "submit_twice_primary",                             "",     checkEventSupport, submitPrimaryBufferTwiceTest);
4802         addFunctionCase                         (commandBuffersTests.get(), "submit_twice_secondary",                   "",     checkEventSupport, submitSecondaryBufferTwiceTest);
4803         addFunctionCase                         (commandBuffersTests.get(), "record_one_time_submit_primary",   "",     checkEventSupport, oneTimeSubmitFlagPrimaryBufferTest);
4804         addFunctionCase                         (commandBuffersTests.get(), "record_one_time_submit_secondary", "",     checkEventSupport, oneTimeSubmitFlagSecondaryBufferTest);
4805         addFunctionCase                         (commandBuffersTests.get(), "render_pass_continue",                             "",     renderPassContinueTest, true);
4806         addFunctionCase                         (commandBuffersTests.get(), "render_pass_continue_no_fb",               "",     renderPassContinueTest, false);
4807         addFunctionCase                         (commandBuffersTests.get(), "record_simul_use_primary",                 "",     checkEventSupport, simultaneousUsePrimaryBufferTest);
4808         addFunctionCase                         (commandBuffersTests.get(), "record_simul_use_secondary",               "",     checkEventSupport, simultaneousUseSecondaryBufferTest);
4809         addFunctionCaseWithPrograms (commandBuffersTests.get(), "record_simul_use_secondary_one_primary", "", genComputeIncrementSource, simultaneousUseSecondaryBufferOnePrimaryBufferTest);
4810         addFunctionCaseWithPrograms (commandBuffersTests.get(), "record_simul_use_secondary_two_primary", "", genComputeIncrementSource, simultaneousUseSecondaryBufferTwoPrimaryBuffersTest);
4811         addFunctionCase                         (commandBuffersTests.get(), "record_query_precise_w_flag",              "",     recordBufferQueryPreciseWithFlagTest);
4812         addFunctionCase                         (commandBuffersTests.get(), "record_query_imprecise_w_flag",    "",     recordBufferQueryImpreciseWithFlagTest);
4813         addFunctionCase                         (commandBuffersTests.get(), "record_query_imprecise_wo_flag",   "",     recordBufferQueryImpreciseWithoutFlagTest);
4814         addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_random",          "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::RANDOM_PTR);
4815         addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_random_cont",     "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION);
4816         addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_random_data",     "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::RANDOM_DATA_PTR);
4817         addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_invalid_type", "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::INVALID_STRUCTURE_TYPE);
4818         addFunctionCaseWithPrograms (commandBuffersTests.get(), "bad_inheritance_info_valid_nonsense_type", "", genComputeIncrementSourceBadInheritance, badInheritanceInfoTest, BadInheritanceInfoCase::VALID_NONSENSE_TYPE);
4819         /* 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) */
4820         addFunctionCase                         (commandBuffersTests.get(), "submit_count_non_zero",                    "", checkEventSupport, submitBufferCountNonZero);
4821         addFunctionCase                         (commandBuffersTests.get(), "submit_count_equal_zero",                  "", checkEventSupport, submitBufferCountEqualZero);
4822         addFunctionCase                         (commandBuffersTests.get(), "submit_wait_single_semaphore",             "", checkEventSupport, submitBufferWaitSingleSemaphore);
4823         addFunctionCase                         (commandBuffersTests.get(), "submit_wait_many_semaphores",              "", checkEventSupport, submitBufferWaitManySemaphores);
4824         addFunctionCase                         (commandBuffersTests.get(), "submit_null_fence",                                "", checkEventSupport, submitBufferNullFence);
4825         addFunctionCase                         (commandBuffersTests.get(), "submit_two_buffers_one_buffer_null_with_fence", "", checkEventSupport, submitTwoBuffersOneBufferNullWithFence);
4826         /* 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) */
4827         addFunctionCase                         (commandBuffersTests.get(), "secondary_execute",                                "",     checkEventSupport, executeSecondaryBufferTest);
4828         addFunctionCase                         (commandBuffersTests.get(), "secondary_execute_twice",                  "",     checkEventSupport, executeSecondaryBufferTwiceTest);
4829         /* 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) */
4830         addFunctionCaseWithPrograms (commandBuffersTests.get(), "order_bind_pipeline",                          "", genComputeSource, orderBindPipelineTest);
4831         /* Verify untested transitions between command buffer states */
4832         addFunctionCase                         (commandBuffersTests.get(), "recording_to_ininitial",                   "", executeStateTransitionTest, STT_RECORDING_TO_INITIAL);
4833         addFunctionCase                         (commandBuffersTests.get(), "executable_to_ininitial",                  "", executeStateTransitionTest, STT_EXECUTABLE_TO_INITIAL);
4834         addFunctionCase                         (commandBuffersTests.get(), "recording_to_invalid",                             "", executeStateTransitionTest, STT_RECORDING_TO_INVALID);
4835         addFunctionCase                         (commandBuffersTests.get(), "executable_to_invalid",                    "", executeStateTransitionTest, STT_EXECUTABLE_TO_INVALID);
4836
4837         return commandBuffersTests.release();
4838 }
4839
4840 } // api
4841 } // vkt
4842