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