1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 The Khronos Group Inc.
6 * Copyright (c) 2018 Danylo Piliaiev <danylo.piliaiev@gmail.com>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Test for conditional rendering of vkCmdDispatch* functions
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktConditionalDispatchTests.hpp"
26 #include "vktConditionalRenderingTestUtil.hpp"
27
28 #include "tcuTestLog.hpp"
29 #include "tcuResource.hpp"
30
31 #include "vkDefs.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkBufferWithMemory.hpp"
37
38 namespace vkt
39 {
40 namespace conditional
41 {
42 namespace
43 {
44
45 enum DispatchCommandType
46 {
47 DISPATCH_COMMAND_TYPE_DISPATCH = 0,
48 DISPATCH_COMMAND_TYPE_DISPATCH_INDIRECT,
49 DISPATCH_COMMAND_TYPE_DISPATCH_BASE,
50 DISPATCH_COMMAND_TYPE_DISPATCH_LAST
51 };
52
getDispatchCommandTypeName(DispatchCommandType command)53 const char* getDispatchCommandTypeName (DispatchCommandType command)
54 {
55 switch (command)
56 {
57 case DISPATCH_COMMAND_TYPE_DISPATCH: return "dispatch";
58 case DISPATCH_COMMAND_TYPE_DISPATCH_INDIRECT: return "dispatch_indirect";
59 case DISPATCH_COMMAND_TYPE_DISPATCH_BASE: return "dispatch_base";
60 default: DE_ASSERT(false);
61 }
62 return "";
63 }
64
65 struct ConditionalTestSpec
66 {
67 DispatchCommandType command;
68 int numCalls;
69 ConditionalData conditionalData;
70 };
71
72 class ConditionalDispatchTest : public vkt::TestCase
73 {
74 public:
75 ConditionalDispatchTest (tcu::TestContext& testCtx,
76 const std::string& name,
77 const std::string& description,
78 const ConditionalTestSpec& testSpec);
79
80 void initPrograms (vk::SourceCollections& sourceCollections) const;
81 void checkSupport (Context& context) const;
82 TestInstance* createInstance (Context& context) const;
83
84 private:
85 const ConditionalTestSpec m_testSpec;
86 };
87
88 class ConditionalDispatchTestInstance : public TestInstance
89 {
90 public:
91 ConditionalDispatchTestInstance (Context &context, ConditionalTestSpec testSpec);
92
93 virtual tcu::TestStatus iterate (void);
94 void recordDispatch (const vk::DeviceInterface& vk,
95 vk::VkCommandBuffer cmdBuffer,
96 vk::BufferWithMemory& indirectBuffer);
97
98 protected:
99 const DispatchCommandType m_command;
100 const int m_numCalls;
101 const ConditionalData m_conditionalData;
102 };
103
ConditionalDispatchTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const ConditionalTestSpec & testSpec)104 ConditionalDispatchTest::ConditionalDispatchTest(tcu::TestContext& testCtx,
105 const std::string& name,
106 const std::string& description,
107 const ConditionalTestSpec& testSpec)
108 : TestCase (testCtx, name, description)
109 , m_testSpec (testSpec)
110 {
111 }
112
initPrograms(vk::SourceCollections & sourceCollections) const113 void ConditionalDispatchTest::initPrograms (vk::SourceCollections& sourceCollections) const
114 {
115 std::ostringstream src;
116 src << "#version 310 es\n"
117 << "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1u) in;\n"
118 << "layout(set = 0, binding = 0, std140) buffer Out\n"
119 << "{\n"
120 << " coherent uint count;\n"
121 << "};\n"
122 << "void main(void)\n"
123 << "{\n"
124 << " atomicAdd(count, 1u);\n"
125 << "}\n";
126
127 sourceCollections.glslSources.add("comp") << glu::ComputeSource(src.str());
128 }
129
checkSupport(Context & context) const130 void ConditionalDispatchTest::checkSupport(Context& context) const
131 {
132 checkConditionalRenderingCapabilities(context, m_testSpec.conditionalData);
133
134 if (m_testSpec.command == DISPATCH_COMMAND_TYPE_DISPATCH_BASE)
135 context.requireDeviceFunctionality("VK_KHR_device_group");
136 }
137
createInstance(Context & context) const138 TestInstance* ConditionalDispatchTest::createInstance (Context& context) const
139 {
140 return new ConditionalDispatchTestInstance(context, m_testSpec);
141 }
142
ConditionalDispatchTestInstance(Context & context,ConditionalTestSpec testSpec)143 ConditionalDispatchTestInstance::ConditionalDispatchTestInstance (Context &context, ConditionalTestSpec testSpec)
144 : TestInstance(context)
145 , m_command(testSpec.command)
146 , m_numCalls(testSpec.numCalls)
147 , m_conditionalData(testSpec.conditionalData)
148 {
149 }
150
recordDispatch(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::BufferWithMemory & indirectBuffer)151 void ConditionalDispatchTestInstance::recordDispatch (const vk::DeviceInterface& vk,
152 vk::VkCommandBuffer cmdBuffer,
153 vk::BufferWithMemory& indirectBuffer)
154 {
155 for (int i = 0; i < m_numCalls; i++)
156 {
157 switch (m_command)
158 {
159 case DISPATCH_COMMAND_TYPE_DISPATCH:
160 {
161 vk.cmdDispatch(cmdBuffer, 1, 1, 1);
162 break;
163 }
164 case DISPATCH_COMMAND_TYPE_DISPATCH_INDIRECT:
165 {
166 vk.cmdDispatchIndirect(cmdBuffer, *indirectBuffer, 0);
167 break;
168 }
169 case DISPATCH_COMMAND_TYPE_DISPATCH_BASE:
170 {
171 vk.cmdDispatchBase(cmdBuffer, 0, 0, 0, 1, 1, 1);
172 break;
173 }
174 default: DE_ASSERT(DE_FALSE);
175 }
176 }
177 }
178
iterate(void)179 tcu::TestStatus ConditionalDispatchTestInstance::iterate (void)
180 {
181 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
182 const vk::VkDevice device = m_context.getDevice();
183 const vk::VkQueue queue = m_context.getUniversalQueue();
184 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
185 vk::Allocator& allocator = m_context.getDefaultAllocator();
186
187 // Create a buffer and host-visible memory for it
188
189 const vk::VkDeviceSize bufferSizeBytes = sizeof(deUint32);
190 const vk::BufferWithMemory outputBuffer(vk, device, allocator, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
191
192 {
193 const vk::Allocation& alloc = outputBuffer.getAllocation();
194 deUint8* outputBufferPtr = reinterpret_cast<deUint8*>(alloc.getHostPtr());
195 *(deUint32*)(outputBufferPtr) = 0;
196 vk::flushAlloc(vk, device, alloc);
197 }
198
199 // Create descriptor set
200
201 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
202 vk::DescriptorSetLayoutBuilder()
203 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
204 .build(vk, device));
205
206 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
207 vk::DescriptorPoolBuilder()
208 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
209 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
210
211 const vk::Unique<vk::VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
212
213 const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
214 vk::DescriptorSetUpdateBuilder()
215 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
216 .update(vk, device);
217
218 // Setup pipeline
219
220 const vk::Unique<vk::VkShaderModule> shaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0u));
221 const vk::Unique<vk::VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
222 const vk::Unique<vk::VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
223
224 const vk::Unique<vk::VkCommandPool> cmdPool (makeCommandPool(vk, device, queueFamilyIndex));
225 const vk::Unique<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
226 const vk::Unique<vk::VkCommandBuffer> secondaryCmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
227
228 // Create indirect buffer
229 const vk::VkDispatchIndirectCommand dispatchCommands[] = { { 1u, 1u, 1u } };
230
231 vk::BufferWithMemory indirectBuffer(
232 vk, device, allocator,
233 vk::makeBufferCreateInfo(sizeof(dispatchCommands), vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
234 vk::MemoryRequirement::HostVisible);
235
236 deUint8* indirectBufferPtr = reinterpret_cast<deUint8*>(indirectBuffer.getAllocation().getHostPtr());
237 deMemcpy(indirectBufferPtr, &dispatchCommands[0], sizeof(dispatchCommands));
238
239 vk::flushAlloc(vk, device, indirectBuffer.getAllocation());
240
241 // Start recording commands
242
243 beginCommandBuffer(vk, *cmdBuffer);
244
245 vk::VkCommandBuffer targetCmdBuffer = *cmdBuffer;
246
247 const bool useSecondaryCmdBuffer = m_conditionalData.conditionInherited || m_conditionalData.conditionInSecondaryCommandBuffer;
248
249 if (useSecondaryCmdBuffer)
250 {
251 const vk::VkCommandBufferInheritanceConditionalRenderingInfoEXT conditionalRenderingInheritanceInfo =
252 {
253 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
254 DE_NULL,
255 m_conditionalData.conditionInherited ? VK_TRUE : VK_FALSE // conditionalRenderingEnable
256 };
257
258 const vk::VkCommandBufferInheritanceInfo inheritanceInfo =
259 {
260 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
261 &conditionalRenderingInheritanceInfo,
262 0u, // renderPass
263 0u, // subpass
264 0u, // framebuffer
265 VK_FALSE, // occlusionQueryEnable
266 (vk::VkQueryControlFlags)0u, // queryFlags
267 (vk::VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
268 };
269
270 const vk::VkCommandBufferBeginInfo commandBufferBeginInfo =
271 {
272 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
273 DE_NULL,
274 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
275 &inheritanceInfo
276 };
277
278 VK_CHECK(vk.beginCommandBuffer(*secondaryCmdBuffer, &commandBufferBeginInfo));
279
280 targetCmdBuffer = *secondaryCmdBuffer;
281 }
282
283 vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
284 vk.cmdBindDescriptorSets(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
285
286 de::SharedPtr<Draw::Buffer> conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
287
288 if (m_conditionalData.conditionInSecondaryCommandBuffer)
289 {
290 beginConditionalRendering(vk, *secondaryCmdBuffer, *conditionalBuffer, m_conditionalData);
291 recordDispatch(vk, *secondaryCmdBuffer, indirectBuffer);
292 vk.cmdEndConditionalRenderingEXT(*secondaryCmdBuffer);
293 vk.endCommandBuffer(*secondaryCmdBuffer);
294 }
295 else if (m_conditionalData.conditionInherited)
296 {
297 recordDispatch(vk, *secondaryCmdBuffer, indirectBuffer);
298 vk.endCommandBuffer(*secondaryCmdBuffer);
299 }
300
301 if (m_conditionalData.conditionInPrimaryCommandBuffer)
302 {
303 beginConditionalRendering(vk, *cmdBuffer, *conditionalBuffer, m_conditionalData);
304
305 if (m_conditionalData.conditionInherited)
306 {
307 vk.cmdExecuteCommands(*cmdBuffer, 1, &secondaryCmdBuffer.get());
308 }
309 else
310 {
311 recordDispatch(vk, *cmdBuffer, indirectBuffer);
312 }
313
314 vk.cmdEndConditionalRenderingEXT(*cmdBuffer);
315 }
316 else if (useSecondaryCmdBuffer)
317 {
318 vk.cmdExecuteCommands(*cmdBuffer, 1, &secondaryCmdBuffer.get());
319 }
320
321 const vk::VkBufferMemoryBarrier outputBufferMemoryBarrier =
322 {
323 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
324 DE_NULL,
325 vk::VK_ACCESS_SHADER_WRITE_BIT,
326 vk::VK_ACCESS_HOST_READ_BIT,
327 VK_QUEUE_FAMILY_IGNORED,
328 VK_QUEUE_FAMILY_IGNORED,
329 outputBuffer.get(),
330 0u,
331 VK_WHOLE_SIZE
332 };
333
334 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &outputBufferMemoryBarrier, 0u, DE_NULL);
335
336 endCommandBuffer(vk, *cmdBuffer);
337
338 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
339
340 // Check result
341
342 qpTestResult res = QP_TEST_RESULT_PASS;
343
344 const vk::Allocation& outputBufferAllocation = outputBuffer.getAllocation();
345 invalidateAlloc(vk, device, outputBufferAllocation);
346
347 const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
348
349 const deUint32 expectedResult = m_conditionalData.expectCommandExecution ? m_numCalls : 0u;
350 if (bufferPtr[0] != expectedResult)
351 {
352 res = QP_TEST_RESULT_FAIL;
353 }
354
355 return tcu::TestStatus(res, qpGetTestResultName(res));
356 }
357
358 } // anonymous
359
ConditionalDispatchTests(tcu::TestContext & testCtx)360 ConditionalDispatchTests::ConditionalDispatchTests (tcu::TestContext &testCtx)
361 : TestCaseGroup (testCtx, "dispatch", "Conditional Rendering Of Dispatch Commands")
362 {
363 /* Left blank on purpose */
364 }
365
~ConditionalDispatchTests(void)366 ConditionalDispatchTests::~ConditionalDispatchTests (void) {}
367
init(void)368 void ConditionalDispatchTests::init (void)
369 {
370 for (int conditionNdx = 0; conditionNdx < DE_LENGTH_OF_ARRAY(conditional::s_testsData); conditionNdx++)
371 {
372 const ConditionalData& conditionData = conditional::s_testsData[conditionNdx];
373
374 if (conditionData.clearInRenderPass)
375 continue;
376
377 de::MovePtr<tcu::TestCaseGroup> conditionalDrawRootGroup(new tcu::TestCaseGroup(m_testCtx, de::toString(conditionData).c_str(), "Conditionaly execute dispatch calls"));
378
379 for (deUint32 commandTypeIdx = 0; commandTypeIdx < DISPATCH_COMMAND_TYPE_DISPATCH_LAST; ++commandTypeIdx)
380 {
381 const DispatchCommandType command = DispatchCommandType(commandTypeIdx);
382
383 ConditionalTestSpec testSpec;
384 testSpec.command = command;
385 testSpec.numCalls = 3;
386 testSpec.conditionalData = conditionData;
387
388 conditionalDrawRootGroup->addChild(new ConditionalDispatchTest(m_testCtx, getDispatchCommandTypeName(command), "", testSpec));
389 }
390
391 addChild(conditionalDrawRootGroup.release());
392 }
393
394 enum class ConditionLocation
395 {
396 PRIMARY_FLAT = 0,
397 PRIMARY_WITH_SECONDARY,
398 SECONDARY_NORMAL,
399 SECONDARY_INHERITED,
400 };
401
402 // Tests verifying the condition is interpreted as a 32-bit value.
403 {
404 de::MovePtr<tcu::TestCaseGroup> conditionSizeGroup(new tcu::TestCaseGroup(m_testCtx, "condition_size", "Tests verifying the condition is being read as a 32-bit value"));
405
406 struct ValuePaddingExecution
407 {
408 deUint32 value;
409 bool padding;
410 bool execution;
411 const char* name;
412 };
413
414 const ValuePaddingExecution kConditionValueResults[] =
415 {
416 { 0x00000001u, false, true, "first_byte" },
417 { 0x00000100u, false, true, "second_byte" },
418 { 0x00010000u, false, true, "third_byte" },
419 { 0x01000000u, false, true, "fourth_byte" },
420 { 0u, true, false, "padded_zero" },
421 };
422
423 struct ConditionLocationSubcase
424 {
425 ConditionLocation location;
426 const char* name;
427 };
428
429 const ConditionLocationSubcase kConditionLocationSubcase[] =
430 {
431 { ConditionLocation::PRIMARY_FLAT, "primary" },
432 { ConditionLocation::PRIMARY_WITH_SECONDARY, "inherited" },
433 { ConditionLocation::SECONDARY_NORMAL, "secondary" },
434 { ConditionLocation::SECONDARY_INHERITED, "secondary_inherited" },
435 };
436
437 for (int subcaseNdx = 0; subcaseNdx < DE_LENGTH_OF_ARRAY(kConditionLocationSubcase); ++subcaseNdx)
438 {
439 const auto& subcase = kConditionLocationSubcase[subcaseNdx];
440
441 de::MovePtr<tcu::TestCaseGroup> subcaseGroup(new tcu::TestCaseGroup(m_testCtx, subcase.name, ""));
442
443 ConditionalData conditionalData = {};
444 conditionalData.conditionInverted = false;
445
446 switch (subcase.location)
447 {
448 case ConditionLocation::PRIMARY_FLAT:
449 conditionalData.conditionInPrimaryCommandBuffer = true;
450 conditionalData.conditionInSecondaryCommandBuffer = false;
451 conditionalData.conditionInherited = false;
452 break;
453
454 case ConditionLocation::PRIMARY_WITH_SECONDARY:
455 conditionalData.conditionInPrimaryCommandBuffer = true;
456 conditionalData.conditionInSecondaryCommandBuffer = false;
457 conditionalData.conditionInherited = true;
458 break;
459
460 case ConditionLocation::SECONDARY_NORMAL:
461 conditionalData.conditionInPrimaryCommandBuffer = false;
462 conditionalData.conditionInSecondaryCommandBuffer = true;
463 conditionalData.conditionInherited = false;
464 break;
465
466 case ConditionLocation::SECONDARY_INHERITED:
467 conditionalData.conditionInPrimaryCommandBuffer = false;
468 conditionalData.conditionInSecondaryCommandBuffer = true;
469 conditionalData.conditionInherited = true;
470 break;
471
472 default:
473 DE_ASSERT(false);
474 break;
475 }
476
477 for (int valueNdx = 0; valueNdx < DE_LENGTH_OF_ARRAY(kConditionValueResults); ++valueNdx)
478 {
479 const auto& valueResults = kConditionValueResults[valueNdx];
480
481 conditionalData.conditionValue = valueResults.value;
482 conditionalData.padConditionValue = valueResults.padding;
483 conditionalData.expectCommandExecution = valueResults.execution;
484
485 ConditionalTestSpec spec;
486 spec.command = DISPATCH_COMMAND_TYPE_DISPATCH;
487 spec.numCalls = 1;
488 spec.conditionalData = conditionalData;
489
490 subcaseGroup->addChild(new ConditionalDispatchTest(m_testCtx, valueResults.name, "", spec));
491 }
492
493 conditionSizeGroup->addChild(subcaseGroup.release());
494 }
495
496 addChild(conditionSizeGroup.release());
497 }
498
499 // Tests checking the buffer allocation offset is applied correctly when reading the condition.
500 {
501 de::MovePtr<tcu::TestCaseGroup> allocOffsetGroup(new tcu::TestCaseGroup(m_testCtx, "alloc_offset", "Tests verifying the buffer allocation offset is applied correctly"));
502
503 const struct
504 {
505 ConditionLocation location;
506 const char* name;
507 } kLocationCases[] =
508 {
509 { ConditionLocation::PRIMARY_FLAT, "primary" },
510 { ConditionLocation::PRIMARY_WITH_SECONDARY, "inherited" },
511 { ConditionLocation::SECONDARY_NORMAL, "secondary" },
512 { ConditionLocation::SECONDARY_INHERITED, "secondary_inherited" },
513 };
514
515 const struct
516 {
517 bool active;
518 const char* name;
519 } kActiveCases[] =
520 {
521 { false, "zero" },
522 { true, "nonzero" },
523 };
524
525 const struct
526 {
527 ConditionalBufferMemory memoryType;
528 const char* name;
529 } kMemoryTypeCases[] =
530 {
531 { LOCAL, "device_local" },
532 { HOST, "host_visible" },
533 };
534
535 for (const auto& locationCase : kLocationCases)
536 {
537 de::MovePtr<tcu::TestCaseGroup> locationSubGroup(new tcu::TestCaseGroup(m_testCtx, locationCase.name, ""));
538
539 for (const auto& activeCase : kActiveCases)
540 {
541 de::MovePtr<tcu::TestCaseGroup> activeSubGroup(new tcu::TestCaseGroup(m_testCtx, activeCase.name, ""));
542
543 for (const auto& memoryTypeCase : kMemoryTypeCases)
544 {
545 ConditionalData conditionalData =
546 {
547 false, // bool conditionInPrimaryCommandBuffer;
548 false, // bool conditionInSecondaryCommandBuffer;
549 false, // bool conditionInverted;
550 false, // bool conditionInherited;
551 0u, // deUint32 conditionValue;
552 false, // bool padConditionValue;
553 true, // bool allocationOffset;
554 false, // bool clearInRenderPass;
555 false, // bool expectCommandExecution;
556 memoryTypeCase.memoryType, // ConditionalBufferMemory memoryType;
557 };
558
559 switch (locationCase.location)
560 {
561 case ConditionLocation::PRIMARY_FLAT:
562 conditionalData.conditionInPrimaryCommandBuffer = true;
563 conditionalData.conditionInSecondaryCommandBuffer = false;
564 conditionalData.conditionInherited = false;
565 break;
566
567 case ConditionLocation::PRIMARY_WITH_SECONDARY:
568 conditionalData.conditionInPrimaryCommandBuffer = true;
569 conditionalData.conditionInSecondaryCommandBuffer = false;
570 conditionalData.conditionInherited = true;
571 break;
572
573 case ConditionLocation::SECONDARY_NORMAL:
574 conditionalData.conditionInPrimaryCommandBuffer = false;
575 conditionalData.conditionInSecondaryCommandBuffer = true;
576 conditionalData.conditionInherited = false;
577 break;
578
579 case ConditionLocation::SECONDARY_INHERITED:
580 conditionalData.conditionInPrimaryCommandBuffer = false;
581 conditionalData.conditionInSecondaryCommandBuffer = true;
582 conditionalData.conditionInherited = true;
583 break;
584
585 default:
586 DE_ASSERT(false);
587 break;
588 }
589
590 conditionalData.conditionValue = (activeCase.active ? 1u : 0u);
591 conditionalData.expectCommandExecution = activeCase.active;
592
593 const ConditionalTestSpec spec =
594 {
595 DISPATCH_COMMAND_TYPE_DISPATCH, // DispatchCommandType command;
596 1, // int numCalls;
597 conditionalData, // ConditionalData conditionalData;
598 };
599
600 activeSubGroup->addChild(new ConditionalDispatchTest(m_testCtx, memoryTypeCase.name, "", spec));
601 }
602
603 locationSubGroup->addChild(activeSubGroup.release());
604 }
605
606 allocOffsetGroup->addChild(locationSubGroup.release());
607 }
608
609 addChild(allocOffsetGroup.release());
610 }
611 }
612
613 } // conditional
614 } // vkt
615