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