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