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