1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2015 Google Inc.
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 *//*--------------------------------------------------------------------*/
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"
60 typedef de::SharedPtr<vk::Unique<vk::VkEvent> > VkEventSp;
63 const deUint64 INFINITE_TIMEOUT = ~(deUint64)0u;
66 template <deUint32 NumBuffers>
67 class CommandBufferBareTestEnvironment
70 CommandBufferBareTestEnvironment (Context& context,
71 VkCommandPoolCreateFlags commandPoolCreateFlags);
73 VkCommandPool getCommandPool (void) const { return *m_commandPool; }
74 VkCommandBuffer getCommandBuffer (deUint32 bufferIndex) const;
78 const VkDevice m_device;
79 const DeviceInterface& m_vkd;
80 const VkQueue m_queue;
81 const deUint32 m_queueFamilyIndex;
82 Allocator& m_allocator;
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];
91 template <deUint32 NumBuffers>
92 CommandBufferBareTestEnvironment<NumBuffers>::CommandBufferBareTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags)
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())
100 m_commandPool = createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex);
102 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
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;
111 VK_CHECK(m_vkd.allocateCommandBuffers(m_device, &cmdBufferAllocateInfo, m_primaryCommandBuffers));
114 template <deUint32 NumBuffers>
115 VkCommandBuffer CommandBufferBareTestEnvironment<NumBuffers>::getCommandBuffer(deUint32 bufferIndex) const
117 DE_ASSERT(bufferIndex < NumBuffers);
118 return m_primaryCommandBuffers[bufferIndex];
121 class CommandBufferRenderPassTestEnvironment : public CommandBufferBareTestEnvironment<1>
124 CommandBufferRenderPassTestEnvironment (Context& context,
125 VkCommandPoolCreateFlags commandPoolCreateFlags);
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; }
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);
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;
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;
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 =
160 { 0u, 0u, }, // VkOffset2D offset;
161 { DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height }, // VkExtent2D extent;
164 CommandBufferRenderPassTestEnvironment::CommandBufferRenderPassTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags)
165 : CommandBufferBareTestEnvironment<1> (context, commandPoolCreateFlags)
167 m_renderPass = makeRenderPass(m_vkd, m_device, DEFAULT_IMAGE_FORMAT);
170 const VkImageCreateInfo imageCreateInfo =
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;
191 m_colorImage = createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
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()));
198 const VkImageViewCreateInfo imageViewCreateInfo =
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;
207 VK_COMPONENT_SWIZZLE_R,
208 VK_COMPONENT_SWIZZLE_G,
209 VK_COMPONENT_SWIZZLE_B,
210 VK_COMPONENT_SWIZZLE_A
211 }, // VkComponentMapping components;
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;
221 m_colorImageView = createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL);
225 const VkImageView attachmentViews[1] =
230 const VkFramebufferCreateInfo framebufferCreateInfo =
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;
243 m_frameBuffer = createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL);
246 m_secCommandPool = createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex);
249 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
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;
258 m_secondaryCommandBuffer = allocateCommandBuffer(m_vkd, m_device, &cmdBufferAllocateInfo);
263 void CommandBufferRenderPassTestEnvironment::beginRenderPass(VkSubpassContents content)
265 vk::beginRenderPass(m_vkd, m_primaryCommandBuffers[0], *m_renderPass, *m_frameBuffer, DEFAULT_IMAGE_AREA, tcu::UVec4(17, 59, 163, 251), content);
268 void CommandBufferRenderPassTestEnvironment::beginPrimaryCommandBuffer(VkCommandBufferUsageFlags usageFlags)
270 beginCommandBuffer(m_vkd, m_primaryCommandBuffers[0], usageFlags);
273 void CommandBufferRenderPassTestEnvironment::beginSecondaryCommandBuffer(VkCommandBufferUsageFlags usageFlags, bool framebufferHint)
275 const VkCommandBufferInheritanceInfo commandBufferInheritanceInfo =
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;
287 const VkCommandBufferBeginInfo commandBufferBeginInfo =
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;
295 VK_CHECK(m_vkd.beginCommandBuffer(*m_secondaryCommandBuffer, &commandBufferBeginInfo));
299 void CommandBufferRenderPassTestEnvironment::submitPrimaryCommandBuffer(void)
301 submitCommandsAndWait(m_vkd, m_device, m_queue, *m_primaryCommandBuffers);
304 de::MovePtr<tcu::TextureLevel> CommandBufferRenderPassTestEnvironment::readColorAttachment ()
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));
312 // Create destination buffer
314 const VkBufferCreateInfo bufferParams =
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;
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()));
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]);
336 submitPrimaryCommandBuffer();
339 invalidateAlloc(m_vkd, m_device, *bufferAlloc);
340 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
347 /********* 19.1. Command Pools (5.1 in VK 1.0 Spec) ***************************/
348 tcu::TestStatus createPoolNullParamsTest(Context& context)
350 const VkDevice vkDevice = context.getDevice();
351 const DeviceInterface& vk = context.getDeviceInterface();
352 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
354 createCommandPool(vk, vkDevice, 0u, queueFamilyIndex);
356 return tcu::TestStatus::pass("Command Pool allocated correctly.");
359 #ifndef CTS_USES_VULKANSC
360 tcu::TestStatus createPoolNonNullAllocatorTest(Context& context)
362 const VkDevice vkDevice = context.getDevice();
363 const DeviceInterface& vk = context.getDeviceInterface();
364 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
365 const VkAllocationCallbacks* allocationCallbacks = getSystemAllocator();
367 const VkCommandPoolCreateInfo cmdPoolParams =
369 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
372 queueFamilyIndex, // queueFamilyIndex;
375 createCommandPool(vk, vkDevice, &cmdPoolParams, allocationCallbacks);
377 return tcu::TestStatus::pass("Command Pool allocated correctly.");
379 #endif // CTS_USES_VULKANSC
381 tcu::TestStatus createPoolTransientBitTest(Context& context)
383 const VkDevice vkDevice = context.getDevice();
384 const DeviceInterface& vk = context.getDeviceInterface();
385 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
387 const VkCommandPoolCreateInfo cmdPoolParams =
389 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
391 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags;
392 queueFamilyIndex, // queueFamilyIndex;
395 createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
397 return tcu::TestStatus::pass("Command Pool allocated correctly.");
400 tcu::TestStatus createPoolResetBitTest(Context& context)
402 const VkDevice vkDevice = context.getDevice();
403 const DeviceInterface& vk = context.getDeviceInterface();
404 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
406 const VkCommandPoolCreateInfo cmdPoolParams =
408 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
410 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
411 queueFamilyIndex, // queueFamilyIndex;
414 createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL);
416 return tcu::TestStatus::pass("Command Pool allocated correctly.");
419 #ifndef CTS_USES_VULKANSC
420 tcu::TestStatus resetPoolReleaseResourcesBitTest(Context& context)
422 const VkDevice vkDevice = context.getDevice();
423 const DeviceInterface& vk = context.getDeviceInterface();
424 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
426 const VkCommandPoolCreateInfo cmdPoolParams =
428 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
431 queueFamilyIndex, // queueFamilyIndex;
434 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
436 VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT));
438 return tcu::TestStatus::pass("Command Pool allocated correctly.");
440 #endif // CTS_USES_VULKANSC
442 tcu::TestStatus resetPoolNoFlagsTest(Context& context)
444 const VkDevice vkDevice = context.getDevice();
445 const DeviceInterface& vk = context.getDeviceInterface();
446 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
448 const VkCommandPoolCreateInfo cmdPoolParams =
450 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
453 queueFamilyIndex, // queueFamilyIndex;
456 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
458 VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, 0u));
460 return tcu::TestStatus::pass("Command Pool allocated correctly.");
463 #ifndef CTS_USES_VULKANSC
464 bool executeCommandBuffer (const VkDevice device,
465 const DeviceInterface& vk,
467 const VkCommandBuffer commandBuffer,
468 const bool exitBeforeEndCommandBuffer = false)
470 const Unique<VkEvent> event (createEvent(vk, device));
471 beginCommandBuffer(vk, commandBuffer, 0u);
473 const VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
474 vk.cmdSetEvent(commandBuffer, *event, stageMask);
475 if (exitBeforeEndCommandBuffer)
476 return exitBeforeEndCommandBuffer;
478 endCommandBuffer(vk, commandBuffer);
480 submitCommandsAndWait(vk, device, queue, commandBuffer);
482 // check if buffer has been executed
483 const VkResult result = vk.getEventStatus(device, *event);
484 return result == VK_EVENT_SET;
487 tcu::TestStatus resetPoolReuseTest (Context& context)
489 const VkDevice vkDevice = context.getDevice();
490 const DeviceInterface& vk = context.getDeviceInterface();
491 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
492 const VkQueue queue = context.getUniversalQueue();
494 const VkCommandPoolCreateInfo cmdPoolParams =
496 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
499 queueFamilyIndex // queueFamilyIndex;
501 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL));
502 const VkCommandBufferAllocateInfo cmdBufParams =
504 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
506 *cmdPool, // commandPool;
507 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
510 const Move<VkCommandBuffer> commandBuffers[] =
512 allocateCommandBuffer(vk, vkDevice, &cmdBufParams),
513 allocateCommandBuffer(vk, vkDevice, &cmdBufParams)
516 #ifdef CTS_USES_VULKANSC
517 bool canFinishEarlier = context.getTestContext().getCommandLine().isSubProcess();
519 bool canFinishEarlier = true;
520 #endif // CTS_USES_VULKANSC
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");
527 VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT));
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");
535 const Unique<VkCommandBuffer> afterResetCommandBuffers(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
536 if (!executeCommandBuffer(vkDevice, vk, queue, *afterResetCommandBuffers) && canFinishEarlier)
537 return tcu::TestStatus::fail("Failed");
540 return tcu::TestStatus::pass("Passed");
542 #endif // CTS_USES_VULKANSC
544 /******** 19.2. Command Buffer Lifetime (5.2 in VK 1.0 Spec) ******************/
545 tcu::TestStatus allocatePrimaryBufferTest(Context& context)
547 const VkDevice vkDevice = context.getDevice();
548 const DeviceInterface& vk = context.getDeviceInterface();
549 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
551 const VkCommandPoolCreateInfo cmdPoolParams =
553 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
555 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
556 queueFamilyIndex, // queueFamilyIndex;
558 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
561 const VkCommandBufferAllocateInfo cmdBufParams =
563 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
565 *cmdPool, // commandPool;
566 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
569 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
571 return tcu::TestStatus::pass("Buffer was created correctly.");
574 tcu::TestStatus allocateManyPrimaryBuffersTest(Context& context)
577 const VkDevice vkDevice = context.getDevice();
578 const DeviceInterface& vk = context.getDeviceInterface();
579 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
581 const VkCommandPoolCreateInfo cmdPoolParams =
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;
588 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
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;
595 const unsigned minCommandBuffer = 10000;
598 const unsigned minCommandBuffer = 100;
599 #endif // CTS_USES_VULKANSC
602 const VkCommandBufferAllocateInfo cmdBufParams =
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;
611 // do not keep the handles to buffers, as they will be freed with command pool
613 // allocate the minimum required amount of buffers
614 VkCommandBuffer cmdBuffers[minCommandBuffer];
615 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
617 std::ostringstream out;
618 out << "allocateManyPrimaryBuffersTest succeded: created " << minCommandBuffer << " command buffers";
620 return tcu::TestStatus::pass(out.str());
623 tcu::TestStatus allocateSecondaryBufferTest(Context& context)
625 const VkDevice vkDevice = context.getDevice();
626 const DeviceInterface& vk = context.getDeviceInterface();
627 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
629 const VkCommandPoolCreateInfo cmdPoolParams =
631 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
633 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
634 queueFamilyIndex, // queueFamilyIndex;
636 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
639 const VkCommandBufferAllocateInfo cmdBufParams =
641 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
643 *cmdPool, // commandPool;
644 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level;
647 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
649 return tcu::TestStatus::pass("Buffer was created correctly.");
652 tcu::TestStatus allocateManySecondaryBuffersTest(Context& context)
655 const VkDevice vkDevice = context.getDevice();
656 const DeviceInterface& vk = context.getDeviceInterface();
657 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
659 const VkCommandPoolCreateInfo cmdPoolParams =
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;
666 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
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;
673 const unsigned minCommandBuffer = 10000;
676 const unsigned minCommandBuffer = 100;
677 #endif // CTS_USES_VULKANSC
680 const VkCommandBufferAllocateInfo cmdBufParams =
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;
689 // do not keep the handles to buffers, as they will be freed with command pool
691 // allocate the minimum required amount of buffers
692 VkCommandBuffer cmdBuffers[minCommandBuffer];
693 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
695 std::ostringstream out;
696 out << "allocateManySecondaryBuffersTest succeded: created " << minCommandBuffer << " command buffers";
698 return tcu::TestStatus::pass(out.str());
701 tcu::TestStatus executePrimaryBufferTest(Context& context)
703 const VkDevice vkDevice = context.getDevice();
704 const DeviceInterface& vk = context.getDeviceInterface();
705 const VkQueue queue = context.getUniversalQueue();
706 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
708 const VkCommandPoolCreateInfo cmdPoolParams =
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;
715 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
718 const VkCommandBufferAllocateInfo cmdBufParams =
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;
726 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
728 // create event that will be used to check if secondary command buffer has been executed
729 const Unique<VkEvent> event (createEvent(vk, vkDevice));
732 VK_CHECK(vk.resetEvent(vkDevice, *event));
734 // record primary command buffer
735 beginCommandBuffer(vk, *primCmdBuf, 0u);
737 // allow execution of event during every stage of pipeline
738 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
740 // record setting event
741 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
743 endCommandBuffer(vk, *primCmdBuf);
745 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
752 return tcu::TestStatus::fail("Execute Primary Command Buffer FAILED");
755 tcu::TestStatus executeLargePrimaryBufferTest(Context& context)
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;
764 const deUint32 LARGE_BUFFER_SIZE = 100;
765 #endif // CTS_USES_VULKANSC
768 const VkCommandPoolCreateInfo cmdPoolParams =
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;
775 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
778 const VkCommandBufferAllocateInfo cmdBufParams =
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;
786 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
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))));
792 // record primary command buffer
793 beginCommandBuffer(vk, *primCmdBuf, 0u);
795 // set all the events
796 for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
798 vk.cmdSetEvent(*primCmdBuf, events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
801 endCommandBuffer(vk, *primCmdBuf);
803 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
805 // check if the buffer was executed correctly - all events had their status
807 tcu::TestStatus testResult = tcu::TestStatus::incomplete();
809 for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx)
811 if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
813 testResult = tcu::TestStatus::fail("An event was not set.");
818 if (!testResult.isComplete())
819 testResult = tcu::TestStatus::pass("All events set correctly.");
824 tcu::TestStatus resetBufferImplicitlyTest(Context& context)
826 const VkDevice vkDevice = context.getDevice();
827 const DeviceInterface& vk = context.getDeviceInterface();
828 const VkQueue queue = context.getUniversalQueue();
829 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
831 const VkCommandPoolCreateInfo cmdPoolParams =
833 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
835 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
836 queueFamilyIndex, // queueFamilyIndex;
838 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
841 const VkCommandBufferAllocateInfo cmdBufParams =
843 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
846 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
849 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
851 const Unique<VkEvent> event (createEvent(vk, vkDevice));
853 // Put the command buffer in recording state.
854 beginCommandBuffer(vk, *cmdBuf, 0u);
857 vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
859 endCommandBuffer(vk, *cmdBuf);
861 submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
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.");
868 vk.resetEvent(vkDevice, *event);
869 if(vk.getEventStatus(vkDevice, *event) != VK_EVENT_RESET)
870 return tcu::TestStatus::fail("Failed to reset the event.");
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);
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());
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.");
885 return tcu::TestStatus::fail("Buffer was not reset correctly.");
888 #ifndef CTS_USES_VULKANSC
891 typedef SharedPtr<Unique<VkEvent> > VkEventShared;
894 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
896 return SharedPtr<Unique<T> >(new Unique<T>(move));
899 bool submitAndCheck (Context& context, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events)
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));
906 const VkSubmitInfo submitInfo =
908 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
919 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get()));
920 VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT));
922 for(int eventNdx = 0; eventNdx < static_cast<int>(events.size()); ++eventNdx)
924 if (vk.getEventStatus(vkDevice, **events[eventNdx]) != VK_EVENT_SET)
926 vk.resetEvent(vkDevice, **events[eventNdx]);
932 void createCommadBuffers (const DeviceInterface& vk,
933 const VkDevice vkDevice,
934 deUint32 bufferCount,
936 const VkCommandBufferLevel cmdBufferLevel,
937 VkCommandBuffer* pCommandBuffers)
939 const VkCommandBufferAllocateInfo cmdBufParams =
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;
947 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, pCommandBuffers));
950 void addCommandsToBuffer (const DeviceInterface& vk, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events)
952 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
954 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
956 (VkRenderPass)0u, // renderPass
958 (VkFramebuffer)0u, // framebuffer
959 VK_FALSE, // occlusionQueryEnable
960 (VkQueryControlFlags)0u, // queryFlags
961 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
964 const VkCommandBufferBeginInfo cmdBufBeginInfo =
966 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
969 &secCmdBufInheritInfo, // pInheritanceInfo;
972 for(int bufferNdx = 0; bufferNdx < static_cast<int>(cmdBuffers.size()); ++bufferNdx)
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]);
980 bool executeSecondaryCmdBuffer (Context& context,
982 std::vector<VkCommandBuffer>& cmdBuffersSecondary,
983 std::vector <VkEventShared>& events)
985 const VkDevice vkDevice = context.getDevice();
986 const DeviceInterface& vk = context.getDeviceInterface();
987 std::vector<VkCommandBuffer> cmdBuffer (1);
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]);
994 bool returnValue = submitAndCheck(context, cmdBuffer, events);
995 vk.freeCommandBuffers(vkDevice, pool, 1u, &cmdBuffer[0]);
999 tcu::TestStatus trimCommandPoolTest (Context& context, const VkCommandBufferLevel cmdBufferLevel)
1001 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1002 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1004 const VkDevice vkDevice = context.getDevice();
1005 const DeviceInterface& vk = context.getDeviceInterface();
1006 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1009 const deUint32 cmdBufferIterationCount = 300u;
1010 const deUint32 cmdBufferCount = 10u;
1012 const VkCommandPoolCreateInfo cmdPoolParams =
1014 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
1016 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
1017 queueFamilyIndex, // queueFamilyIndex;
1019 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1021 std::vector <VkEventShared> events;
1022 for (deUint32 ndx = 0u; ndx < cmdBufferCount; ++ndx)
1023 events.push_back(makeSharedPtr(createEvent(vk, vkDevice)));
1026 std::vector<VkCommandBuffer> cmdBuffers(cmdBufferCount);
1027 createCommadBuffers(vk, vkDevice, cmdBufferCount, *cmdPool, cmdBufferLevel, &cmdBuffers[0]);
1029 for (deUint32 cmdBufferIterationrNdx = 0; cmdBufferIterationrNdx < cmdBufferIterationCount; ++cmdBufferIterationrNdx)
1031 addCommandsToBuffer(vk, cmdBuffers, events);
1033 //Peak, situation when we use a lot more command buffers
1034 if (cmdBufferIterationrNdx % 10u == 0)
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);
1040 switch(cmdBufferLevel)
1042 case VK_COMMAND_BUFFER_LEVEL_PRIMARY:
1043 if (!submitAndCheck(context, cmdBuffersPeak, events))
1044 return tcu::TestStatus::fail("Fail");
1046 case VK_COMMAND_BUFFER_LEVEL_SECONDARY:
1047 if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffersPeak, events))
1048 return tcu::TestStatus::fail("Fail");
1053 vk.freeCommandBuffers(vkDevice, *cmdPool, static_cast<deUint32>(cmdBuffersPeak.size()), &cmdBuffersPeak[0]);
1056 vk.trimCommandPool(vkDevice, *cmdPool, (VkCommandPoolTrimFlags)0);
1058 switch(cmdBufferLevel)
1060 case VK_COMMAND_BUFFER_LEVEL_PRIMARY:
1061 if (!submitAndCheck(context, cmdBuffers, events))
1062 return tcu::TestStatus::fail("Fail");
1064 case VK_COMMAND_BUFFER_LEVEL_SECONDARY:
1065 if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffers, events))
1066 return tcu::TestStatus::fail("Fail");
1072 for (deUint32 bufferNdx = cmdBufferIterationrNdx % 3u; bufferNdx < cmdBufferCount; bufferNdx+=2u)
1074 vk.freeCommandBuffers(vkDevice, *cmdPool, 1u, &cmdBuffers[bufferNdx]);
1075 createCommadBuffers(vk, vkDevice, 1u, *cmdPool, cmdBufferLevel, &cmdBuffers[bufferNdx]);
1080 return tcu::TestStatus::pass("Pass");
1083 #endif // CTS_USES_VULKANSC
1085 /******** 19.3. Command Buffer Recording (5.3 in VK 1.0 Spec) *****************/
1086 tcu::TestStatus recordSinglePrimaryBufferTest(Context& context)
1088 const VkDevice vkDevice = context.getDevice();
1089 const DeviceInterface& vk = context.getDeviceInterface();
1090 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1092 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1099 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1102 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1110 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1112 // create event that will be used to check if secondary command buffer has been executed
1113 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1115 // record primary command buffer
1116 beginCommandBuffer(vk, *primCmdBuf, 0u);
1118 // record setting event
1119 vk.cmdSetEvent(*primCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1121 endCommandBuffer(vk, *primCmdBuf);
1123 return tcu::TestStatus::pass("Primary buffer recorded successfully.");
1126 tcu::TestStatus recordLargePrimaryBufferTest(Context &context)
1128 const VkDevice vkDevice = context.getDevice();
1129 const DeviceInterface& vk = context.getDeviceInterface();
1130 const VkQueue queue = context.getUniversalQueue();
1131 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1133 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1140 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1143 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1151 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1153 // create event that will be used to check if secondary command buffer has been executed
1154 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1157 VK_CHECK(vk.resetEvent(vkDevice, *event));
1159 // record primary command buffer
1160 beginCommandBuffer(vk, *primCmdBuf, 0u);
1162 // allow execution of event during every stage of pipeline
1163 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1165 // define minimal amount of commands to accept
1166 #ifndef CTS_USES_VULKANSC
1167 const long long unsigned minNumCommands = 10000llu;
1169 const long long unsigned minNumCommands = 1000llu;
1170 #endif // CTS_USES_VULKANSC
1172 for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands )
1174 // record setting event
1175 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1177 // record resetting event
1178 vk.cmdResetEvent(*primCmdBuf, *event,stageMask);
1182 endCommandBuffer(vk, *primCmdBuf);
1184 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1186 return tcu::TestStatus::pass("hugeTest succeeded");
1189 tcu::TestStatus recordSingleSecondaryBufferTest(Context& context)
1191 const VkDevice vkDevice = context.getDevice();
1192 const DeviceInterface& vk = context.getDeviceInterface();
1193 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1195 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1202 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1205 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1213 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1215 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
1217 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1219 (VkRenderPass)0u, // renderPass
1221 (VkFramebuffer)0u, // framebuffer
1222 VK_FALSE, // occlusionQueryEnable
1223 (VkQueryControlFlags)0u, // queryFlags
1224 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
1226 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
1228 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1231 &secCmdBufInheritInfo,
1234 // create event that will be used to check if secondary command buffer has been executed
1235 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1237 // record primary command buffer
1238 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1240 // record setting event
1241 vk.cmdSetEvent(*secCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1243 endCommandBuffer(vk, *secCmdBuf);
1245 return tcu::TestStatus::pass("Secondary buffer recorded successfully.");
1248 tcu::TestStatus recordLargeSecondaryBufferTest(Context &context)
1250 const VkDevice vkDevice = context.getDevice();
1251 const DeviceInterface& vk = context.getDeviceInterface();
1252 const VkQueue queue = context.getUniversalQueue();
1253 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1255 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1262 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1263 const Unique<VkCommandPool> secCmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1265 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1273 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1275 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
1283 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1285 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
1287 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1289 (VkRenderPass)0u, // renderPass
1291 (VkFramebuffer)0u, // framebuffer
1292 VK_FALSE, // occlusionQueryEnable
1293 (VkQueryControlFlags)0u, // queryFlags
1294 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
1296 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
1298 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1301 &secCmdBufInheritInfo,
1304 // create event that will be used to check if secondary command buffer has been executed
1305 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1308 VK_CHECK(vk.resetEvent(vkDevice, *event));
1310 // record primary command buffer
1311 beginCommandBuffer(vk, *primCmdBuf, 0u);
1313 // record secondary command buffer
1314 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1316 // allow execution of event during every stage of pipeline
1317 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1319 // define minimal amount of commands to accept
1320 #ifndef CTS_USES_VULKANSC
1321 const long long unsigned minNumCommands = 10000llu;
1323 const long long unsigned minNumCommands = 1000llu;
1324 #endif // CTS_USES_VULKANSC
1326 for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands )
1328 // record setting event
1329 vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1331 // record resetting event
1332 vk.cmdResetEvent(*secCmdBuf, *event,stageMask);
1336 // end recording of secondary buffers
1337 endCommandBuffer(vk, *secCmdBuf);
1339 // execute secondary buffer
1340 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
1342 endCommandBuffer(vk, *primCmdBuf);
1344 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
1346 return tcu::TestStatus::pass("hugeTest succeeded");
1349 tcu::TestStatus submitPrimaryBufferTwiceTest(Context& context)
1351 const VkDevice vkDevice = context.getDevice();
1352 const DeviceInterface& vk = context.getDeviceInterface();
1353 const VkQueue queue = context.getUniversalQueue();
1354 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1356 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1363 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1366 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1374 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1376 // create event that will be used to check if secondary command buffer has been executed
1377 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1380 VK_CHECK(vk.resetEvent(vkDevice, *event));
1382 // record primary command buffer
1383 beginCommandBuffer(vk, *primCmdBuf, 0u);
1385 // allow execution of event during every stage of pipeline
1386 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1388 // record setting event
1389 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1391 endCommandBuffer(vk, *primCmdBuf);
1393 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
1401 VK_CHECK(vk.resetEvent(vkDevice, *event));
1403 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
1410 return tcu::TestStatus::pass("Submit Twice Test succeeded");
1413 tcu::TestStatus submitSecondaryBufferTwiceTest(Context& context)
1415 const VkDevice vkDevice = context.getDevice();
1416 const DeviceInterface& vk = context.getDeviceInterface();
1417 const VkQueue queue = context.getUniversalQueue();
1418 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1420 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1428 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1429 const Unique<VkCommandPool> secCmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1432 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1441 const Unique<VkCommandBuffer> primCmdBuf1 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1442 const Unique<VkCommandBuffer> primCmdBuf2 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1444 // Secondary Command buffer
1445 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
1453 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1455 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
1457 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1459 (VkRenderPass)0u, // renderPass
1461 (VkFramebuffer)0u, // framebuffer
1462 VK_FALSE, // occlusionQueryEnable
1463 (VkQueryControlFlags)0u, // queryFlags
1464 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
1466 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
1468 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1471 &secCmdBufInheritInfo,
1474 // create event that will be used to check if secondary command buffer has been executed
1475 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1478 VK_CHECK(vk.resetEvent(vkDevice, *event));
1480 // record first primary command buffer
1481 beginCommandBuffer(vk, *primCmdBuf1, 0u);
1483 // record secondary command buffer
1484 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1486 // allow execution of event during every stage of pipeline
1487 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1489 // record setting event
1490 vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1493 // end recording of secondary buffers
1494 endCommandBuffer(vk, *secCmdBuf);
1496 // execute secondary buffer
1497 vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get());
1499 endCommandBuffer(vk, *primCmdBuf1);
1501 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf1.get());
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");
1508 // reset first primary buffer
1509 vk.resetCommandBuffer( *primCmdBuf1, 0u);
1511 // reset event to allow receiving it again
1512 VK_CHECK(vk.resetEvent(vkDevice, *event));
1514 // record second primary command buffer
1515 beginCommandBuffer(vk, *primCmdBuf2, 0u);
1517 // execute secondary buffer
1518 vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get());
1521 endCommandBuffer(vk, *primCmdBuf2);
1523 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf2.get());
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");
1530 return tcu::TestStatus::pass("Submit Twice Secondary Command Buffer succeeded");
1533 tcu::TestStatus oneTimeSubmitFlagPrimaryBufferTest(Context& context)
1535 const VkDevice vkDevice = context.getDevice();
1536 const DeviceInterface& vk = context.getDeviceInterface();
1537 const VkQueue queue = context.getUniversalQueue();
1538 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1540 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1547 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1550 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1558 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1560 // create event that will be used to check if secondary command buffer has been executed
1561 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1564 VK_CHECK(vk.resetEvent(vkDevice, *event));
1566 // record primary command buffer
1567 beginCommandBuffer(vk, *primCmdBuf);
1569 // allow execution of event during every stage of pipeline
1570 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1572 // record setting event
1573 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1575 endCommandBuffer(vk, *primCmdBuf);
1577 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
1584 // record primary command buffer again - implicit reset because of VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
1585 beginCommandBuffer(vk, *primCmdBuf);
1587 // allow execution of event during every stage of pipeline
1588 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1590 // record setting event
1591 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
1593 endCommandBuffer(vk, *primCmdBuf);
1595 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
1602 return tcu::TestStatus::pass("oneTimeSubmitFlagPrimaryBufferTest succeeded");
1605 tcu::TestStatus oneTimeSubmitFlagSecondaryBufferTest(Context& context)
1607 const VkDevice vkDevice = context.getDevice();
1608 const DeviceInterface& vk = context.getDeviceInterface();
1609 const VkQueue queue = context.getUniversalQueue();
1610 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1612 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1620 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1621 const Unique<VkCommandPool> secCmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1624 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1633 const Unique<VkCommandBuffer> primCmdBuf1 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1634 const Unique<VkCommandBuffer> primCmdBuf2 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1636 // Secondary Command buffer
1637 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
1645 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1647 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
1649 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1651 (VkRenderPass)0u, // renderPass
1653 (VkFramebuffer)0u, // framebuffer
1654 VK_FALSE, // occlusionQueryEnable
1655 (VkQueryControlFlags)0u, // queryFlags
1656 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
1658 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
1660 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1662 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1663 &secCmdBufInheritInfo,
1666 // create event that will be used to check if secondary command buffer has been executed
1667 const Unique<VkEvent> event (createEvent(vk, vkDevice));
1670 VK_CHECK(vk.resetEvent(vkDevice, *event));
1672 // record first primary command buffer
1673 beginCommandBuffer(vk, *primCmdBuf1, 0u);
1675 // record secondary command buffer
1676 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1678 // allow execution of event during every stage of pipeline
1679 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1681 // record setting event
1682 vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1685 // end recording of secondary buffers
1686 endCommandBuffer(vk, *secCmdBuf);
1688 // execute secondary buffer
1689 vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get());
1691 endCommandBuffer(vk, *primCmdBuf1);
1693 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf1.get());
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");
1700 // reset first primary buffer
1701 vk.resetCommandBuffer( *primCmdBuf1, 0u);
1703 // reset event to allow receiving it again
1704 VK_CHECK(vk.resetEvent(vkDevice, *event));
1706 // record secondary command buffer again
1707 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1709 // allow execution of event during every stage of pipeline
1710 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1712 // record setting event
1713 vk.cmdSetEvent(*secCmdBuf, *event,stageMask);
1715 // end recording of secondary buffers
1716 endCommandBuffer(vk, *secCmdBuf);
1718 // record second primary command buffer
1719 beginCommandBuffer(vk, *primCmdBuf2, 0u);
1721 // execute secondary buffer
1722 vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get());
1725 endCommandBuffer(vk, *primCmdBuf2);
1727 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf2.get());
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");
1734 return tcu::TestStatus::pass("oneTimeSubmitFlagSecondaryBufferTest succeeded");
1737 tcu::TestStatus renderPassContinueTest(Context& context, bool framebufferHint)
1739 const DeviceInterface& vkd = context.getDeviceInterface();
1740 CommandBufferRenderPassTestEnvironment env (context, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
1742 VkCommandBuffer primaryCommandBuffer = env.getPrimaryCommandBuffer();
1743 VkCommandBuffer secondaryCommandBuffer = env.getSecondaryCommandBuffer();
1744 const deUint32 clearColor[4] = { 2, 47, 131, 211 };
1746 const VkClearAttachment clearAttachment =
1748 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1749 0, // deUint32 colorAttachment;
1750 makeClearValueColorU32(clearColor[0],
1753 clearColor[3]) // VkClearValue clearValue;
1756 const VkClearRect clearRect =
1758 CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA, // VkRect2D rect;
1759 0u, // deUint32 baseArrayLayer;
1760 1u // deUint32 layerCount;
1763 env.beginSecondaryCommandBuffer(VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, framebufferHint);
1764 vkd.cmdClearAttachments(secondaryCommandBuffer, 1, &clearAttachment, 1, &clearRect);
1765 endCommandBuffer(vkd, secondaryCommandBuffer);
1768 env.beginPrimaryCommandBuffer(0);
1769 env.beginRenderPass(VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1770 vkd.cmdExecuteCommands(primaryCommandBuffer, 1, &secondaryCommandBuffer);
1771 endRenderPass(vkd, primaryCommandBuffer);
1773 endCommandBuffer(vkd, primaryCommandBuffer);
1775 env.submitPrimaryCommandBuffer();
1777 de::MovePtr<tcu::TextureLevel> result = env.readColorAttachment();
1778 tcu::PixelBufferAccess pixelBufferAccess = result->getAccess();
1780 for (deUint32 i = 0; i < (CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.width * CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.height); ++i)
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");
1788 return tcu::TestStatus::pass("render pass continue test passed");
1791 tcu::TestStatus simultaneousUsePrimaryBufferTest(Context& context)
1793 const VkDevice vkDevice = context.getDevice();
1794 const DeviceInterface& vk = context.getDeviceInterface();
1795 const VkQueue queue = context.getUniversalQueue();
1796 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1798 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1805 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1808 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1816 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
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));
1823 VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
1825 // record primary command buffer
1826 beginCommandBuffer(vk, *primCmdBuf, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
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);
1831 // Set the second event
1832 vk.cmdSetEvent(*primCmdBuf, eventTwo.get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1834 endCommandBuffer(vk, *primCmdBuf);
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));
1840 const VkSubmitInfo submitInfo =
1842 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
1853 // submit first buffer
1854 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence1));
1856 // submit second buffer
1857 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence2));
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);
1864 VK_CHECK(vk.setEvent(vkDevice, *eventOne));
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));
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
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");
1879 return tcu::TestStatus::fail("simultaneous use - primary buffers test FAILED");
1882 tcu::TestStatus simultaneousUseSecondaryBufferTest(Context& context)
1884 const VkDevice vkDevice = context.getDevice();
1885 const DeviceInterface& vk = context.getDeviceInterface();
1886 const VkQueue queue = context.getUniversalQueue();
1887 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1889 const VkCommandPoolCreateInfo cmdPoolParams =
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;
1896 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
1899 const VkCommandBufferAllocateInfo cmdBufParams =
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;
1907 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
1909 // Secondary Command buffer params
1910 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
1918 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
1920 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
1922 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1924 (VkRenderPass)0u, // renderPass
1926 (VkFramebuffer)0u, // framebuffer
1927 VK_FALSE, // occlusionQueryEnable
1928 (VkQueryControlFlags)0u, // queryFlags
1929 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
1931 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
1933 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1935 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags
1936 &secCmdBufInheritInfo,
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));
1944 VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
1945 VK_CHECK(vk.resetEvent(vkDevice, *eventTwo));
1947 // record secondary command buffer
1948 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
1950 // allow execution of event during every stage of pipeline
1951 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1954 vk.cmdWaitEvents(*secCmdBuf, 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
1957 vk.cmdSetEvent(*secCmdBuf, *eventTwo, stageMask);
1959 // end recording of secondary buffers
1960 endCommandBuffer(vk, *secCmdBuf);
1962 // record primary command buffer
1963 beginCommandBuffer(vk, *primCmdBuf, 0u);
1965 // execute secondary buffer
1966 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
1968 endCommandBuffer(vk, *primCmdBuf);
1970 // create fence to wait for execution of queue
1971 const Unique<VkFence> fence (createFence(vk, vkDevice));
1973 const VkSubmitInfo submitInfo =
1975 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
1986 // submit primary buffer, the secondary should be executed too
1987 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
1989 // wait for both buffers to stop at event for 100 microseconds
1990 vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 100000);
1993 VK_CHECK(vk.setEvent(vkDevice, *eventOne));
1995 // wait for end of execution of queue
1996 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
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
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");
2006 return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2009 tcu::TestStatus simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& context)
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);
2018 const VkCommandPoolCreateInfo cmdPoolParams =
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;
2025 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
2028 const VkCommandBufferAllocateInfo cmdBufParams =
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;
2036 const Unique<VkCommandBuffer> primCmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
2038 // Secondary Command buffer params
2039 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
2047 const Unique<VkCommandBuffer> secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2049 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
2051 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2056 VK_FALSE, // occlusionQueryEnable
2057 (VkQueryControlFlags)0u,
2058 (VkQueryPipelineStatisticFlags)0u,
2060 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
2062 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2064 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags
2065 &secCmdBufInheritInfo,
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);
2080 const VkPipelineLayoutCreateInfo layoutCreateInfo =
2082 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
2084 (VkPipelineLayoutCreateFlags)0,
2085 numDescriptorSets, // setLayoutCount
2086 &descriptorSetLayout.get(), // pSetLayouts
2087 0u, // pushConstantRangeCount
2088 DE_NULL, // pPushConstantRanges
2090 Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2092 const Unique<VkShaderModule> computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2094 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
2096 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2098 (VkPipelineShaderStageCreateFlags)0,
2099 VK_SHADER_STAGE_COMPUTE_BIT, // stage
2100 *computeModule, // shader
2102 DE_NULL, // pSpecializationInfo
2105 const VkComputePipelineCreateInfo pipelineCreateInfo =
2107 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2110 shaderCreateInfo, // cs
2111 *pipelineLayout, // layout
2112 (vk::VkPipeline)0, // basePipelineHandle
2113 0u, // basePipelineIndex
2116 const VkBufferMemoryBarrier bufferBarrier =
2118 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType
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
2125 (VkDeviceSize)0u, // offset
2126 (VkDeviceSize)VK_WHOLE_SIZE, // size
2129 const Unique<VkPipeline> pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2131 // record secondary command buffer
2132 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
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,
2140 0, (const VkImageMemoryBarrier*)DE_NULL);
2142 // end recording of secondary buffer
2143 endCommandBuffer(vk, *secCmdBuf);
2145 // record primary command buffer
2146 beginCommandBuffer(vk, *primCmdBuf, 0u);
2148 // execute secondary buffer twice in same primary
2149 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2150 vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get());
2152 endCommandBuffer(vk, *primCmdBuf);
2154 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
2162 return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2165 enum class BadInheritanceInfoCase
2168 RANDOM_PTR_CONTINUATION,
2170 INVALID_STRUCTURE_TYPE,
2171 VALID_NONSENSE_TYPE,
2174 tcu::TestStatus badInheritanceInfoTest (Context& context, BadInheritanceInfoCase testCase)
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);
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();
2188 // Buffers, descriptor set layouts and descriptor sets.
2189 const deUint32 offset = 0u;
2190 const deUint32 addressableSize = 256u;
2191 const deUint32 dataSize = 8u;
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));
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);
2204 const auto pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
2206 // Compute shader module.
2207 const Unique<VkShaderModule> computeModule (createShaderModule(vkd, device, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2209 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
2211 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2213 (VkPipelineShaderStageCreateFlags)0,
2214 VK_SHADER_STAGE_COMPUTE_BIT, // stage
2215 *computeModule, // shader
2217 DE_NULL, // pSpecializationInfo
2220 const VkComputePipelineCreateInfo pipelineCreateInfo =
2222 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2225 shaderCreateInfo, // cs
2226 *pipelineLayout, // layout
2227 (vk::VkPipeline)0, // basePipelineHandle
2228 0u, // basePipelineIndex
2231 const Unique<VkPipeline> pipeline (createComputePipeline(vkd, device, (VkPipelineCache)0u, &pipelineCreateInfo));
2233 // Compute to host barrier to read result.
2234 const VkBufferMemoryBarrier bufferBarrier =
2236 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType
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
2243 (VkDeviceSize)0u, // offset
2244 (VkDeviceSize)VK_WHOLE_SIZE, // size
2247 // Record command buffer and submit it.
2248 VkCommandBufferBeginInfo beginInfo =
2250 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2251 nullptr, // const void* pNext;
2252 0u, // VkCommandBufferUsageFlags flags;
2253 nullptr, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
2256 // Structures used in different test types.
2257 VkCommandBufferInheritanceInfo inheritanceInfo;
2258 VkBufferCreateInfo validNonsenseStructure;
2261 VkStructureType sType;
2265 if (testCase == BadInheritanceInfoCase::RANDOM_PTR || testCase == BadInheritanceInfoCase::RANDOM_PTR_CONTINUATION)
2267 de::Random rnd (1602600778u);
2268 VkCommandBufferInheritanceInfo* info;
2269 auto ptrData = reinterpret_cast<deUint8*>(&info);
2271 // Fill pointer value with pseudorandom garbage.
2272 for (size_t i = 0; i < sizeof(info); ++i)
2273 *ptrData++ = rnd.getUint8();
2275 beginInfo.pInheritanceInfo = info;
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;
2282 else if (testCase == BadInheritanceInfoCase::RANDOM_DATA_PTR)
2284 de::Random rnd (1602601141u);
2285 auto itr = reinterpret_cast<deUint8*>(&inheritanceInfo);
2287 // Fill inheritance info data structure with random data.
2288 for (size_t i = 0; i < sizeof(inheritanceInfo); ++i)
2289 *itr++ = rnd.getUint8();
2291 beginInfo.pInheritanceInfo = &inheritanceInfo;
2293 else if (testCase == BadInheritanceInfoCase::INVALID_STRUCTURE_TYPE)
2295 de::Random rnd (1602658515u);
2296 auto ptrData = reinterpret_cast<deUint8*>(&(invalidStructure.pNext));
2297 invalidStructure.sType = VK_STRUCTURE_TYPE_MAX_ENUM;
2299 // Fill pNext pointer with random data.
2300 for (size_t i = 0; i < sizeof(invalidStructure.pNext); ++i)
2301 *ptrData++ = rnd.getUint8();
2303 beginInfo.pInheritanceInfo = reinterpret_cast<VkCommandBufferInheritanceInfo*>(&invalidStructure);
2305 else if (testCase == BadInheritanceInfoCase::VALID_NONSENSE_TYPE)
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;
2316 beginInfo.pInheritanceInfo = reinterpret_cast<VkCommandBufferInheritanceInfo*>(&validNonsenseStructure);
2323 VK_CHECK(vkd.beginCommandBuffer(cmdBuffer, &beginInfo));
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,
2331 0, (const VkImageMemoryBarrier*)DE_NULL);
2333 endCommandBuffer(vkd, cmdBuffer);
2334 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
2336 deUint32 resultCount;
2337 result.readResultContentsTo(&resultCount);
2339 // Make sure the command buffer was run.
2340 if (resultCount != 1u)
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());
2347 return tcu::TestStatus::pass("Pass");
2350 tcu::TestStatus simultaneousUseSecondaryBufferTwoPrimaryBuffersTest(Context& context)
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);
2359 const VkCommandPoolCreateInfo cmdPoolParams =
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;
2366 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
2369 const VkCommandBufferAllocateInfo cmdBufParams =
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;
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();
2385 // Secondary Command buffer params
2386 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
2394 const Unique<VkCommandBuffer> secCmdBuf(allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2396 const VkCommandBufferBeginInfo primCmdBufBeginInfo =
2398 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2401 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2404 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
2406 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2408 (VkRenderPass)0u, // renderPass
2410 (VkFramebuffer)0u, // framebuffer
2411 VK_FALSE, // occlusionQueryEnable
2412 (VkQueryControlFlags)0u, // queryFlags
2413 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
2415 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
2417 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2419 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags
2420 &secCmdBufInheritInfo,
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);
2435 const VkPipelineLayoutCreateInfo layoutCreateInfo =
2437 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
2439 (VkPipelineLayoutCreateFlags)0,
2440 numDescriptorSets, // setLayoutCount
2441 &descriptorSetLayout.get(), // pSetLayouts
2442 0u, // pushConstantRangeCount
2443 DE_NULL, // pPushConstantRanges
2445 Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, vkDevice, &layoutCreateInfo));
2447 const Unique<VkShaderModule> computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u));
2449 const VkPipelineShaderStageCreateInfo shaderCreateInfo =
2451 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2453 (VkPipelineShaderStageCreateFlags)0,
2454 VK_SHADER_STAGE_COMPUTE_BIT, // stage
2455 *computeModule, // shader
2457 DE_NULL, // pSpecializationInfo
2460 const VkComputePipelineCreateInfo pipelineCreateInfo =
2462 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2465 shaderCreateInfo, // cs
2466 *pipelineLayout, // layout
2467 (vk::VkPipeline)0, // basePipelineHandle
2468 0u, // basePipelineIndex
2471 const Unique<VkPipeline> pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo));
2473 // record secondary command buffer
2474 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
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);
2480 // end recording of secondary buffer
2481 endCommandBuffer(vk, *secCmdBuf);
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));
2487 vk.cmdExecuteCommands(*primCmdBufOne, 1, &secCmdBuf.get());
2489 endCommandBuffer(vk, *primCmdBufOne);
2491 VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
2493 vk.cmdExecuteCommands(*primCmdBufTwo, 1, &secCmdBuf.get());
2495 endCommandBuffer(vk, *primCmdBufTwo);
2497 // create fence to wait for execution of queue
2498 const Unique<VkFence> fence(createFence(vk, vkDevice));
2500 const VkSubmitInfo submitInfo =
2502 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
2513 // submit primary buffers, the secondary should be executed too
2514 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2516 // wait for end of execution of queue
2517 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
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");
2525 return tcu::TestStatus::fail("Simultaneous Secondary Command Buffer Execution FAILED");
2528 tcu::TestStatus recordBufferQueryPreciseWithFlagTest(Context& context)
2530 const VkDevice vkDevice = context.getDevice();
2531 const DeviceInterface& vk = context.getDeviceInterface();
2532 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2534 if (!context.getDeviceFeatures().inheritedQueries)
2535 TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2537 const VkCommandPoolCreateInfo cmdPoolParams =
2539 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
2541 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
2542 queueFamilyIndex, // queueFamilyIndex;
2544 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
2547 const VkCommandBufferAllocateInfo primCmdBufParams =
2549 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2552 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
2555 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2557 // Secondary Command buffer params
2558 const VkCommandBufferAllocateInfo secCmdBufParams =
2560 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2563 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level;
2566 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2568 const VkCommandBufferBeginInfo primBufferBeginInfo =
2570 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2573 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2576 const VkCommandBufferInheritanceInfo secBufferInheritInfo =
2578 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2583 VK_TRUE, // occlusionQueryEnable
2584 VK_QUERY_CONTROL_PRECISE_BIT, // queryFlags
2585 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
2587 const VkCommandBufferBeginInfo secBufferBeginInfo =
2589 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2592 &secBufferInheritInfo,
2595 const VkQueryPoolCreateInfo queryPoolCreateInfo =
2597 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType
2599 (VkQueryPoolCreateFlags)0, // flags
2600 VK_QUERY_TYPE_OCCLUSION, // queryType
2602 0u, // pipelineStatistics
2604 Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2606 VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2607 endCommandBuffer(vk, secCmdBuf.get());
2609 VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2611 vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2612 vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT);
2614 vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2616 vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2618 endCommandBuffer(vk, primCmdBuf.get());
2620 return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query.");
2623 tcu::TestStatus recordBufferQueryImpreciseWithFlagTest(Context& context)
2625 const VkDevice vkDevice = context.getDevice();
2626 const DeviceInterface& vk = context.getDeviceInterface();
2627 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2629 if (!context.getDeviceFeatures().inheritedQueries)
2630 TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2632 const VkCommandPoolCreateInfo cmdPoolParams =
2634 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
2636 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
2637 queueFamilyIndex, // queueFamilyIndex;
2639 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
2642 const VkCommandBufferAllocateInfo primCmdBufParams =
2644 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2647 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
2650 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2652 // Secondary Command buffer params
2653 const VkCommandBufferAllocateInfo secCmdBufParams =
2655 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2658 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level;
2661 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2663 const VkCommandBufferBeginInfo primBufferBeginInfo =
2665 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2668 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2671 const VkCommandBufferInheritanceInfo secBufferInheritInfo =
2673 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2678 VK_TRUE, // occlusionQueryEnable
2679 VK_QUERY_CONTROL_PRECISE_BIT, // queryFlags
2680 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
2682 const VkCommandBufferBeginInfo secBufferBeginInfo =
2684 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2687 &secBufferInheritInfo,
2690 const VkQueryPoolCreateInfo queryPoolCreateInfo =
2692 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType
2695 VK_QUERY_TYPE_OCCLUSION, // queryType
2697 0u, // pipelineStatistics
2699 Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2701 VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2702 endCommandBuffer(vk, secCmdBuf.get());
2704 VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2706 vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2707 vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, 0u);
2709 vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2711 vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2713 endCommandBuffer(vk, primCmdBuf.get());
2715 return tcu::TestStatus::pass("Successfully recorded an imprecise query with a secondary command buffer allowing a precise occlusion query.");
2718 tcu::TestStatus recordBufferQueryImpreciseWithoutFlagTest(Context& context)
2720 const VkDevice vkDevice = context.getDevice();
2721 const DeviceInterface& vk = context.getDeviceInterface();
2722 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2724 if (!context.getDeviceFeatures().inheritedQueries)
2725 TCU_THROW(NotSupportedError, "Inherited queries feature is not supported");
2727 const VkCommandPoolCreateInfo cmdPoolParams =
2729 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
2731 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
2732 queueFamilyIndex, // queueFamilyIndex;
2734 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
2737 const VkCommandBufferAllocateInfo primCmdBufParams =
2739 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2742 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
2745 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams));
2747 // Secondary Command buffer params
2748 const VkCommandBufferAllocateInfo secCmdBufParams =
2750 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2753 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level;
2756 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
2758 const VkCommandBufferBeginInfo primBufferBeginInfo =
2760 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2763 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2766 const VkCommandBufferInheritanceInfo secBufferInheritInfo =
2768 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
2773 VK_TRUE, // occlusionQueryEnable
2775 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
2777 const VkCommandBufferBeginInfo secBufferBeginInfo =
2779 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2782 &secBufferInheritInfo,
2785 const VkQueryPoolCreateInfo queryPoolCreateInfo =
2787 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType
2789 (VkQueryPoolCreateFlags)0,
2790 VK_QUERY_TYPE_OCCLUSION,
2794 Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo));
2796 VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo));
2797 endCommandBuffer(vk, secCmdBuf.get());
2799 VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo));
2801 vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u);
2802 vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, 0u);
2804 vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get());
2806 vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u);
2808 endCommandBuffer(vk, primCmdBuf.get());
2810 return tcu::TestStatus::pass("Successfully recorded an imprecise query with a secondary command buffer not allowing a precise occlusion query.");
2813 /******** 19.4. Command Buffer Submission (5.4 in VK 1.0 Spec) ****************/
2814 tcu::TestStatus submitBufferCountNonZero(Context& context)
2816 const VkDevice vkDevice = context.getDevice();
2817 const DeviceInterface& vk = context.getDeviceInterface();
2818 const VkQueue queue = context.getUniversalQueue();
2819 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2821 const deUint32 BUFFER_COUNT = 5u;
2823 const VkCommandPoolCreateInfo cmdPoolParams =
2825 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
2828 queueFamilyIndex, // queueFamilyIndex;
2830 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
2833 const VkCommandBufferAllocateInfo cmdBufParams =
2835 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2838 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
2839 BUFFER_COUNT, // bufferCount;
2841 VkCommandBuffer cmdBuffers[BUFFER_COUNT];
2842 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
2844 const VkCommandBufferBeginInfo cmdBufBeginInfo =
2846 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2849 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2852 std::vector<VkEventSp> events;
2853 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2855 events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice))));
2858 // Record the command buffers
2859 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2861 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
2863 vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2865 endCommandBuffer(vk, cmdBuffers[ndx]);
2868 // We'll use a fence to wait for the execution of the queue
2869 const Unique<VkFence> fence (createFence(vk, vkDevice));
2871 const VkSubmitInfo submitInfo =
2873 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
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));
2889 // Check if the buffers were executed
2890 tcu::TestStatus testResult = tcu::TestStatus::incomplete();
2892 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2894 if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET)
2896 testResult = tcu::TestStatus::fail("Failed to set the event.");
2901 if (!testResult.isComplete())
2902 testResult = tcu::TestStatus::pass("All buffers were submitted and executed correctly.");
2907 tcu::TestStatus submitBufferCountEqualZero(Context& context)
2909 const VkDevice vkDevice = context.getDevice();
2910 const DeviceInterface& vk = context.getDeviceInterface();
2911 const VkQueue queue = context.getUniversalQueue();
2912 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2914 const deUint32 BUFFER_COUNT = 2u;
2916 const VkCommandPoolCreateInfo cmdPoolParams =
2918 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
2921 queueFamilyIndex, // queueFamilyIndex;
2923 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
2926 const VkCommandBufferAllocateInfo cmdBufParams =
2928 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
2931 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
2932 BUFFER_COUNT, // bufferCount;
2934 VkCommandBuffer cmdBuffers[BUFFER_COUNT];
2935 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
2937 const VkCommandBufferBeginInfo cmdBufBeginInfo =
2939 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
2942 (const VkCommandBufferInheritanceInfo*)DE_NULL,
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))));
2949 // Record the command buffers
2950 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
2952 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
2954 vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2956 endCommandBuffer(vk, cmdBuffers[ndx]);
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));
2963 const VkSubmitInfo submitInfoCountZero =
2965 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
2976 const VkSubmitInfo submitInfoCountOne =
2978 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
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()));
2995 const VkFence fences[] =
3001 // Wait for the queue
3002 VK_CHECK(vk.waitForFences(vkDevice, (deUint32)DE_LENGTH_OF_ARRAY(fences), fences, VK_TRUE, INFINITE_TIMEOUT));
3004 // Check if the first buffer was executed
3005 tcu::TestStatus testResult = tcu::TestStatus::incomplete();
3007 if (vk.getEventStatus(vkDevice, events[0]->get()) == VK_EVENT_SET)
3008 testResult = tcu::TestStatus::fail("The first event was signaled.");
3010 testResult = tcu::TestStatus::pass("The first submission was ignored.");
3015 tcu::TestStatus submitBufferWaitSingleSemaphore(Context& context)
3017 const VkDevice vkDevice = context.getDevice();
3018 const DeviceInterface& vk = context.getDeviceInterface();
3019 const VkQueue queue = context.getUniversalQueue();
3020 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
3022 const VkCommandPoolCreateInfo cmdPoolParams =
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;
3029 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
3032 const VkCommandBufferAllocateInfo cmdBufParams =
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;
3041 // Create two command buffers
3042 const Unique<VkCommandBuffer> primCmdBuf1 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3043 const Unique<VkCommandBuffer> primCmdBuf2 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3045 const VkCommandBufferBeginInfo primCmdBufBeginInfo =
3047 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3050 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
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));
3058 VK_CHECK(vk.resetEvent(vkDevice, *event1));
3059 VK_CHECK(vk.resetEvent(vkDevice, *event2));
3061 // record first command buffer
3062 VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo));
3064 // allow execution of event during every stage of pipeline
3065 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3067 // record setting event
3068 vk.cmdSetEvent(*primCmdBuf1, *event1,stageMask);
3070 endCommandBuffer(vk, *primCmdBuf1);
3072 // record second command buffer
3073 VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo));
3075 // allow execution of event during every stage of pipeline
3076 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3078 // record setting event
3079 vk.cmdSetEvent(*primCmdBuf2, *event2,stageMask);
3081 endCommandBuffer(vk, *primCmdBuf2);
3083 // create fence to wait for execution of queue
3084 const Unique<VkFence> fence (createFence(vk, vkDevice));
3086 // create semaphore for use in this test
3087 const Unique <VkSemaphore> semaphore (createSemaphore(vk, vkDevice));
3089 // create submit info for first buffer - signalling semaphore
3090 const VkSubmitInfo submitInfo1 =
3092 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3103 // Submit the command buffer to the queue
3104 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3106 // wait for end of execution of queue
3107 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
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");
3114 const VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
3116 // create submit info for second buffer - waiting for semaphore
3117 const VkSubmitInfo submitInfo2 =
3119 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
3121 1u, // waitSemaphoreCount
3122 &semaphore.get(), // pWaitSemaphores
3123 &waitDstStageFlags, // pWaitDstStageMask
3124 1, // commandBufferCount
3125 &primCmdBuf2.get(), // pCommandBuffers
3126 0u, // signalSemaphoreCount
3127 DE_NULL, // pSignalSemaphores
3130 // reset fence, so it can be used again
3131 VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3133 // Submit the second command buffer to the queue
3134 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3136 // wait for end of execution of queue
3137 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
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");
3145 return tcu::TestStatus::pass("Submit Buffer and Wait for Single Semaphore Test succeeded");
3148 tcu::TestStatus submitBufferWaitManySemaphores(Context& context)
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
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();
3160 const VkCommandPoolCreateInfo cmdPoolParams =
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;
3167 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
3170 const VkCommandBufferAllocateInfo cmdBufParams =
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;
3179 // Create command buffer
3180 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3182 const VkCommandBufferBeginInfo primCmdBufBeginInfo =
3184 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3187 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
3190 // create event that will be used to check if command buffers has been executed
3191 const Unique<VkEvent> event (createEvent(vk, vkDevice));
3193 // reset event - at creation state is undefined
3194 VK_CHECK(vk.resetEvent(vkDevice, *event));
3196 // record command buffer
3197 VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3199 // allow execution of event during every stage of pipeline
3200 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3202 // record setting event
3203 vk.cmdSetEvent(*primCmdBuf, *event,stageMask);
3205 endCommandBuffer(vk, *primCmdBuf);
3207 // create fence to wait for execution of queue
3208 const Unique<VkFence> fence (createFence(vk, vkDevice));
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];
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();
3222 // create submit info for buffer - signal semaphores
3223 const VkSubmitInfo submitInfo1 =
3225 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
3227 0u, // waitSemaphoreCount
3228 DE_NULL, // pWaitSemaphores
3229 DE_NULL, // pWaitDstStageMask
3230 1, // commandBufferCount
3231 &primCmdBuf.get(), // pCommandBuffers
3232 numSemaphores, // signalSemaphoreCount
3233 semaphores // pSignalSemaphores
3235 // Submit the command buffer to the queue
3236 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence));
3238 // wait for end of execution of queue
3239 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT));
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");
3246 // reset event, so next buffers can set it again
3247 VK_CHECK(vk.resetEvent(vkDevice, *event));
3249 // reset fence, so it can be used again
3250 VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3253 const deUint32 numberOfSemaphoresToBeWaitedByOneSubmission = numSemaphores / numSubmissions;
3254 const std::vector<VkPipelineStageFlags> waitDstStageFlags (numberOfSemaphoresToBeWaitedByOneSubmission, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
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) {
3259 // create submit info for buffer - waiting for semaphore
3260 const VkSubmitInfo submitInfo2 =
3262 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3273 // Submit the second command buffer to the queue
3274 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence));
3276 // wait for 1 second.
3277 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 1000 * 1000 * 1000));
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");
3285 // reset fence, so it can be used again
3286 VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get()));
3288 // reset event, so next buffers can set it again
3289 VK_CHECK(vk.resetEvent(vkDevice, *event));
3292 return tcu::TestStatus::pass("Submit Buffer and Wait for Many Semaphores Test succeeded");
3295 tcu::TestStatus submitBufferNullFence(Context& context)
3297 const VkDevice vkDevice = context.getDevice();
3298 const DeviceInterface& vk = context.getDeviceInterface();
3299 const VkQueue queue = context.getUniversalQueue();
3300 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
3302 const short BUFFER_COUNT = 2;
3304 const VkCommandPoolCreateInfo cmdPoolParams =
3306 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
3309 queueFamilyIndex, // queueFamilyIndex;
3311 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
3314 const VkCommandBufferAllocateInfo cmdBufParams =
3316 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
3319 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
3322 VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3323 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3324 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffers[ndx]));
3326 const VkCommandBufferBeginInfo cmdBufBeginInfo =
3328 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3331 (const VkCommandBufferInheritanceInfo*)DE_NULL,
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))));
3338 // Record the command buffers
3339 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3341 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3343 vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3345 endCommandBuffer(vk, cmdBuffers[ndx]);
3348 // We'll use a fence to wait for the execution of the queue
3349 const Unique<VkFence> fence (createFence(vk, vkDevice));
3351 const VkSubmitInfo submitInfoNullFence =
3353 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3364 const VkSubmitInfo submitInfoNonNullFence =
3366 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
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
3380 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNullFence, DE_NULL));
3381 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNonNullFence, fence.get()));
3383 // Wait for the queue
3384 VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3387 tcu::TestStatus testResult = tcu::TestStatus::incomplete();
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)
3392 testResult = tcu::TestStatus::fail("One of the buffers was not executed.");
3396 testResult = tcu::TestStatus::pass("Buffers have been submitted and executed correctly.");
3399 vk.queueWaitIdle(queue);
3403 tcu::TestStatus submitTwoBuffersOneBufferNullWithFence(Context& context)
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;
3411 const VkCommandPoolCreateInfo cmdPoolParams =
3413 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
3415 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
3416 queueFamilyIndex, // queueFamilyIndex;
3418 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
3420 const VkCommandBufferAllocateInfo cmdBufParams =
3422 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
3425 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
3426 BUFFER_COUNT, // bufferCount;
3429 VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3430 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers));
3432 const VkCommandBufferBeginInfo cmdBufBeginInfo =
3434 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3437 (const VkCommandBufferInheritanceInfo*)DE_NULL, // pInheritanceInfo
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))));
3444 // Record the command buffers
3445 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3447 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo));
3449 vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3451 VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx]));
3454 // First command buffer
3455 const VkSubmitInfo submitInfoNonNullFirst =
3457 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3468 // Second command buffer
3469 const VkSubmitInfo submitInfoNonNullSecond =
3471 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3482 // Fence will be submitted with the null queue
3483 const Unique<VkFence> fence (createFence(vk, vkDevice));
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()));
3491 // Wait for the queue
3492 VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT));
3494 return tcu::TestStatus::pass("Buffers have been submitted correctly");
3497 /******** 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) *******/
3498 tcu::TestStatus executeSecondaryBufferTest(Context& context)
3500 const VkDevice vkDevice = context.getDevice();
3501 const DeviceInterface& vk = context.getDeviceInterface();
3502 const VkQueue queue = context.getUniversalQueue();
3503 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
3505 const VkCommandPoolCreateInfo cmdPoolParams =
3507 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
3509 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags;
3510 queueFamilyIndex, // queueFamilyIndex;
3512 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
3515 const VkCommandBufferAllocateInfo cmdBufParams =
3517 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
3519 *cmdPool, // commandPool;
3520 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level;
3523 const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3525 // Secondary Command buffer
3526 const VkCommandBufferAllocateInfo secCmdBufParams =
3528 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType;
3530 *cmdPool, // commandPool;
3531 VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level;
3534 const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams));
3536 const VkCommandBufferBeginInfo primCmdBufBeginInfo =
3538 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3541 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3544 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
3546 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3548 DE_NULL, // renderPass
3550 DE_NULL, // framebuffer
3551 VK_FALSE, // occlusionQueryEnable
3552 (VkQueryControlFlags)0u, // queryFlags
3553 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
3555 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
3557 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3560 &secCmdBufInheritInfo,
3563 // create event that will be used to check if secondary command buffer has been executed
3564 const Unique<VkEvent> event (createEvent(vk, vkDevice));
3567 VK_CHECK(vk.resetEvent(vkDevice, *event));
3569 // record secondary command buffer
3570 VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo));
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);
3577 // end recording of the secondary buffer
3578 endCommandBuffer(vk, *secCmdBuf);
3580 // record primary command buffer
3581 VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo));
3583 // execute secondary buffer
3584 vk.cmdExecuteCommands(*primCmdBuf, 1u, &secCmdBuf.get());
3586 endCommandBuffer(vk, *primCmdBuf);
3588 submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get());
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");
3595 return tcu::TestStatus::fail("executeSecondaryBufferTest FAILED");
3598 tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context)
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();
3606 const VkCommandPoolCreateInfo cmdPoolParams =
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;
3613 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams));
3616 const VkCommandBufferAllocateInfo cmdBufParams =
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;
3624 const Unique<VkCommandBuffer> primCmdBufOne (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3625 const Unique<VkCommandBuffer> primCmdBufTwo (allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
3627 // Secondary Command buffers params
3628 const VkCommandBufferAllocateInfo secCmdBufParams =
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;
3636 VkCommandBuffer cmdBuffers[BUFFER_COUNT];
3637 VK_CHECK(vk.allocateCommandBuffers(vkDevice, &secCmdBufParams, cmdBuffers));
3639 const VkCommandBufferBeginInfo primCmdBufBeginInfo =
3641 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3644 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3647 const VkCommandBufferInheritanceInfo secCmdBufInheritInfo =
3649 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
3651 (VkRenderPass)0u, // renderPass
3653 (VkFramebuffer)0u, // framebuffer
3654 VK_FALSE, // occlusionQueryEnable
3655 (VkQueryControlFlags)0u, // queryFlags
3656 (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
3658 const VkCommandBufferBeginInfo secCmdBufBeginInfo =
3660 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3662 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags
3663 &secCmdBufInheritInfo,
3666 // create event that will be used to check if secondary command buffer has been executed
3667 const Unique<VkEvent> eventOne (createEvent(vk, vkDevice));
3670 VK_CHECK(vk.resetEvent(vkDevice, *eventOne));
3672 for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx)
3674 // record secondary command buffer
3675 VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &secCmdBufBeginInfo));
3677 // allow execution of event during every stage of pipeline
3678 VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3681 vk.cmdWaitEvents(cmdBuffers[ndx], 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL);
3683 // end recording of secondary buffers
3684 endCommandBuffer(vk, cmdBuffers[ndx]);
3687 // record primary command buffer one
3688 VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo));
3690 // execute one secondary buffer
3691 vk.cmdExecuteCommands(*primCmdBufOne, 1, cmdBuffers );
3693 endCommandBuffer(vk, *primCmdBufOne);
3695 // record primary command buffer two
3696 VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo));
3698 // execute one secondary buffer with all buffers
3699 vk.cmdExecuteCommands(*primCmdBufTwo, BUFFER_COUNT, cmdBuffers );
3701 endCommandBuffer(vk, *primCmdBufTwo);
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));
3707 const VkSubmitInfo submitInfoOne =
3709 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3720 // submit primary buffer, the secondary should be executed too
3721 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoOne, *fenceOne));
3723 // wait for buffer to stop at event for 100 microseconds
3724 vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
3726 const VkSubmitInfo submitInfoTwo =
3728 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
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
3739 // submit second primary buffer, the secondary should be executed too
3740 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoTwo, *fenceTwo));
3742 // wait for all buffers to stop at event for 100 microseconds
3743 vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000);
3745 // now all buffers are waiting at eventOne
3746 // set event eventOne
3747 VK_CHECK(vk.setEvent(vkDevice, *eventOne));
3749 // wait for end of execution of fenceOne
3750 VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, INFINITE_TIMEOUT));
3752 // wait for end of execution of second queue
3753 VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceTwo.get(), 0u, INFINITE_TIMEOUT));
3755 return tcu::TestStatus::pass("executeSecondaryBufferTwiceTest succeeded");
3758 /******** 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) **/
3759 tcu::TestStatus orderBindPipelineTest(Context& context)
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);
3770 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
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);
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;
3785 de::MovePtr<Allocation> bufferMemA;
3786 const Unique<VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA, context));
3788 de::MovePtr<Allocation> bufferMemB;
3789 const Unique<VkBuffer> bufferB (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB, context));
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);
3797 const VkPipelineLayoutCreateInfo layoutCreateInfo =
3799 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
3801 (VkPipelineLayoutCreateFlags)0,
3802 numDescriptorSets, // setLayoutCount
3803 &descriptorSetLayout.get(), // pSetLayouts
3804 0u, // pushConstantRangeCount
3805 DE_NULL, // pPushConstantRanges
3807 Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, device, &layoutCreateInfo));
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));
3812 const VkPipelineShaderStageCreateInfo shaderCreateInfoGood =
3814 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3816 (VkPipelineShaderStageCreateFlags)0,
3817 VK_SHADER_STAGE_COMPUTE_BIT, // stage
3818 *computeModuleGood, // shader
3820 DE_NULL, // pSpecializationInfo
3823 const VkPipelineShaderStageCreateInfo shaderCreateInfoBad =
3825 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3827 (vk::VkPipelineShaderStageCreateFlags)0,
3828 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
3829 *computeModuleBad, // shader
3831 DE_NULL, // pSpecializationInfo
3834 const VkComputePipelineCreateInfo createInfoGood =
3836 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3839 shaderCreateInfoGood, // cs
3840 *pipelineLayout, // layout
3841 (vk::VkPipeline)0, // basePipelineHandle
3842 0u, // basePipelineIndex
3845 const VkComputePipelineCreateInfo createInfoBad =
3847 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3850 shaderCreateInfoBad, // cs
3851 *pipelineLayout, // descriptorSetLayout.get()
3852 (VkPipeline)0, // basePipelineHandle
3853 0u, // basePipelineIndex
3856 const Unique<VkPipeline> pipelineGood (createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoGood));
3857 const Unique<VkPipeline> pipelineBad (createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoBad));
3859 const VkAccessFlags inputBit = (VK_ACCESS_UNIFORM_READ_BIT);
3860 const VkBufferMemoryBarrier bufferBarriers[] =
3863 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3865 VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
3866 inputBit, // dstAccessMask
3867 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3868 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3870 (VkDeviceSize)0u, // offset
3871 (VkDeviceSize)bufferSizeA, // size
3874 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3876 VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
3877 inputBit, // dstAccessMask
3878 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3879 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3881 (VkDeviceSize)0u, // offset
3882 (VkDeviceSize)bufferSizeB, // size
3886 const deUint32 numSrcBuffers = 1u;
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] =
3902 tcu::Vec4 results[4];
3904 // submit and wait begin
3906 const tcu::UVec3 numWorkGroups = tcu::UVec3(4, 1u, 1);
3908 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
3910 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType;
3912 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3913 queueFamilyIndex, // queueFamilyIndex
3915 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo));
3916 const VkCommandBufferAllocateInfo cmdBufCreateInfo =
3918 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
3920 *cmdPool, // commandPool
3921 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3925 const VkCommandBufferBeginInfo cmdBufBeginInfo =
3927 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
3930 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3933 const Unique<VkCommandBuffer> cmd (allocateCommandBuffer(vk, device, &cmdBufCreateInfo));
3935 VK_CHECK(vk.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
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);
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);
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);
3955 // submit second primary buffer, the secondary should be executed too
3956 submitCommandsAndWait(vk, device, queue, cmd.get());
3958 // submit and wait end
3959 result.readResultContentsTo(&results);
3962 if (results[0] == references[0] &&
3963 results[1] == references[1] &&
3964 results[2] == references[2] &&
3965 results[3] == references[3])
3967 return tcu::TestStatus::pass("Pass");
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))
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");
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");
3998 enum StateTransitionTest
4000 STT_RECORDING_TO_INITIAL = 0,
4001 STT_EXECUTABLE_TO_INITIAL,
4002 STT_RECORDING_TO_INVALID,
4003 STT_EXECUTABLE_TO_INVALID,
4006 tcu::TestStatus executeStateTransitionTest(Context& context, StateTransitionTest type)
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));
4016 VK_CHECK(vk.resetEvent(vkDevice, *globalEvent));
4020 case STT_RECORDING_TO_INITIAL:
4022 beginCommandBuffer(vk, *cmdBuffer, 0u);
4023 vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4025 // command buffer is still in recording state
4027 case STT_EXECUTABLE_TO_INITIAL:
4029 beginCommandBuffer(vk, *cmdBuffer, 0u);
4030 vk.cmdSetEvent(*cmdBuffer, *globalEvent, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4031 endCommandBuffer(vk, *cmdBuffer);
4033 // command buffer is still in executable state
4035 case STT_RECORDING_TO_INVALID:
4037 VkSubpassDescription subpassDescription;
4038 deMemset(&subpassDescription, 0, sizeof(VkSubpassDescription));
4039 subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4041 VkRenderPassCreateInfo renderPassCreateInfo
4043 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
4044 DE_NULL, 0, 0, DE_NULL,
4045 1, &subpassDescription, 0, DE_NULL
4048 // Error here - renderpass and framebuffer were created localy
4049 Move <VkRenderPass> renderPass = createRenderPass(vk, vkDevice, &renderPassCreateInfo);
4051 VkFramebufferCreateInfo framebufferCreateInfo
4053 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, DE_NULL,
4054 0, *renderPass, 0, DE_NULL, 16, 16, 1
4056 Move <VkFramebuffer> framebuffer = createFramebuffer(vk, vkDevice, &framebufferCreateInfo);
4058 VkRenderPassBeginInfo renderPassBeginInfo =
4060 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4061 DE_NULL, *renderPass, *framebuffer, { { 0, 0 }, { 16, 16 } },
4065 beginCommandBuffer(vk, *cmdBuffer, 0u);
4066 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
4067 vk.cmdEndRenderPass(*cmdBuffer);
4069 // not executing endCommandBuffer(vk, *cmdBuffer);
4070 // command buffer is still in recording state
4072 // renderpass and framebuffer are destroyed; command buffer should be now in invalid state
4074 case STT_EXECUTABLE_TO_INVALID:
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));
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
4085 // localEvent is destroyed; command buffer should be now in invalid state
4089 VK_CHECK(vk.resetEvent(vkDevice, *globalEvent));
4091 vk.resetCommandBuffer(*cmdBuffer, 0u);
4092 // command buffer should now be back in initial state
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);
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");
4105 return tcu::TestStatus::pass("Pass");
4109 void genComputeSource (SourceCollections& programCollection)
4111 const char* const versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4112 std::ostringstream bufGood;
4114 bufGood << versionDecl << "\n"
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"
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"
4124 << " highp vec4 read_colors[4];\n"
4126 << "void main(void)\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"
4133 << " result_color = b_instance.colorB;\n"
4134 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
4137 programCollection.glslSources.add("compute_good") << glu::ComputeSource(bufGood.str());
4139 std::ostringstream bufBad;
4141 bufBad << versionDecl << "\n"
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"
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"
4151 << " highp vec4 read_colors[4];\n"
4153 << "void main(void)\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"
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"
4164 programCollection.glslSources.add("compute_bad") << glu::ComputeSource(bufBad.str());
4167 void genComputeIncrementSource (SourceCollections& programCollection)
4169 const char* const versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
4170 std::ostringstream bufIncrement;
4172 bufIncrement << versionDecl << "\n"
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"
4177 << " coherent uint count;\n"
4179 << "void main(void)\n"
4181 << " atomicAdd(b_in_out.count, 1u);\n"
4184 programCollection.glslSources.add("compute_increment") << glu::ComputeSource(bufIncrement.str());
4187 void genComputeIncrementSourceBadInheritance(SourceCollections& programCollection, BadInheritanceInfoCase testCase)
4190 return genComputeIncrementSource(programCollection);
4193 void checkEventSupport (Context& context)
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");
4200 #endif // CTS_USES_VULKANSC
4203 void checkCommandBufferSimultaneousUseSupport(Context& context)
4205 #ifdef CTS_USES_VULKANSC
4206 if(context.getDeviceVulkanSC10Properties().commandBufferSimultaneousUse == VK_FALSE)
4207 TCU_THROW(NotSupportedError, "commandBufferSimultaneousUse is not supported");
4210 #endif // CTS_USES_VULKANSC
4213 void checkSecondaryCommandBufferNullOrImagelessFramebufferSupport(Context& context)
4215 #ifdef CTS_USES_VULKANSC
4216 if (context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
4217 TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
4220 #endif // CTS_USES_VULKANSC
4223 void checkSecondaryCommandBufferNullOrImagelessFramebufferSupport1(Context& context, bool value)
4226 #ifdef CTS_USES_VULKANSC
4227 if (context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
4228 TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
4231 #endif // CTS_USES_VULKANSC
4234 void checkEventAndCommandBufferSimultaneousUseSupport(Context& context)
4236 checkEventSupport(context);
4237 checkCommandBufferSimultaneousUseSupport(context);
4240 void checkEventAndSecondaryCommandBufferNullFramebufferSupport(Context& context)
4242 checkEventSupport(context);
4243 checkSecondaryCommandBufferNullOrImagelessFramebufferSupport(context);
4246 void checkSimultaneousUseAndSecondaryCommandBufferNullFramebufferSupport(Context& context)
4248 checkCommandBufferSimultaneousUseSupport(context);
4249 checkSecondaryCommandBufferNullOrImagelessFramebufferSupport(context);
4252 void checkEventAndSimultaneousUseAndSecondaryCommandBufferNullFramebufferSupport(Context& context)
4254 checkEventSupport(context);
4255 checkCommandBufferSimultaneousUseSupport(context);
4256 checkSecondaryCommandBufferNullOrImagelessFramebufferSupport(context);
4259 #ifndef CTS_USES_VULKANSC
4260 void checkEventSupport (Context& context, const VkCommandBufferLevel)
4262 checkEventSupport(context);
4264 #endif // CTS_USES_VULKANSC
4266 struct ManyDrawsParams
4268 VkCommandBufferLevel level;
4269 VkExtent3D imageExtent;
4272 ManyDrawsParams(VkCommandBufferLevel level_, const VkExtent3D& extent_, deUint32 seed_)
4274 , imageExtent (extent_)
4279 struct ManyDrawsVertex
4281 using Color = tcu::Vector<deUint8, 4>;
4286 ManyDrawsVertex (const tcu::Vec2& coords_, const Color& color_) : coords(coords_), color(color_) {}
4289 VkFormat getSupportedDepthStencilFormat (const InstanceInterface& vki, VkPhysicalDevice physDev)
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);
4294 for (int i = 0; i < DE_LENGTH_OF_ARRAY(formatList); ++i)
4296 const auto properties = getPhysicalDeviceFormatProperties(vki, physDev, formatList[i]);
4297 if ((properties.optimalTilingFeatures & requirements) == requirements)
4298 return formatList[i];
4301 TCU_THROW(NotSupportedError, "No suitable depth/stencil format support");
4302 return VK_FORMAT_UNDEFINED;
4305 class ManyDrawsCase : public TestCase
4308 ManyDrawsCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const ManyDrawsParams& params);
4309 virtual ~ManyDrawsCase (void) {}
4311 virtual void checkSupport (Context& context) const;
4312 virtual void initPrograms (vk::SourceCollections& programCollection) const;
4313 virtual TestInstance* createInstance (Context& context) const;
4315 static VkFormat getColorFormat (void) { return VK_FORMAT_R8G8B8A8_UINT; }
4318 ManyDrawsParams m_params;
4321 class ManyDrawsInstance : public TestInstance
4324 ManyDrawsInstance (Context& context, const ManyDrawsParams& params);
4325 virtual ~ManyDrawsInstance (void) {}
4327 virtual tcu::TestStatus iterate (void);
4330 ManyDrawsParams m_params;
4333 using BufferPtr = de::MovePtr<BufferWithMemory>;
4334 using ImagePtr = de::MovePtr<ImageWithMemory>;
4336 struct ManyDrawsVertexBuffers
4338 BufferPtr stagingBuffer;
4339 BufferPtr vertexBuffer;
4342 struct ManyDrawsAllocatedData
4344 ManyDrawsVertexBuffers frontBuffers;
4345 ManyDrawsVertexBuffers backBuffers;
4346 ImagePtr colorAttachment;
4347 ImagePtr dsAttachment;
4348 BufferPtr colorCheckBuffer;
4349 BufferPtr stencilCheckBuffer;
4351 static deUint32 calcNumPixels (const VkExtent3D& extent)
4353 DE_ASSERT(extent.depth == 1u);
4354 return (extent.width * extent.height);
4356 static deUint32 calcNumVertices (const VkExtent3D& extent)
4358 // One triangle (3 vertices) per output image pixel.
4359 return (calcNumPixels(extent) * 3u);
4362 static VkDeviceSize calcVertexBufferSize (const VkExtent3D& extent)
4364 return calcNumVertices(extent) * sizeof(ManyDrawsVertex);
4367 static void makeVertexBuffers (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkDeviceSize size, ManyDrawsVertexBuffers& buffers)
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));
4372 buffers.stagingBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, stagingBufferInfo, MemoryRequirement::HostVisible));
4373 buffers.vertexBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::Any));
4376 ManyDrawsAllocatedData (const DeviceInterface &vkd, VkDevice device, Allocator &alloc, const VkExtent3D& imageExtent, VkFormat colorFormat, VkFormat dsFormat)
4378 const auto numPixels = calcNumPixels(imageExtent);
4379 const auto vertexBufferSize = calcVertexBufferSize(imageExtent);
4381 makeVertexBuffers(vkd, device, alloc, vertexBufferSize, frontBuffers);
4382 makeVertexBuffers(vkd, device, alloc, vertexBufferSize, backBuffers);
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;
4387 const VkImageCreateInfo colorAttachmentInfo =
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;
4405 colorAttachment = ImagePtr(new ImageWithMemory(vkd, device, alloc, colorAttachmentInfo, MemoryRequirement::Any));
4407 const VkImageCreateInfo dsAttachmentInfo =
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;
4425 dsAttachment = ImagePtr(new ImageWithMemory(vkd, device, alloc, dsAttachmentInfo, MemoryRequirement::Any));
4427 const auto colorCheckBufferSize = static_cast<VkDeviceSize>(numPixels * tcu::getPixelSize(mapVkFormat(colorFormat)));
4428 const auto colorCheckBufferInfo = makeBufferCreateInfo(colorCheckBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
4430 colorCheckBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, colorCheckBufferInfo, MemoryRequirement::HostVisible));
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);
4436 stencilCheckBuffer = BufferPtr(new BufferWithMemory(vkd, device, alloc, stencilCheckBufferInfo, MemoryRequirement::HostVisible));
4440 ManyDrawsCase::ManyDrawsCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const ManyDrawsParams& params)
4441 : TestCase (testCtx, name, description)
4445 void ManyDrawsCase::checkSupport (Context& context) const
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);
4456 ManyDrawsAllocatedData allocatedData(vkd, device, alloc, m_params.imageExtent, getColorFormat(), dsFormat);
4458 catch (const vk::Error& err)
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");
4467 void ManyDrawsCase::initPrograms (vk::SourceCollections& programCollection) const
4469 std::ostringstream vert;
4473 << "layout(location=0) in vec2 inCoords;\n"
4474 << "layout(location=1) in uvec4 inColor;\n"
4476 << "layout(location=0) out flat uvec4 outColor;\n"
4480 << " gl_Position = vec4(inCoords, 0.0, 1.0);\n"
4481 << " outColor = inColor;\n"
4485 std::ostringstream frag;
4489 << "layout(location=0) in flat uvec4 inColor;\n"
4490 << "layout(location=0) out uvec4 outColor;\n"
4494 << " outColor = inColor;\n"
4498 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
4499 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
4502 TestInstance* ManyDrawsCase::createInstance (Context& context) const
4504 return new ManyDrawsInstance(context, m_params);
4507 ManyDrawsInstance::ManyDrawsInstance (Context& context, const ManyDrawsParams& params)
4508 : TestInstance (context)
4512 void copyAndFlush (const DeviceInterface& vkd, VkDevice device, BufferWithMemory& buffer, const std::vector<ManyDrawsVertex>& vertices)
4514 auto& alloc = buffer.getAllocation();
4515 void* hostPtr = alloc.getHostPtr();
4517 deMemcpy(hostPtr, vertices.data(), de::dataSize(vertices));
4518 flushAlloc(vkd, device, alloc);
4521 tcu::TestStatus ManyDrawsInstance::iterate (void)
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();
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);
4543 // Allocate all needed data up front.
4544 ManyDrawsAllocatedData testData(vkd, device, alloc, m_params.imageExtent, colorFormat, dsFormat);
4546 // Generate random colors.
4547 de::Random rnd(m_params.seed);
4548 std::vector<ManyDrawsVertex::Color> colors;
4550 colors.reserve(numPixels);
4551 for (deUint32 i = 0; i < numPixels; ++i)
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));
4559 colors.push_back(ManyDrawsVertex::Color(rnd.getUint8(), rnd.getUint8(), rnd.getUint8(), alphaValue));
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);
4569 for (deUint32 y = 0; y < m_params.imageExtent.height; ++y)
4570 for (deUint32 x = 0; x < m_params.imageExtent.width; ++x)
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;
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];
4583 const tcu::Vec2 triangle[3u] =
4585 tcu::Vec2(x_left, y_top),
4586 tcu::Vec2(x_right, y_top),
4587 tcu::Vec2(x_mid, y_bottom),
4590 frontVector.emplace_back(triangle[0], frontColor);
4591 frontVector.emplace_back(triangle[1], frontColor);
4592 frontVector.emplace_back(triangle[2], frontColor);
4594 backVector.emplace_back(triangle[0], backColor);
4595 backVector.emplace_back(triangle[1], backColor);
4596 backVector.emplace_back(triangle[2], backColor);
4599 // Copy vertex data to staging buffers.
4600 copyAndFlush(vkd, device, *testData.frontBuffers.stagingBuffer, frontVector);
4601 copyAndFlush(vkd, device, *testData.backBuffers.stagingBuffer, backVector);
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);
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);
4611 const VkImageView attachmentArray[] = { colorAttachmentView.get(), dsAttachmentView.get() };
4612 const auto numAttachments = static_cast<deUint32>(DE_LENGTH_OF_ARRAY(attachmentArray));
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);
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);
4620 const std::vector<VkViewport> viewports (1u, makeViewport(m_params.imageExtent));
4621 const std::vector<VkRect2D> scissors (1u, makeRect2D(m_params.imageExtent));
4623 const auto descriptorSetLayout = DescriptorSetLayoutBuilder().build(vkd, device);
4624 const auto pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
4626 const VkVertexInputBindingDescription bindings[] =
4628 makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(ManyDrawsVertex)), VK_VERTEX_INPUT_RATE_VERTEX),
4631 const VkVertexInputAttributeDescription attributes[] =
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))),
4637 const VkPipelineVertexInputStateCreateInfo inputState =
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;
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.
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);
4658 const VkPipelineDepthStencilStateCreateInfo dsState =
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
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);
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);
4684 CmdBufferPtr primaryCmdBufferPtr;
4685 CmdBufferPtr secondaryCmdBufferPtr;
4686 VkCommandBuffer primaryCmdBuffer;
4687 VkCommandBuffer secondaryCmdBuffer;
4688 VkCommandBuffer drawsCmdBuffer;
4690 primaryCmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4691 primaryCmdBuffer = primaryCmdBufferPtr.get();
4692 drawsCmdBuffer = primaryCmdBuffer;
4693 beginCommandBuffer(vkd, primaryCmdBuffer);
4696 std::vector<VkClearValue> clearValues(2u);
4697 clearValues[0] = makeClearValueColorU32(0u, 0u, 0u, 0u);
4698 clearValues[1] = makeClearValueDepthStencil(1.0f, 0u);
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, ©Region);
4703 vkd.cmdCopyBuffer(primaryCmdBuffer, testData.backBuffers.stagingBuffer->get(), testData.backBuffers.vertexBuffer->get(), 1u, ©Region);
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);
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);
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));
4719 secondaryCmdBufferPtr = allocateCommandBuffer(vkd, device, secCmdPool.get(), VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4720 secondaryCmdBuffer = secondaryCmdBufferPtr.get();
4721 drawsCmdBuffer = secondaryCmdBuffer;
4723 const VkCommandBufferInheritanceInfo inheritanceInfo =
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;
4735 const VkCommandBufferUsageFlags usageFlags = (VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
4736 const VkCommandBufferBeginInfo beginInfo =
4738 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4740 usageFlags, // VkCommandBufferUsageFlags flags;
4741 &inheritanceInfo, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
4744 VK_CHECK(vkd.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
4748 vkd.cmdBindPipeline(drawsCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
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);
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);
4762 endCommandBuffer(vkd, secondaryCmdBuffer);
4763 vkd.cmdExecuteCommands(primaryCmdBuffer, 1u, &secondaryCmdBuffer);
4766 endRenderPass(vkd, primaryCmdBuffer);
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);
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);
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);
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);
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);
4786 endCommandBuffer(vkd, primaryCmdBuffer);
4787 submitCommandsAndWait(vkd, device, queue, primaryCmdBuffer);
4789 // Check buffer contents.
4790 auto& colorCheckBufferAlloc = testData.colorCheckBuffer->getAllocation();
4791 void* colorCheckBufferData = colorCheckBufferAlloc.getHostPtr();
4792 invalidateAlloc(vkd, device, colorCheckBufferAlloc);
4794 auto& stencilCheckBufferAlloc = testData.stencilCheckBuffer->getAllocation();
4795 void* stencilCheckBufferData = stencilCheckBufferAlloc.getHostPtr();
4796 invalidateAlloc(vkd, device, stencilCheckBufferAlloc);
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);
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;
4817 for (int y = 0; y < iHeight; ++y)
4818 for (int x = 0; x < iWidth; ++x)
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);
4825 const auto stencilValue = stencilAccess.getPixStencil(x, y);
4826 const bool stencilMismatch = (stencilValue != expectedStencil);
4828 referenceAccess.setPixel(expectedValue, x, y);
4829 colorErrorAccess.setPixel((colorMismatch ? red : green), x, y);
4830 stencilErrorAccess.setPixel((stencilMismatch ? red : green), x, y);
4832 if (stencilMismatch)
4839 if (colorFail || stencilFail)
4841 auto& log = m_context.getTestContext().getLog();
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
4850 TCU_FAIL("Mismatched output and reference color or stencil; please check test log --");
4853 return tcu::TestStatus::pass("Pass");
4858 tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx)
4860 de::MovePtr<tcu::TestCaseGroup> commandBuffersTests (new tcu::TestCaseGroup(testCtx, "command_buffers", "Command Buffers Tests"));
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);
4895 deUint32 seed = 1614182419u;
4896 const auto smallExtent = makeExtent3D(128u, 128u, 1u);
4897 const auto largeExtent = makeExtent3D(512u, 512u, 1u);
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++)));
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);
4940 return commandBuffersTests.release();