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