1/*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2022 The Khronos Group Inc. 6 * Copyright (c) 2022 NVIDIA Corporation. 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 Ray Query Opacity Micromap Tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktRayQueryOpacityMicromapTests.hpp" 26#include "vktTestCase.hpp" 27 28#include "vkRayTracingUtil.hpp" 29#include "vkObjUtil.hpp" 30#include "vkCmdUtil.hpp" 31#include "vkBufferWithMemory.hpp" 32#include "vkBuilderUtil.hpp" 33#include "vkTypeUtil.hpp" 34#include "vkBarrierUtil.hpp" 35#include "vktTestGroupUtil.hpp" 36 37#include "deUniquePtr.hpp" 38#include "deRandom.hpp" 39 40#include <sstream> 41#include <vector> 42#include <iostream> 43 44namespace vkt 45{ 46namespace RayQuery 47{ 48 49namespace 50{ 51 52using namespace vk; 53 54enum ShaderSourcePipeline 55{ 56 SSP_GRAPHICS_PIPELINE, 57 SSP_COMPUTE_PIPELINE, 58 SSP_RAY_TRACING_PIPELINE 59}; 60 61enum ShaderSourceType 62{ 63 SST_VERTEX_SHADER, 64 SST_COMPUTE_SHADER, 65 SST_RAY_GENERATION_SHADER, 66}; 67 68enum TestFlagBits 69{ 70 TEST_FLAG_BIT_FORCE_OPAQUE_INSTANCE = 1U << 0, 71 TEST_FLAG_BIT_FORCE_OPAQUE_RAY_FLAG = 1U << 1, 72 TEST_FLAG_BIT_DISABLE_OPACITY_MICROMAP_INSTANCE = 1U << 2, 73 TEST_FLAG_BIT_FORCE_2_STATE_INSTANCE = 1U << 3, 74 TEST_FLAG_BIT_FORCE_2_STATE_RAY_FLAG = 1U << 4, 75 TEST_FLAG_BIT_LAST = 1U << 5, 76}; 77 78std::vector<std::string> testFlagBitNames = 79{ 80 "force_opaque_instance", 81 "force_opaque_ray_flag", 82 "disable_opacity_micromap_instance", 83 "force_2_state_instance", 84 "force_2_state_ray_flag", 85}; 86 87enum CopyType { 88 CT_NONE, 89 CT_FIRST_ACTIVE, 90 CT_CLONE = CT_FIRST_ACTIVE, 91 CT_COMPACT, 92 CT_NUM_COPY_TYPES, 93}; 94 95std::vector<std::string> copyTypeNames 96{ 97 "None", 98 "Clone", 99 "Compact", 100}; 101 102struct TestParams 103{ 104 ShaderSourceType shaderSourceType; 105 ShaderSourcePipeline shaderSourcePipeline; 106 bool useSpecialIndex; 107 deUint32 testFlagMask; 108 deUint32 subdivisionLevel; // Must be 0 for useSpecialIndex 109 deUint32 mode; // Special index value if useSpecialIndex, 2 or 4 for number of states otherwise 110 deUint32 seed; 111 CopyType copyType; 112 bool useMaintenance5; 113}; 114 115static constexpr deUint32 kNumThreadsAtOnce = 1024; 116 117 118class OpacityMicromapCase : public TestCase 119{ 120public: 121 OpacityMicromapCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params); 122 virtual ~OpacityMicromapCase (void) {} 123 124 virtual void checkSupport (Context& context) const; 125 virtual void initPrograms (vk::SourceCollections& programCollection) const; 126 virtual TestInstance* createInstance (Context& context) const; 127 128protected: 129 TestParams m_params; 130}; 131 132class OpacityMicromapInstance : public TestInstance 133{ 134public: 135 OpacityMicromapInstance (Context& context, const TestParams& params); 136 virtual ~OpacityMicromapInstance (void) {} 137 138 virtual tcu::TestStatus iterate (void); 139 140protected: 141 TestParams m_params; 142}; 143 144OpacityMicromapCase::OpacityMicromapCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params) 145 : TestCase (testCtx, name) 146 , m_params (params) 147{} 148 149void OpacityMicromapCase::checkSupport (Context& context) const 150{ 151 context.requireDeviceFunctionality("VK_KHR_ray_query"); 152 context.requireDeviceFunctionality("VK_KHR_acceleration_structure"); 153 context.requireDeviceFunctionality("VK_EXT_opacity_micromap"); 154 155 if (m_params.useMaintenance5) 156 context.requireDeviceFunctionality("VK_KHR_maintenance5"); 157 158 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures(); 159 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE) 160 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery"); 161 162 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures(); 163 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE) 164 TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure"); 165 166 const VkPhysicalDeviceOpacityMicromapFeaturesEXT& opacityMicromapFeaturesEXT = context.getOpacityMicromapFeaturesEXT(); 167 if (opacityMicromapFeaturesEXT.micromap == DE_FALSE) 168 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceOpacityMicromapFeaturesEXT.micromap"); 169 170 if (m_params.shaderSourceType == SST_RAY_GENERATION_SHADER) 171 { 172 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 173 174 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures(); 175 176 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE) 177 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline"); 178 } 179 180 switch (m_params.shaderSourceType) 181 { 182 case SST_VERTEX_SHADER: 183 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 184 break; 185 default: 186 break; 187 } 188 189 const VkPhysicalDeviceOpacityMicromapPropertiesEXT& opacityMicromapPropertiesEXT = context.getOpacityMicromapPropertiesEXT(); 190 191 if (!m_params.useSpecialIndex) 192 { 193 switch (m_params.mode) 194 { 195 case 2: 196 if (m_params.subdivisionLevel > opacityMicromapPropertiesEXT.maxOpacity2StateSubdivisionLevel) 197 TCU_THROW(NotSupportedError, "Requires a higher supported 2 state subdivision level"); 198 break; 199 case 4: 200 if (m_params.subdivisionLevel > opacityMicromapPropertiesEXT.maxOpacity4StateSubdivisionLevel) 201 TCU_THROW(NotSupportedError, "Requires a higher supported 4 state subdivision level"); 202 break; 203 default: 204 DE_ASSERT(false); 205 break; 206 } 207 } 208} 209 210static deUint32 levelToSubtriangles(deUint32 level) 211{ 212 return 1 << (2 * level); 213} 214 215void OpacityMicromapCase::initPrograms (vk::SourceCollections& programCollection) const 216{ 217 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 218 219 deUint32 numRays = levelToSubtriangles(m_params.subdivisionLevel); 220 221 std::string flagsString = (m_params.testFlagMask & TEST_FLAG_BIT_FORCE_OPAQUE_RAY_FLAG) ? "gl_RayFlagsOpaqueEXT" : "gl_RayFlagsNoneEXT"; 222 223 if (m_params.testFlagMask & TEST_FLAG_BIT_FORCE_2_STATE_RAY_FLAG) 224 flagsString += " | gl_RayFlagsForceOpacityMicromap2StateEXT"; 225 226 std::ostringstream sharedHeader; 227 sharedHeader 228 << "#version 460 core\n" 229 << "#extension GL_EXT_ray_query : require\n" 230 << "#extension GL_EXT_opacity_micromap : require\n" 231 << "\n" 232 << "layout(set=0, binding=0) uniform accelerationStructureEXT topLevelAS;\n" 233 << "layout(set=0, binding=1, std430) buffer RayOrigins {\n" 234 << " vec4 values[" << numRays << "];\n" 235 << "} origins;\n" 236 << "layout(set=0, binding=2, std430) buffer OutputModes {\n" 237 << " uint values[" << numRays << "];\n" 238 << "} modes;\n"; 239 240 std::ostringstream mainLoop; 241 mainLoop 242 << " while (index < " << numRays << ") {\n" 243 << " const uint cullMask = 0xFF;\n" 244 << " const vec3 origin = origins.values[index].xyz;\n" 245 << " const vec3 direction = vec3(0.0, 0.0, -1.0);\n" 246 << " const float tMin = 0.0f;\n" 247 << " const float tMax = 2.0f;\n" 248 << " uint outputVal = 0;\n" // 0 for miss, 1 for non-opaque, 2 for opaque 249 << " rayQueryEXT rq;\n" 250 << " rayQueryInitializeEXT(rq, topLevelAS, " << flagsString << ", cullMask, origin, tMin, direction, tMax);\n" 251 << " while (rayQueryProceedEXT(rq)) {\n" 252 << " if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT) {\n" 253 << " outputVal = 1;\n" 254 << " }\n" 255 << " }\n" 256 << " if (rayQueryGetIntersectionTypeEXT(rq, true) == gl_RayQueryCommittedIntersectionTriangleEXT) {\n" 257 << " outputVal = 2;\n" 258 << " }\n" 259 << " modes.values[index] = outputVal;\n" 260 << " index += " << kNumThreadsAtOnce << ";\n" 261 << " }\n"; 262 263 if (m_params.shaderSourceType == SST_VERTEX_SHADER) { 264 std::ostringstream vert; 265 vert 266 << sharedHeader.str() 267 << "void main()\n" 268 << "{\n" 269 << " uint index = gl_VertexIndex.x;\n" 270 << mainLoop.str() 271 << " gl_PointSize = 1.0f;\n" 272 << "}\n" 273 ; 274 275 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str()) << buildOptions; 276 } 277 else if (m_params.shaderSourceType == SST_RAY_GENERATION_SHADER) 278 { 279 std::ostringstream rgen; 280 rgen 281 << sharedHeader.str() 282 << "#extension GL_EXT_ray_tracing : require\n" 283 << "void main()\n" 284 << "{\n" 285 << " uint index = gl_LaunchIDEXT.x;\n" 286 << mainLoop.str() 287 << "}\n" 288 ; 289 290 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 291 } 292 else 293 { 294 DE_ASSERT(m_params.shaderSourceType == SST_COMPUTE_SHADER); 295 std::ostringstream comp; 296 comp 297 << sharedHeader.str() 298 << "layout(local_size_x=1024, local_size_y=1, local_size_z=1) in;\n" 299 << "\n" 300 << "void main()\n" 301 << "{\n" 302 << " uint index = gl_LocalInvocationID.x;\n" 303 << mainLoop.str() 304 << "}\n" 305 ; 306 307 programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(comp.str())) << buildOptions; 308 } 309} 310 311TestInstance* OpacityMicromapCase::createInstance (Context& context) const 312{ 313 return new OpacityMicromapInstance(context, m_params); 314} 315 316OpacityMicromapInstance::OpacityMicromapInstance (Context& context, const TestParams& params) 317 : TestInstance (context) 318 , m_params (params) 319{} 320 321tcu::Vec2 calcSubtriangleCentroid(const deUint32 index, const deUint32 subdivisionLevel) 322{ 323 if (subdivisionLevel == 0) { 324 return tcu::Vec2(1.0f/3.0f, 1.0f/3.0f); 325 } 326 327 deUint32 d = index; 328 329 d = ((d >> 1) & 0x22222222u) | ((d << 1) & 0x44444444u) | (d & 0x99999999u); 330 d = ((d >> 2) & 0x0c0c0c0cu) | ((d << 2) & 0x30303030u) | (d & 0xc3c3c3c3u); 331 d = ((d >> 4) & 0x00f000f0u) | ((d << 4) & 0x0f000f00u) | (d & 0xf00ff00fu); 332 d = ((d >> 8) & 0x0000ff00u) | ((d << 8) & 0x00ff0000u) | (d & 0xff0000ffu); 333 334 deUint32 f = (d & 0xffffu) | ((d << 16) & ~d); 335 336 f ^= (f >> 1) & 0x7fff7fffu; 337 f ^= (f >> 2) & 0x3fff3fffu; 338 f ^= (f >> 4) & 0x0fff0fffu; 339 f ^= (f >> 8) & 0x00ff00ffu; 340 341 deUint32 t = (f ^ d) >> 16; 342 343 deUint32 iu = ((f & ~t) | (d & ~t) | (~d & ~f & t)) & 0xffffu; 344 deUint32 iv = ((f >> 16) ^ d) & 0xffffu; 345 deUint32 iw = ((~f & ~t) | (d & ~t) | (~d & f & t)) & ((1 << subdivisionLevel) - 1); 346 347 const float scale = 1.0f / float(1 << subdivisionLevel); 348 349 float u = (1.0f / 3.0f) * scale; 350 float v = (1.0f / 3.0f) * scale; 351 352 // we need to only look at "subdivisionLevel" bits 353 iu = iu & ((1 << subdivisionLevel) - 1); 354 iv = iv & ((1 << subdivisionLevel) - 1); 355 iw = iw & ((1 << subdivisionLevel) - 1); 356 357 bool upright = (iu & 1) ^ (iv & 1) ^ (iw & 1); 358 if (!upright) 359 { 360 iu = iu + 1; 361 iv = iv + 1; 362 } 363 364 if (upright) 365 { 366 return tcu::Vec2( 367 u + (float)iu * scale, 368 v + (float)iv * scale 369 ); 370 } else 371 { 372 return tcu::Vec2( 373 (float)iu * scale - u, 374 (float)iv * scale - v 375 ); 376 } 377} 378 379static Move<VkRenderPass> makeEmptyRenderPass(const DeviceInterface& vk, 380 const VkDevice device) 381{ 382 std::vector<VkSubpassDescription> subpassDescriptions; 383 std::vector<VkSubpassDependency> subpassDependencies; 384 385 const VkSubpassDescription description = 386 { 387 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 388 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 389 0u, // deUint32 inputAttachmentCount; 390 DE_NULL, // const VkAttachmentReference* pInputAttachments; 391 0u, // deUint32 colorAttachmentCount; 392 DE_NULL, // const VkAttachmentReference* pColorAttachments; 393 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 394 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 395 0, // deUint32 preserveAttachmentCount; 396 DE_NULL // const deUint32* pPreserveAttachments; 397 }; 398 subpassDescriptions.push_back(description); 399 400 const VkSubpassDependency dependency = 401 { 402 0u, // deUint32 srcSubpass; 403 0u, // deUint32 dstSubpass; 404 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, // VkPipelineStageFlags srcStageMask; 405 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // VkPipelineStageFlags dstStageMask; 406 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 407 VK_ACCESS_MEMORY_READ_BIT, // VkAccessFlags dstAccessMask; 408 0u // VkDependencyFlags dependencyFlags; 409 }; 410 subpassDependencies.push_back(dependency); 411 412 const VkRenderPassCreateInfo renderPassInfo = 413 { 414 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 415 DE_NULL, // const void* pNext; 416 static_cast<VkRenderPassCreateFlags>(0u), // VkRenderPassCreateFlags flags; 417 0u, // deUint32 attachmentCount; 418 DE_NULL, // const VkAttachmentDescription* pAttachments; 419 static_cast<deUint32>(subpassDescriptions.size()), // deUint32 subpassCount; 420 &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses; 421 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount; 422 subpassDependencies.size() > 0 ? &subpassDependencies[0] : DE_NULL // const VkSubpassDependency* pDependencies; 423 }; 424 425 return createRenderPass(vk, device, &renderPassInfo); 426} 427 428Move<VkPipeline> makeGraphicsPipeline(const DeviceInterface& vk, 429 const VkDevice device, 430 const VkPipelineLayout pipelineLayout, 431 const VkRenderPass renderPass, 432 const VkShaderModule vertexModule, 433 const deUint32 subpass) 434{ 435 VkExtent2D renderSize { 256, 256 }; 436 VkViewport viewport = makeViewport(renderSize); 437 VkRect2D scissor = makeRect2D(renderSize); 438 439 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = 440 { 441 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType 442 DE_NULL, // const void* pNext 443 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags 444 1u, // deUint32 viewportCount 445 &viewport, // const VkViewport* pViewports 446 1u, // deUint32 scissorCount 447 &scissor // const VkRect2D* pScissors 448 }; 449 450 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = 451 { 452 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType 453 DE_NULL, // const void* pNext 454 0u, // VkPipelineInputAssemblyStateCreateFlags flags 455 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology 456 VK_FALSE // VkBool32 primitiveRestartEnable 457 }; 458 459 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = 460 { 461 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType 462 DE_NULL, // const void* pNext 463 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags 464 0u, // deUint32 vertexBindingDescriptionCount 465 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions 466 0u, // deUint32 vertexAttributeDescriptionCount 467 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions 468 }; 469 470 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = 471 { 472 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType 473 DE_NULL, // const void* pNext 474 0u, // VkPipelineRasterizationStateCreateFlags flags 475 VK_FALSE, // VkBool32 depthClampEnable 476 VK_TRUE, // VkBool32 rasterizerDiscardEnable 477 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode 478 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode 479 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace 480 VK_FALSE, // VkBool32 depthBiasEnable 481 0.0f, // float depthBiasConstantFactor 482 0.0f, // float depthBiasClamp 483 0.0f, // float depthBiasSlopeFactor 484 1.0f // float lineWidth 485 }; 486 487 return makeGraphicsPipeline( 488 vk, // const DeviceInterface& vk 489 device, // const VkDevice device 490 pipelineLayout, // const VkPipelineLayout pipelineLayout 491 vertexModule, // const VkShaderModule vertexShaderModule 492 DE_NULL, // const VkShaderModule tessellationControlModule 493 DE_NULL, // const VkShaderModule tessellationEvalModule 494 DE_NULL, // const VkShaderModule geometryShaderModule 495 DE_NULL, // const VkShaderModule fragmentShaderModule 496 renderPass, // const VkRenderPass renderPass 497 subpass, // const deUint32 subpass 498 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 499 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* inputAssemblyStateCreateInfo 500 DE_NULL, // const VkPipelineTessellationStateCreateInfo* tessStateCreateInfo 501 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* viewportStateCreateInfo 502 &rasterizationStateCreateInfo); // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 503} 504 505tcu::TestStatus OpacityMicromapInstance::iterate (void) 506{ 507 const auto& vkd = m_context.getDeviceInterface(); 508 const auto device = m_context.getDevice(); 509 auto& alloc = m_context.getDefaultAllocator(); 510 const auto qIndex = m_context.getUniversalQueueFamilyIndex(); 511 const auto queue = m_context.getUniversalQueue(); 512 513 // Command pool and buffer. 514 const auto cmdPool = makeCommandPool(vkd, device, qIndex); 515 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY); 516 const auto cmdBuffer = cmdBufferPtr.get(); 517 518 beginCommandBuffer(vkd, cmdBuffer); 519 520 // Build acceleration structures. 521 auto topLevelAS = makeTopLevelAccelerationStructure(); 522 auto bottomLevelAS = makeBottomLevelAccelerationStructure(); 523 524 deUint32 numSubtriangles = levelToSubtriangles(m_params.subdivisionLevel); 525 deUint32 opacityMicromapBytes = (m_params.mode == 2) ? (numSubtriangles + 3) / 4 : (numSubtriangles + 1) / 2; 526 527 // Generate random micromap data 528 std::vector<deUint8> opacityMicromapData; 529 530 de::Random rnd(m_params.seed); 531 532 while (opacityMicromapData.size() < opacityMicromapBytes) { 533 opacityMicromapData.push_back(rnd.getUint8()); 534 } 535 536 // Build a micromap (ignore infrastructure for now) 537 // Create the buffer with the mask and index data 538 // Allocate a fairly conservative bound for now 539 VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = initVulkanStructure();; 540 const auto micromapDataBufferSize = static_cast<VkDeviceSize>(1024 + opacityMicromapBytes); 541 auto micromapDataBufferCreateInfo = makeBufferCreateInfo(micromapDataBufferSize, 542 VK_BUFFER_USAGE_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 543 if (m_params.useMaintenance5) 544 { 545 bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)micromapDataBufferCreateInfo.usage; 546 micromapDataBufferCreateInfo.pNext = &bufferUsageFlags2; 547 micromapDataBufferCreateInfo.usage = 0; 548 } 549 550 BufferWithMemory micromapDataBuffer(vkd, device, alloc, micromapDataBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress); 551 auto& micromapDataBufferAlloc = micromapDataBuffer.getAllocation(); 552 void* micromapDataBufferData = micromapDataBufferAlloc.getHostPtr(); 553 554 const int TriangleOffset = 0; 555 const int IndexOffset = 256; 556 const int DataOffset = 512; 557 558 // Fill out VkMicromapUsageEXT with size information 559 VkMicromapUsageEXT mmUsage = { }; 560 mmUsage.count = 1; 561 mmUsage.subdivisionLevel = m_params.subdivisionLevel; 562 mmUsage.format = m_params.mode == 2 ? VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT : VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT; 563 564 { 565 deUint8 *data = static_cast<deUint8*>(micromapDataBufferData); 566 567 deMemset(data, 0, size_t(micromapDataBufferCreateInfo.size)); 568 569 DE_STATIC_ASSERT(sizeof(VkMicromapTriangleEXT) == 8); 570 571 // Triangle information 572 VkMicromapTriangleEXT* tri = (VkMicromapTriangleEXT*)(&data[TriangleOffset]); 573 tri->dataOffset = 0; 574 tri->subdivisionLevel = uint16_t(mmUsage.subdivisionLevel); 575 tri->format = uint16_t(mmUsage.format); 576 577 // Micromap data 578 { 579 for (size_t i = 0; i < opacityMicromapData.size(); i++) { 580 data[DataOffset + i] = opacityMicromapData[i]; 581 } 582 } 583 584 // Index information 585 *((deUint32*)&data[IndexOffset]) = m_params.useSpecialIndex ? m_params.mode : 0; 586 } 587 588 // Query the size from the build info 589 VkMicromapBuildInfoEXT mmBuildInfo = { 590 VK_STRUCTURE_TYPE_MICROMAP_BUILD_INFO_EXT, // VkStructureType sType; 591 DE_NULL, // const void* pNext; 592 VK_MICROMAP_TYPE_OPACITY_MICROMAP_EXT, // VkMicromapTypeEXT type; 593 0, // VkBuildMicromapFlagsEXT flags; 594 VK_BUILD_MICROMAP_MODE_BUILD_EXT, // VkBuildMicromapModeEXT mode; 595 DE_NULL, // VkMicromapEXT dstMicromap; 596 1, // uint32_t usageCountsCount; 597 &mmUsage, // const VkMicromapUsageEXT* pUsageCounts; 598 DE_NULL, // const VkMicromapUsageEXT* const* ppUsageCounts; 599 makeDeviceOrHostAddressConstKHR(DE_NULL), // VkDeviceOrHostAddressConstKHR data; 600 makeDeviceOrHostAddressKHR(DE_NULL), // VkDeviceOrHostAddressKHR scratchData; 601 makeDeviceOrHostAddressConstKHR(DE_NULL), // VkDeviceOrHostAddressConstKHR triangleArray; 602 0, // VkDeviceSize triangleArrayStride; 603 }; 604 605 VkMicromapBuildSizesInfoEXT sizeInfo = { 606 VK_STRUCTURE_TYPE_MICROMAP_BUILD_SIZES_INFO_EXT, // VkStructureType sType; 607 DE_NULL, // const void* pNext; 608 0, // VkDeviceSize micromapSize; 609 0, // VkDeviceSize buildScratchSize; 610 DE_FALSE, // VkBool32 discardable; 611 }; 612 613 vkd.getMicromapBuildSizesEXT(device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &mmBuildInfo, &sizeInfo); 614 615 // Create the backing and scratch storage 616 const auto micromapBackingBufferCreateInfo = makeBufferCreateInfo(sizeInfo.micromapSize, 617 VK_BUFFER_USAGE_MICROMAP_STORAGE_BIT_EXT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 618 BufferWithMemory micromapBackingBuffer(vkd, device, alloc, micromapBackingBufferCreateInfo, MemoryRequirement::Local | MemoryRequirement::DeviceAddress); 619 620 auto micromapScratchBufferCreateInfo = makeBufferCreateInfo(sizeInfo.buildScratchSize, 621 VK_BUFFER_USAGE_MICROMAP_STORAGE_BIT_EXT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 622 if (m_params.useMaintenance5) 623 { 624 bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)micromapScratchBufferCreateInfo.usage; 625 micromapScratchBufferCreateInfo.pNext = &bufferUsageFlags2; 626 micromapScratchBufferCreateInfo.usage = 0; 627 } 628 BufferWithMemory micromapScratchBuffer(vkd, device, alloc, micromapScratchBufferCreateInfo, MemoryRequirement::Local | MemoryRequirement::DeviceAddress); 629 630 de::MovePtr<BufferWithMemory> copyMicromapBackingBuffer; 631 632 // Create the micromap itself 633 VkMicromapCreateInfoEXT maCreateInfo = { 634 VK_STRUCTURE_TYPE_MICROMAP_CREATE_INFO_EXT, // VkStructureType sType; 635 DE_NULL, // const void* pNext; 636 0, // VkMicromapCreateFlagsEXT createFlags; 637 micromapBackingBuffer.get(), // VkBuffer buffer; 638 0, // VkDeviceSize offset; 639 sizeInfo.micromapSize, // VkDeviceSize size; 640 VK_MICROMAP_TYPE_OPACITY_MICROMAP_EXT, // VkMicromapTypeEXT type; 641 0ull // VkDeviceAddress deviceAddress; 642 }; 643 644 VkMicromapEXT micromap = VK_NULL_HANDLE, origMicromap = VK_NULL_HANDLE; 645 646 VK_CHECK(vkd.createMicromapEXT(device, &maCreateInfo, nullptr, µmap)); 647 648 // Do the build 649 mmBuildInfo.dstMicromap = micromap; 650 mmBuildInfo.data = makeDeviceOrHostAddressConstKHR(vkd, device, micromapDataBuffer.get(), DataOffset); 651 mmBuildInfo.triangleArray = makeDeviceOrHostAddressConstKHR(vkd, device, micromapDataBuffer.get(), TriangleOffset); 652 mmBuildInfo.scratchData = makeDeviceOrHostAddressKHR(vkd, device, micromapScratchBuffer.get(), 0); 653 654 vkd.cmdBuildMicromapsEXT(cmdBuffer, 1, &mmBuildInfo); 655 656 { 657 VkMemoryBarrier2 memoryBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, NULL, 658 VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT, VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT, 659 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_ACCESS_2_MICROMAP_READ_BIT_EXT }; 660 VkDependencyInfoKHR dependencyInfo = { 661 VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR, // VkStructureType sType; 662 DE_NULL, // const void* pNext; 663 0u, // VkDependencyFlags dependencyFlags; 664 1u, // uint32_t memoryBarrierCount; 665 &memoryBarrier, // const VkMemoryBarrier2KHR* pMemoryBarriers; 666 0u, // uint32_t bufferMemoryBarrierCount; 667 DE_NULL, // const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; 668 0u, // uint32_t imageMemoryBarrierCount; 669 DE_NULL, // const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; 670 }; 671 672 vkd.cmdPipelineBarrier2(cmdBuffer, &dependencyInfo); 673 } 674 675 if (m_params.copyType != CT_NONE) { 676 copyMicromapBackingBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 677 vkd, device, alloc, micromapBackingBufferCreateInfo, MemoryRequirement::Local | MemoryRequirement::DeviceAddress)); 678 679 origMicromap = micromap; 680 681 maCreateInfo.buffer = copyMicromapBackingBuffer->get(); 682 683 VK_CHECK(vkd.createMicromapEXT(device, &maCreateInfo, nullptr, µmap)); 684 685 VkCopyMicromapInfoEXT copyMicromapInfo = { 686 VK_STRUCTURE_TYPE_COPY_MICROMAP_INFO_EXT, // VkStructureType sType; 687 DE_NULL, // const void* pNext; 688 origMicromap, // VkMicromapEXT src; 689 micromap, // VkMicromapEXT dst; 690 VK_COPY_MICROMAP_MODE_CLONE_EXT // VkCopyMicromapModeEXT mode; 691 }; 692 693 vkd.cmdCopyMicromapEXT(cmdBuffer, ©MicromapInfo); 694 695 { 696 VkMemoryBarrier2 memoryBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, NULL, 697 VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT, VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT, 698 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_ACCESS_2_MICROMAP_READ_BIT_EXT }; 699 VkDependencyInfoKHR dependencyInfo = { 700 VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR, // VkStructureType sType; 701 DE_NULL, // const void* pNext; 702 0u, // VkDependencyFlags dependencyFlags; 703 1u, // uint32_t memoryBarrierCount; 704 &memoryBarrier, // const VkMemoryBarrier2KHR* pMemoryBarriers; 705 0u, // uint32_t bufferMemoryBarrierCount; 706 DE_NULL, // const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; 707 0u, // uint32_t imageMemoryBarrierCount; 708 DE_NULL, // const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; 709 }; 710 711 dependencyInfo.memoryBarrierCount = 1; 712 dependencyInfo.pMemoryBarriers = &memoryBarrier; 713 714 vkd.cmdPipelineBarrier2(cmdBuffer, &dependencyInfo); 715 } 716 } 717 718 // Attach the micromap to the geometry 719 VkAccelerationStructureTrianglesOpacityMicromapEXT opacityGeometryMicromap = { 720 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_OPACITY_MICROMAP_EXT, //VkStructureType sType; 721 DE_NULL, //void* pNext; 722 VK_INDEX_TYPE_UINT32, //VkIndexType indexType; 723 makeDeviceOrHostAddressConstKHR(vkd, device, micromapDataBuffer.get(), IndexOffset), //VkDeviceOrHostAddressConstKHR indexBuffer; 724 0u, //VkDeviceSize indexStride; 725 0u, //uint32_t baseTriangle; 726 1u, //uint32_t usageCountsCount; 727 & mmUsage, //const VkMicromapUsageEXT* pUsageCounts; 728 DE_NULL, //const VkMicromapUsageEXT* const* ppUsageCounts; 729 micromap //VkMicromapEXT micromap; 730 }; 731 732 const std::vector<tcu::Vec3> triangle = 733 { 734 tcu::Vec3(0.0f, 0.0f, 0.0f), 735 tcu::Vec3(1.0f, 0.0f, 0.0f), 736 tcu::Vec3(0.0f, 1.0f, 0.0f), 737 }; 738 739 bottomLevelAS->addGeometry(triangle, true/*is triangles*/, 0, &opacityGeometryMicromap); 740 if (m_params.testFlagMask & TEST_FLAG_BIT_DISABLE_OPACITY_MICROMAP_INSTANCE) 741 bottomLevelAS->setBuildFlags(VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT); 742 bottomLevelAS->createAndBuild(vkd, device, cmdBuffer, alloc); 743 de::SharedPtr<BottomLevelAccelerationStructure> blasSharedPtr (bottomLevelAS.release()); 744 745 VkGeometryInstanceFlagsKHR instanceFlags = 0; 746 747 if (m_params.testFlagMask & TEST_FLAG_BIT_FORCE_2_STATE_INSTANCE) 748 instanceFlags |= VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT; 749 if (m_params.testFlagMask & TEST_FLAG_BIT_FORCE_OPAQUE_INSTANCE) 750 instanceFlags |= VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR; 751 if (m_params.testFlagMask & TEST_FLAG_BIT_DISABLE_OPACITY_MICROMAP_INSTANCE) 752 instanceFlags |= VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT; 753 754 topLevelAS->setInstanceCount(1); 755 topLevelAS->addInstance(blasSharedPtr, identityMatrix3x4, 0, 0xFFu, 0u, instanceFlags); 756 topLevelAS->createAndBuild(vkd, device, cmdBuffer, alloc); 757 758 // One ray per subtriangle for this test 759 deUint32 numRays = numSubtriangles; 760 761 // SSBO buffer for origins. 762 const auto originsBufferSize = static_cast<VkDeviceSize>(sizeof(tcu::Vec4) * numRays); 763 auto originsBufferInfo = makeBufferCreateInfo(originsBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 764 if (m_params.useMaintenance5) 765 { 766 bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)originsBufferInfo.usage; 767 originsBufferInfo.pNext = &bufferUsageFlags2; 768 originsBufferInfo.usage = 0; 769 } 770 BufferWithMemory originsBuffer (vkd, device, alloc, originsBufferInfo, MemoryRequirement::HostVisible); 771 auto& originsBufferAlloc = originsBuffer.getAllocation(); 772 void* originsBufferData = originsBufferAlloc.getHostPtr(); 773 774 std::vector<tcu::Vec4> origins; 775 std::vector<deUint32> expectedOutputModes; 776 origins.reserve(numRays); 777 expectedOutputModes.reserve(numRays); 778 779 // Fill in vector of expected outputs 780 for (deUint32 index = 0; index < numRays; index++) { 781 deUint32 state = m_params.testFlagMask & (TEST_FLAG_BIT_FORCE_OPAQUE_INSTANCE | TEST_FLAG_BIT_FORCE_OPAQUE_RAY_FLAG) ? 782 VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT : VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT; 783 784 if (!(m_params.testFlagMask & TEST_FLAG_BIT_DISABLE_OPACITY_MICROMAP_INSTANCE)) 785 { 786 if (m_params.useSpecialIndex) 787 { 788 state = m_params.mode; 789 } 790 else 791 { 792 if (m_params.mode == 2) { 793 deUint8 byte = opacityMicromapData[index / 8]; 794 state = (byte >> (index % 8)) & 0x1; 795 } else { 796 DE_ASSERT(m_params.mode == 4); 797 deUint8 byte = opacityMicromapData[index / 4]; 798 state = (byte >> 2*(index % 4)) & 0x3; 799 } 800 // Process in SPECIAL_INDEX number space 801 state = ~state; 802 } 803 804 if (m_params.testFlagMask & (TEST_FLAG_BIT_FORCE_2_STATE_INSTANCE | TEST_FLAG_BIT_FORCE_2_STATE_RAY_FLAG)) 805 { 806 if (state == deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT)) 807 state = deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT); 808 if (state == deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT)) 809 state = deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT); 810 } 811 } 812 813 if (state != deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT)) 814 { 815 if (m_params.testFlagMask & (TEST_FLAG_BIT_FORCE_OPAQUE_INSTANCE | TEST_FLAG_BIT_FORCE_OPAQUE_RAY_FLAG)) 816 { 817 state = deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT); 818 } else if (state != deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT)) { 819 state = deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT); 820 } 821 } 822 823 if (state == deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT)) 824 { 825 expectedOutputModes.push_back(0); 826 } 827 else if (state == deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT)) 828 { 829 expectedOutputModes.push_back(1); 830 } 831 else if (state == deUint32(VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT)) 832 { 833 expectedOutputModes.push_back(2); 834 } 835 else 836 { 837 DE_ASSERT(false); 838 } 839 } 840 841 for(deUint32 index = 0; index < numRays; index++) { 842 tcu::Vec2 centroid = calcSubtriangleCentroid(index, m_params.subdivisionLevel); 843 origins.push_back(tcu::Vec4(centroid.x(), centroid.y(), 1.0, 0.0)); 844 } 845 846 const auto originsBufferSizeSz = static_cast<size_t>(originsBufferSize); 847 deMemcpy(originsBufferData, origins.data(), originsBufferSizeSz); 848 flushAlloc(vkd, device, originsBufferAlloc); 849 850 // Storage buffer for output modes 851 const auto outputModesBufferSize = static_cast<VkDeviceSize>(sizeof(deUint32) * numRays); 852 const auto outputModesBufferInfo = makeBufferCreateInfo(outputModesBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 853 BufferWithMemory outputModesBuffer (vkd, device, alloc, outputModesBufferInfo, MemoryRequirement::HostVisible); 854 auto& outputModesBufferAlloc = outputModesBuffer.getAllocation(); 855 void* outputModesBufferData = outputModesBufferAlloc.getHostPtr(); 856 deMemset(outputModesBufferData, 0xFF, static_cast<size_t>(outputModesBufferSize)); 857 flushAlloc(vkd, device, outputModesBufferAlloc); 858 859 // Descriptor set layout. 860 DescriptorSetLayoutBuilder dsLayoutBuilder; 861 dsLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL); 862 dsLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL); 863 dsLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL); 864 const auto setLayout = dsLayoutBuilder.build(vkd, device); 865 866 // Pipeline layout. 867 const auto pipelineLayout = makePipelineLayout(vkd, device, setLayout.get()); 868 869 // Descriptor pool and set. 870 DescriptorPoolBuilder poolBuilder; 871 poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR); 872 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 873 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 874 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 875 const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get()); 876 877 // Update descriptor set. 878 { 879 const VkWriteDescriptorSetAccelerationStructureKHR accelDescInfo = 880 { 881 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, 882 nullptr, 883 1u, 884 topLevelAS.get()->getPtr(), 885 }; 886 const auto inStorageBufferInfo = makeDescriptorBufferInfo(originsBuffer.get(), 0ull, VK_WHOLE_SIZE); 887 const auto storageBufferInfo = makeDescriptorBufferInfo(outputModesBuffer.get(), 0ull, VK_WHOLE_SIZE); 888 889 DescriptorSetUpdateBuilder updateBuilder; 890 updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelDescInfo); 891 updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inStorageBufferInfo); 892 updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &storageBufferInfo); 893 updateBuilder.update(vkd, device); 894 } 895 896 Move<VkPipeline> pipeline; 897 de::MovePtr<BufferWithMemory> raygenSBT; 898 Move<VkRenderPass> renderPass; 899 Move<VkFramebuffer> framebuffer; 900 901 if (m_params.shaderSourceType == SST_VERTEX_SHADER) 902 { 903 auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0); 904 905 renderPass = makeEmptyRenderPass(vkd, device); 906 framebuffer = makeFramebuffer(vkd, device, *renderPass, 0u, DE_NULL, 32, 32); 907 pipeline = makeGraphicsPipeline(vkd, device, *pipelineLayout, *renderPass, *vertexModule, 0); 908 909 beginRenderPass(vkd, cmdBuffer, *renderPass, *framebuffer, makeRect2D(32u, 32u)); 910 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get()); 911 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); 912 vkd.cmdDraw(cmdBuffer, kNumThreadsAtOnce, 1, 0, 0); 913 endRenderPass(vkd, cmdBuffer); 914 } else if (m_params.shaderSourceType == SST_RAY_GENERATION_SHADER) 915 { 916 const auto& vki = m_context.getInstanceInterface(); 917 const auto physDev = m_context.getPhysicalDevice(); 918 919 // Shader module. 920 auto rgenModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0); 921 922 // Get some ray tracing properties. 923 deUint32 shaderGroupHandleSize = 0u; 924 deUint32 shaderGroupBaseAlignment = 1u; 925 { 926 const auto rayTracingPropertiesKHR = makeRayTracingProperties(vki, physDev); 927 shaderGroupHandleSize = rayTracingPropertiesKHR->getShaderGroupHandleSize(); 928 shaderGroupBaseAlignment = rayTracingPropertiesKHR->getShaderGroupBaseAlignment(); 929 } 930 931 auto raygenSBTRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 932 auto unusedSBTRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 933 934 { 935 const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>(); 936 rayTracingPipeline->setCreateFlags(VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT); 937 if (m_params.useMaintenance5) 938 rayTracingPipeline->setCreateFlags2(VK_PIPELINE_CREATE_2_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT); 939 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, 0); 940 941 pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get()); 942 943 raygenSBT = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1); 944 raygenSBTRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenSBT->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 945 } 946 947 // Trace rays. 948 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get()); 949 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); 950 vkd.cmdTraceRaysKHR(cmdBuffer, &raygenSBTRegion, &unusedSBTRegion, &unusedSBTRegion, &unusedSBTRegion, kNumThreadsAtOnce, 1u, 1u); 951 } 952 else 953 { 954 DE_ASSERT(m_params.shaderSourceType == SST_COMPUTE_SHADER); 955 // Shader module. 956 const auto compModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0); 957 958 // Pipeline. 959 const VkPipelineShaderStageCreateInfo shaderInfo = 960 { 961 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 962 nullptr, // const void* pNext; 963 0u, // VkPipelineShaderStageCreateFlags flags; 964 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 965 compModule.get(), // VkShaderModule module; 966 "main", // const char* pName; 967 nullptr, // const VkSpecializationInfo* pSpecializationInfo; 968 }; 969 const VkComputePipelineCreateInfo pipelineInfo = 970 { 971 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 972 nullptr, // const void* pNext; 973 0u, // VkPipelineCreateFlags flags; 974 shaderInfo, // VkPipelineShaderStageCreateInfo stage; 975 pipelineLayout.get(), // VkPipelineLayout layout; 976 DE_NULL, // VkPipeline basePipelineHandle; 977 0, // deInt32 basePipelineIndex; 978 }; 979 pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineInfo); 980 981 // Dispatch work with ray queries. 982 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get()); 983 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); 984 vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u); 985 } 986 987 // Barrier for the output buffer. 988 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 989 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr); 990 991 endCommandBuffer(vkd, cmdBuffer); 992 submitCommandsAndWait(vkd, device, queue, cmdBuffer); 993 994 if (micromap != VK_NULL_HANDLE) 995 vkd.destroyMicromapEXT(device, micromap, DE_NULL); 996 if (micromap != VK_NULL_HANDLE) 997 vkd.destroyMicromapEXT(device, origMicromap, DE_NULL); 998 999 // Verify results. 1000 std::vector<deUint32> outputData (expectedOutputModes.size()); 1001 const auto outputModesBufferSizeSz = static_cast<size_t>(outputModesBufferSize); 1002 1003 invalidateAlloc(vkd, device, outputModesBufferAlloc); 1004 DE_ASSERT(de::dataSize(outputData) == outputModesBufferSizeSz); 1005 deMemcpy(outputData.data(), outputModesBufferData, outputModesBufferSizeSz); 1006 1007 for (size_t i = 0; i < outputData.size(); ++i) 1008 { 1009 const auto& outVal = outputData[i]; 1010 const auto& expectedVal = expectedOutputModes[i]; 1011 1012 if (outVal != expectedVal) 1013 { 1014 std::ostringstream msg; 1015 msg << "Unexpected value found for ray " << i << ": expected " << expectedVal << " and found " << outVal << ";"; 1016 TCU_FAIL(msg.str()); 1017 } 1018#if 0 1019 else 1020 { 1021 std::ostringstream msg; 1022 msg << "Expected value found for ray " << i << ": expected " << expectedVal << " and found " << outVal << ";\n"; // XXX Debug remove 1023 std::cout << msg.str(); 1024 } 1025#endif 1026 } 1027 1028 return tcu::TestStatus::pass("Pass"); 1029} 1030 1031} // anonymous 1032 1033constexpr deUint32 kMaxSubdivisionLevel = 15; 1034 1035void addBasicTests(tcu::TestCaseGroup* group) 1036{ 1037 deUint32 seed = 1614674687u; 1038 1039 const struct 1040 { 1041 ShaderSourceType shaderSourceType; 1042 ShaderSourcePipeline shaderSourcePipeline; 1043 std::string name; 1044 } shaderSourceTypes[] = 1045 { 1046 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" }, 1047 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", }, 1048 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", }, 1049 }; 1050 1051 const struct 1052 { 1053 bool useSpecialIndex; 1054 std::string name; 1055 } specialIndexUse[] = 1056 { 1057 { false, "map_value"}, 1058 { true, "special_index"}, 1059 }; 1060 1061 auto& testCtx = group->getTestContext(); 1062 1063 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx) 1064 { 1065 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name.c_str())); 1066 1067 for (deUint32 testFlagMask = 0; testFlagMask < TEST_FLAG_BIT_LAST; testFlagMask++) 1068 { 1069 std::string maskName = ""; 1070 1071 for (deUint32 bit = 0; bit < testFlagBitNames.size(); bit++) 1072 { 1073 if (testFlagMask & (1 << bit)) 1074 { 1075 if (maskName != "") 1076 maskName += "_"; 1077 maskName += testFlagBitNames[bit]; 1078 } 1079 } 1080 if (maskName == "") 1081 maskName = "NoFlags"; 1082 1083 de::MovePtr<tcu::TestCaseGroup> testFlagGroup(new tcu::TestCaseGroup(sourceTypeGroup->getTestContext(), maskName.c_str())); 1084 1085 for (size_t specialIndexNdx = 0; specialIndexNdx < DE_LENGTH_OF_ARRAY(specialIndexUse); ++specialIndexNdx) 1086 { 1087 de::MovePtr<tcu::TestCaseGroup> specialGroup(new tcu::TestCaseGroup(testFlagGroup->getTestContext(), specialIndexUse[specialIndexNdx].name.c_str())); 1088 1089 if (specialIndexUse[specialIndexNdx].useSpecialIndex) 1090 { 1091 for (deUint32 specialIndex = 0; specialIndex < 4; specialIndex++) { 1092 TestParams testParams 1093 { 1094 shaderSourceTypes[shaderSourceNdx].shaderSourceType, 1095 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline, 1096 specialIndexUse[specialIndexNdx].useSpecialIndex, 1097 testFlagMask, 1098 0, 1099 ~specialIndex, 1100 seed++, 1101 CT_NONE, 1102 false, 1103 }; 1104 1105 std::stringstream css; 1106 css << specialIndex; 1107 1108 specialGroup->addChild(new OpacityMicromapCase(testCtx, css.str().c_str(), testParams)); 1109 } 1110 testFlagGroup->addChild(specialGroup.release()); 1111 } else 1112 { 1113 struct { 1114 deUint32 mode; 1115 std::string name; 1116 } modes[] = 1117 { 1118 { 2, "2"}, 1119 { 4, "4" } 1120 }; 1121 for (deUint32 modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(modes); ++modeNdx) 1122 { 1123 de::MovePtr<tcu::TestCaseGroup> modeGroup(new tcu::TestCaseGroup(testFlagGroup->getTestContext(), modes[modeNdx].name.c_str())); 1124 1125 for (deUint32 level = 0; level <= kMaxSubdivisionLevel; level++) 1126 { 1127 TestParams testParams 1128 { 1129 shaderSourceTypes[shaderSourceNdx].shaderSourceType, 1130 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline, 1131 specialIndexUse[specialIndexNdx].useSpecialIndex, 1132 testFlagMask, 1133 level, 1134 modes[modeNdx].mode, 1135 seed++, 1136 CT_NONE, 1137 false, 1138 }; 1139 1140 std::stringstream css; 1141 css << "level_" << level; 1142 1143 modeGroup->addChild(new OpacityMicromapCase(testCtx, css.str().c_str(), testParams)); 1144 } 1145 specialGroup->addChild(modeGroup.release()); 1146 } 1147 testFlagGroup->addChild(specialGroup.release()); 1148 } 1149 } 1150 1151 sourceTypeGroup->addChild(testFlagGroup.release()); 1152 } 1153 1154 group->addChild(sourceTypeGroup.release()); 1155 } 1156} 1157 1158void addCopyTests(tcu::TestCaseGroup* group) 1159{ 1160 deUint32 seed = 1614674688u; 1161 1162 auto& testCtx = group->getTestContext(); 1163 1164 for (size_t copyTypeNdx = CT_FIRST_ACTIVE; copyTypeNdx < CT_NUM_COPY_TYPES; ++copyTypeNdx) 1165 { 1166 de::MovePtr<tcu::TestCaseGroup> copyTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), copyTypeNames[copyTypeNdx].c_str())); 1167 1168 struct { 1169 deUint32 mode; 1170 std::string name; 1171 } modes[] = 1172 { 1173 { 2, "2"}, 1174 { 4, "4" } 1175 }; 1176 for (deUint32 modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(modes); ++modeNdx) 1177 { 1178 de::MovePtr<tcu::TestCaseGroup> modeGroup(new tcu::TestCaseGroup(copyTypeGroup->getTestContext(), modes[modeNdx].name.c_str())); 1179 1180 for (deUint32 level = 0; level <= kMaxSubdivisionLevel; level++) 1181 { 1182 TestParams testParams 1183 { 1184 SST_COMPUTE_SHADER, 1185 SSP_COMPUTE_PIPELINE, 1186 false, 1187 0, 1188 level, 1189 modes[modeNdx].mode, 1190 seed++, 1191 (CopyType)copyTypeNdx, 1192 false, 1193 }; 1194 1195 std::stringstream css; 1196 css << "level_" << level; 1197 1198 modeGroup->addChild(new OpacityMicromapCase(testCtx, css.str().c_str(), testParams)); 1199 } 1200 copyTypeGroup->addChild(modeGroup.release()); 1201 } 1202 group->addChild(copyTypeGroup.release()); 1203 } 1204 1205 { 1206 TestParams testParams 1207 { 1208 SST_COMPUTE_SHADER, 1209 SSP_COMPUTE_PIPELINE, 1210 false, 1211 0, 1212 0, 1213 2, 1214 1, 1215 CT_FIRST_ACTIVE, 1216 true, 1217 }; 1218 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(group->getTestContext(), "misc", "")); 1219 miscGroup->addChild(new OpacityMicromapCase(testCtx, "maintenance5", testParams)); 1220 group->addChild(miscGroup.release()); 1221 } 1222} 1223 1224tcu::TestCaseGroup* createOpacityMicromapTests(tcu::TestContext& testCtx) 1225{ 1226 // Test acceleration structures using opacity micromap with ray query 1227 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "opacity_micromap")); 1228 1229 // Test accessing all formats of opacity micromaps 1230 addTestGroup(group.get(), "render", addBasicTests); 1231 // Test copying opacity micromaps 1232 addTestGroup(group.get(), "copy", addCopyTests); 1233 1234 return group.release(); 1235} 1236 1237} // RayQuery 1238} // vkt 1239