1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2020 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Ray Query Builtin tests 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktRayQueryWatertightnessTests.hpp" 25 26#include "vkDefs.hpp" 27 28#include "vktTestCase.hpp" 29#include "vktTestGroupUtil.hpp" 30#include "vkCmdUtil.hpp" 31#include "vkObjUtil.hpp" 32#include "vkBuilderUtil.hpp" 33#include "vkBarrierUtil.hpp" 34#include "vkBufferWithMemory.hpp" 35#include "vkImageWithMemory.hpp" 36#include "vkTypeUtil.hpp" 37#include "vkImageUtil.hpp" 38#include "deRandom.hpp" 39#include "tcuTexture.hpp" 40#include "tcuTextureUtil.hpp" 41#include "tcuTestLog.hpp" 42#include "tcuImageCompare.hpp" 43#include "tcuCommandLine.hpp" 44 45#include "vkRayTracingUtil.hpp" 46 47namespace vkt 48{ 49namespace RayQuery 50{ 51namespace 52{ 53using namespace vk; 54using namespace vkt; 55 56static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR 57 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR 58 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR 59 | VK_SHADER_STAGE_MISS_BIT_KHR 60 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR 61 | VK_SHADER_STAGE_CALLABLE_BIT_KHR; 62 63enum TestType 64{ 65 TEST_TYPE_NO_MISS = 0, 66 TEST_TYPE_SINGLE_HIT, 67}; 68 69enum GeomType 70{ 71 GEOM_TYPE_TRIANGLES, 72 GEOM_TYPE_AABBS, 73 GEOM_TYPE_LAST, 74}; 75 76const deUint32 TEST_WIDTH = 256u; 77const deUint32 TEST_HEIGHT = 256u; 78const float MIN_AABB_SIDE_LENGTH = 1e-6f; 79const float MIN_TRIANGLE_EDGE_LENGTH = 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT); 80const float MIN_TRIANGLE_AREA_SIZE = 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT); 81 82struct TestParams; 83 84typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams); 85typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams); 86typedef const std::string (*ShaderBodyTextFunc)(const TestParams& testParams); 87 88class PipelineConfiguration 89{ 90public: 91 PipelineConfiguration () {} 92 virtual ~PipelineConfiguration () {} 93 94 virtual void initConfiguration (Context& context, 95 TestParams& testParams) = 0; 96 virtual void fillCommandBuffer (Context& context, 97 TestParams& testParams, 98 VkCommandBuffer commandBuffer, 99 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 100 const VkDescriptorImageInfo& resultImageInfo) = 0; 101}; 102 103class TestConfiguration 104{ 105public: 106 TestConfiguration () 107 : m_bottomAccelerationStructures () 108 , m_topAccelerationStructure () 109 , m_expected () 110 { 111 } 112 virtual ~TestConfiguration () 113 { 114 } 115 116 virtual const VkAccelerationStructureKHR* initAccelerationStructures (Context& context, 117 TestParams& testParams, 118 VkCommandBuffer cmdBuffer) = 0; 119 virtual bool verify (BufferWithMemory* resultBuffer, 120 Context& context, 121 TestParams& testParams) = 0; 122 123protected: 124 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> m_bottomAccelerationStructures; 125 de::SharedPtr<TopLevelAccelerationStructure> m_topAccelerationStructure; 126 std::vector<deInt32> m_expected; 127}; 128 129struct TestParams 130{ 131 deUint32 width; 132 deUint32 height; 133 deUint32 depth; 134 deUint32 randomSeed; 135 TestType testType; 136 VkShaderStageFlagBits stage; 137 GeomType geomType; 138 deUint32 squaresGroupCount; 139 deUint32 geometriesGroupCount; 140 deUint32 instancesGroupCount; 141 VkFormat format; 142 CheckSupportFunc pipelineCheckSupport; 143 InitProgramsFunc pipelineInitPrograms; 144 ShaderBodyTextFunc testConfigShaderBodyText; 145}; 146 147deUint32 getShaderGroupHandleSize (const InstanceInterface& vki, 148 const VkPhysicalDevice physicalDevice) 149{ 150 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR; 151 152 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice); 153 154 return rayTracingPropertiesKHR->getShaderGroupHandleSize(); 155} 156 157deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki, 158 const VkPhysicalDevice physicalDevice) 159{ 160 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR; 161 162 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice); 163 164 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment(); 165} 166 167VkBuffer getVkBuffer (const de::MovePtr<BufferWithMemory>& buffer) 168{ 169 VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get(); 170 171 return result; 172} 173 174VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, VkDeviceSize size) 175{ 176 const VkDeviceSize sizeFixed = ((buffer == DE_NULL) ? 0ull : size); 177 178 return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), sizeFixed, sizeFixed); 179} 180 181VkImageCreateInfo makeImageCreateInfo (VkFormat format, 182 deUint32 width, 183 deUint32 height, 184 deUint32 depth, 185 VkImageType imageType = VK_IMAGE_TYPE_3D, 186 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT) 187{ 188 const VkImageCreateInfo imageCreateInfo = 189 { 190 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 191 DE_NULL, // const void* pNext; 192 (VkImageCreateFlags)0u, // VkImageCreateFlags flags; 193 imageType, // VkImageType imageType; 194 format, // VkFormat format; 195 makeExtent3D(width, height, depth), // VkExtent3D extent; 196 1u, // deUint32 mipLevels; 197 1u, // deUint32 arrayLayers; 198 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 199 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 200 usageFlags, // VkImageUsageFlags usage; 201 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 202 0u, // deUint32 queueFamilyIndexCount; 203 DE_NULL, // const deUint32* pQueueFamilyIndices; 204 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 205 }; 206 207 return imageCreateInfo; 208} 209 210static const std::string getMissPassthrough (void) 211{ 212 const std::string missPassthrough = 213 "#version 460 core\n" 214 "#extension GL_EXT_ray_tracing : require\n" 215 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 216 "\n" 217 "void main()\n" 218 "{\n" 219 "}\n"; 220 221 return missPassthrough; 222} 223 224static const std::string getHitPassthrough (void) 225{ 226 const std::string hitPassthrough = 227 "#version 460 core\n" 228 "#extension GL_EXT_ray_tracing : require\n" 229 "hitAttributeEXT vec3 attribs;\n" 230 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 231 "\n" 232 "void main()\n" 233 "{\n" 234 "}\n"; 235 236 return hitPassthrough; 237} 238 239static const std::string getGraphicsPassthrough (void) 240{ 241 std::ostringstream src; 242 243 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 244 << "\n" 245 << "void main(void)\n" 246 << "{\n" 247 << "}\n"; 248 249 return src.str(); 250} 251 252static const std::string getVertexPassthrough (void) 253{ 254 std::ostringstream src; 255 256 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 257 << "\n" 258 << "layout(location = 0) in vec4 in_position;\n" 259 << "\n" 260 << "void main(void)\n" 261 << "{\n" 262 << " gl_Position = in_position;\n" 263 << "}\n"; 264 265 return src.str(); 266} 267 268static inline tcu::Vec2 mixVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha) 269{ 270 const tcu::Vec2 result = a * alpha + b * (1.0f - alpha); 271 272 return result; 273} 274 275static inline tcu::Vec2 mixCoordsVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha, const float beta) 276{ 277 const tcu::Vec2 result = tcu::Vec2(deFloatMix(a.x(), b.x(), alpha), deFloatMix(a.y(), b.y(), beta)); 278 279 return result; 280} 281 282inline float triangleEdgeLength (const tcu::Vec2& vertexA, const tcu::Vec2& vertexB) 283{ 284 const float abx = vertexA.x() - vertexB.x(); 285 const float aby = vertexA.y() - vertexB.y(); 286 const float abq = abx * abx + aby * aby; 287 const float ab = deFloatSqrt(abq); 288 289 return ab; 290} 291 292inline float triangleArea (const float edgeALen, const float edgeBLen, const float edgeCLen) 293{ 294 const float s = (edgeALen + edgeBLen + edgeCLen) / 2.0f; 295 const float q = s * (s - edgeALen) * (s - edgeBLen) * (s - edgeCLen); 296 297 if (q <= 0.0f) 298 return 0.0f; 299 300 return deFloatSqrt(q); 301} 302 303static const std::string getGeomName (bool writePointSize) 304{ 305 std::ostringstream str; 306 str << "geom" << (writePointSize ? "_point_size" : ""); 307 return str.str(); 308} 309 310class GraphicsConfiguration : public PipelineConfiguration 311{ 312public: 313 static void checkSupport (Context& context, 314 const TestParams& testParams); 315 static void initPrograms (SourceCollections& programCollection, 316 const TestParams& testParams); 317 318 GraphicsConfiguration (); 319 virtual ~GraphicsConfiguration () {} 320 321 void initVertexBuffer (Context& context, 322 TestParams& testParams); 323 Move<VkPipeline> makeGraphicsPipeline (Context& context, 324 TestParams& testParams); 325 virtual void initConfiguration (Context& context, 326 TestParams& testParams) override; 327 virtual void fillCommandBuffer (Context& context, 328 TestParams& testParams, 329 VkCommandBuffer commandBuffer, 330 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 331 const VkDescriptorImageInfo& resultImageInfo) override; 332 333private: 334 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 335 Move<VkDescriptorPool> m_descriptorPool; 336 Move<VkDescriptorSet> m_descriptorSet; 337 338 VkFormat m_framebufferFormat; 339 Move<VkImage> m_framebufferImage; 340 de::MovePtr<Allocation> m_framebufferImageAlloc; 341 Move<VkImageView> m_framebufferAttachment; 342 343 Move<VkShaderModule> m_vertShaderModule; 344 Move<VkShaderModule> m_geomShaderModule; 345 Move<VkShaderModule> m_tescShaderModule; 346 Move<VkShaderModule> m_teseShaderModule; 347 Move<VkShaderModule> m_fragShaderModule; 348 349 Move<VkRenderPass> m_renderPass; 350 Move<VkFramebuffer> m_framebuffer; 351 Move<VkPipelineLayout> m_pipelineLayout; 352 Move<VkPipeline> m_pipeline; 353 354 deUint32 m_vertexCount; 355 Move<VkBuffer> m_vertexBuffer; 356 de::MovePtr<Allocation> m_vertexBufferAlloc; 357}; 358 359GraphicsConfiguration::GraphicsConfiguration() 360 : PipelineConfiguration () 361 , m_descriptorSetLayout () 362 , m_descriptorPool () 363 , m_descriptorSet () 364 , m_framebufferFormat (VK_FORMAT_R8G8B8A8_UNORM) 365 , m_framebufferImage () 366 , m_framebufferImageAlloc () 367 , m_framebufferAttachment () 368 , m_vertShaderModule () 369 , m_geomShaderModule () 370 , m_tescShaderModule () 371 , m_teseShaderModule () 372 , m_fragShaderModule () 373 , m_renderPass () 374 , m_framebuffer () 375 , m_pipelineLayout () 376 , m_pipeline () 377 , m_vertexCount (0) 378 , m_vertexBuffer () 379 , m_vertexBufferAlloc () 380{ 381} 382 383void GraphicsConfiguration::checkSupport (Context& context, 384 const TestParams& testParams) 385{ 386 switch (testParams.stage) 387 { 388 case VK_SHADER_STAGE_VERTEX_BIT: 389 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 390 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 391 case VK_SHADER_STAGE_GEOMETRY_BIT: 392 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 393 break; 394 default: 395 break; 396 } 397 398 switch (testParams.stage) 399 { 400 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 401 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 402 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER); 403 break; 404 case VK_SHADER_STAGE_GEOMETRY_BIT: 405 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER); 406 break; 407 default: 408 break; 409 } 410} 411 412void GraphicsConfiguration::initPrograms (SourceCollections& programCollection, 413 const TestParams& testParams) 414{ 415 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 416 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams); 417 418 switch (testParams.stage) 419 { 420 case VK_SHADER_STAGE_VERTEX_BIT: 421 { 422 { 423 std::ostringstream src; 424 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 425 << "#extension GL_EXT_ray_query : require\n" 426 << "#extension GL_EXT_ray_tracing : require\n" 427 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 428 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 429 << "\n" 430 << "void testFunc(ivec3 pos, ivec3 size)\n" 431 << "{\n" 432 << testShaderBody 433 << "}\n" 434 << "\n" 435 << "void main(void)\n" 436 << "{\n" 437 << " const int posId = int(gl_VertexIndex / 3);\n" 438 << " const int vertId = int(gl_VertexIndex % 3);\n" 439 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n" 440 << " const ivec3 pos = ivec3(posId % size.x, posId / size.x, 0);\n" 441 << "\n" 442 << " if (vertId == 0)\n" 443 << " {\n" 444 << " testFunc(pos, size);\n" 445 << " }\n" 446 << "}\n"; 447 448 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions; 449 } 450 451 programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions; 452 453 break; 454 } 455 456 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 457 { 458 { 459 std::ostringstream src; 460 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 461 << "\n" 462 << "layout(location = 0) in vec4 in_position;\n" 463 << "out gl_PerVertex\n" 464 << "{\n" 465 << " vec4 gl_Position;\n" 466 << "};\n" 467 << "\n" 468 << "void main(void)\n" 469 << "{\n" 470 << " gl_Position = in_position;\n" 471 << "}\n"; 472 473 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions; 474 } 475 476 { 477 std::ostringstream src; 478 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 479 << "#extension GL_EXT_tessellation_shader : require\n" 480 << "#extension GL_EXT_ray_query : require\n" 481 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 482 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 483 << "in gl_PerVertex\n" 484 << "{\n" 485 << " vec4 gl_Position;\n" 486 << "} gl_in[];\n" 487 << "layout(vertices = 3) out;\n" 488 << "out gl_PerVertex\n" 489 << "{\n" 490 << " vec4 gl_Position;\n" 491 << "} gl_out[];\n" 492 << "\n" 493 << "void testFunc(ivec3 pos, ivec3 size)\n" 494 << "{\n" 495 << testShaderBody 496 << "}\n" 497 << "\n" 498 << "void main(void)\n" 499 << "{\n" 500 << "\n" 501 << " if (gl_InvocationID == 0)\n" 502 << " {\n" 503 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n" 504 << " int index = int(gl_in[gl_InvocationID].gl_Position.z);\n" 505 << " int x = index % size.x;\n" 506 << " int y = index / size.y;\n" 507 << " const ivec3 pos = ivec3(x, y, 0);\n" 508 << " testFunc(pos, size);\n" 509 << " }\n" 510 << "\n" 511 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 512 << " gl_TessLevelInner[0] = 1;\n" 513 << " gl_TessLevelInner[1] = 1;\n" 514 << " gl_TessLevelOuter[gl_InvocationID] = 1;\n" 515 << "}\n"; 516 517 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions; 518 } 519 520 { 521 std::ostringstream src; 522 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 523 << "#extension GL_EXT_tessellation_shader : require\n" 524 << "layout(triangles, equal_spacing, ccw) in;\n" 525 << "in gl_PerVertex\n" 526 << "{\n" 527 << " vec4 gl_Position;\n" 528 << "} gl_in[];\n" 529 << "\n" 530 << "void main(void)\n" 531 << "{\n" 532 << " gl_Position = gl_in[0].gl_Position;\n" 533 << "}\n"; 534 535 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions; 536 } 537 538 break; 539 } 540 541 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 542 { 543 { 544 std::ostringstream src; 545 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 546 << "\n" 547 << "layout(location = 0) in vec4 in_position;\n" 548 << "out gl_PerVertex" 549 << "{\n" 550 << " vec4 gl_Position;\n" 551 << "};\n" 552 << "\n" 553 << "void main(void)\n" 554 << "{\n" 555 << " gl_Position = in_position;\n" 556 << "}\n"; 557 558 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions; 559 } 560 561 { 562 std::ostringstream src; 563 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 564 << "#extension GL_EXT_tessellation_shader : require\n" 565 << "in gl_PerVertex\n" 566 << "{\n" 567 << " vec4 gl_Position;\n" 568 << "} gl_in[];\n" 569 << "layout(vertices = 3) out;\n" 570 << "out gl_PerVertex\n" 571 << "{\n" 572 << " vec4 gl_Position;\n" 573 << "} gl_out[];\n" 574 << "\n" 575 << "void main(void)\n" 576 << "{\n" 577 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 578 << " gl_TessLevelInner[0] = 1;\n" 579 << " gl_TessLevelInner[1] = 1;\n" 580 << " gl_TessLevelOuter[gl_InvocationID] = 1;\n" 581 << "}\n"; 582 583 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions; 584 } 585 586 { 587 std::ostringstream src; 588 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 589 << "#extension GL_EXT_tessellation_shader : require\n" 590 << "#extension GL_EXT_ray_query : require\n" 591 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 592 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 593 << "layout(triangles, equal_spacing, ccw) in;\n" 594 << "in gl_PerVertex\n" 595 << "{\n" 596 << " vec4 gl_Position;\n" 597 << "} gl_in[];\n" 598 << "\n" 599 << "void testFunc(ivec3 pos, ivec3 size)\n" 600 << "{\n" 601 << testShaderBody 602 << "}\n" 603 << "\n" 604 << "void main(void)\n" 605 << "{\n" 606 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n" 607 << " int index = int(gl_in[0].gl_Position.z);\n" 608 << " int x = index % size.x;\n" 609 << " int y = index / size.y;\n" 610 << " const ivec3 pos = ivec3(x, y, 0);\n" 611 << " testFunc(pos, size);\n" 612 << " gl_Position = gl_in[0].gl_Position;\n" 613 << "}\n"; 614 615 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions; 616 } 617 618 break; 619 } 620 621 case VK_SHADER_STAGE_GEOMETRY_BIT: 622 { 623 programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions; 624 625 for (deUint32 i = 0; i < 2; ++i) 626 { 627 const bool writePointSize = i == 1; 628 std::string pointSize = writePointSize ? " gl_PointSize = 1.0f;\n" : ""; 629 630 std::ostringstream src; 631 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 632 << "#extension GL_EXT_ray_query : require\n" 633 << "layout(triangles) in;\n" 634 << "layout(points, max_vertices = 1) out;\n" 635 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 636 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 637 << "\n" 638 << "void testFunc(ivec3 pos, ivec3 size)\n" 639 << "{\n" 640 << testShaderBody 641 << "}\n" 642 << "\n" 643 << "void main(void)\n" 644 << "{\n" 645 << " const int posId = int(gl_PrimitiveIDIn);\n" 646 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n" 647 << " const ivec3 pos = ivec3(posId % size.x, posId / size.x, 0);\n" 648 << "\n" 649 << " testFunc(pos, size);\n" 650 << pointSize 651 << "}\n"; 652 653 programCollection.glslSources.add(getGeomName(writePointSize)) << glu::GeometrySource(src.str()) << buildOptions; 654 } 655 656 break; 657 } 658 659 case VK_SHADER_STAGE_FRAGMENT_BIT: 660 { 661 programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions; 662 663 { 664 std::ostringstream src; 665 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n" 666 << "#extension GL_EXT_ray_query : require\n" 667 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 668 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 669 << "\n" 670 << "void testFunc(ivec3 pos, ivec3 size)\n" 671 << "{\n" 672 << testShaderBody 673 << "}\n" 674 << "\n" 675 << "void main(void)\n" 676 << "{\n" 677 << " const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n" 678 << " const ivec3 pos = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n" 679 << "\n" 680 << " testFunc(pos, size);\n" 681 << "}\n"; 682 683 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions; 684 } 685 686 break; 687 } 688 689 default: 690 TCU_THROW(InternalError, "Unknown stage"); 691 } 692} 693 694void GraphicsConfiguration::initVertexBuffer (Context& context, 695 TestParams& testParams) 696{ 697 const DeviceInterface& vkd = context.getDeviceInterface(); 698 const VkDevice device = context.getDevice(); 699 const deUint32 width = testParams.width; 700 const deUint32 height = testParams.height; 701 Allocator& allocator = context.getDefaultAllocator(); 702 std::vector<tcu::Vec4> vertices; 703 704 switch (testParams.stage) 705 { 706 case VK_SHADER_STAGE_VERTEX_BIT: 707 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 708 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 709 { 710 float z = 0.0f; 711 const float w = 1.0f; 712 713 vertices.reserve(3 * height * width); 714 715 for (deUint32 y = 0; y < height; ++y) 716 for (deUint32 x = 0; x < width; ++x) 717 { 718 const float x0 = float(x + 0) / float(width); 719 const float y0 = float(y + 0) / float(height); 720 const float x1 = float(x + 1) / float(width); 721 const float y1 = float(y + 1) / float(height); 722 const float xm = (x0 + x1) / 2.0f; 723 const float ym = (y0 + y1) / 2.0f; 724 725 vertices.push_back(tcu::Vec4(x0, y0, z, w)); 726 vertices.push_back(tcu::Vec4(xm, y1, z, w)); 727 vertices.push_back(tcu::Vec4(x1, ym, z, w)); 728 729 z += 1.f; 730 } 731 732 break; 733 } 734 735 case VK_SHADER_STAGE_GEOMETRY_BIT: 736 { 737 const float z = 0.0f; 738 const float w = 1.0f; 739 740 vertices.reserve(3 * height * width); 741 742 for (deUint32 y = 0; y < height; ++y) 743 for (deUint32 x = 0; x < width; ++x) 744 { 745 const float x0 = float(x + 0) / float(width); 746 const float y0 = float(y + 0) / float(height); 747 const float x1 = float(x + 1) / float(width); 748 const float y1 = float(y + 1) / float(height); 749 const float xm = (x0 + x1) / 2.0f; 750 const float ym = (y0 + y1) / 2.0f; 751 752 vertices.push_back(tcu::Vec4(x0, y0, z, w)); 753 vertices.push_back(tcu::Vec4(xm, y1, z, w)); 754 vertices.push_back(tcu::Vec4(x1, ym, z, w)); 755 } 756 757 break; 758 } 759 760 case VK_SHADER_STAGE_FRAGMENT_BIT: 761 { 762 const float z = 1.0f; 763 const float w = 1.0f; 764 const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w); 765 const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w); 766 const tcu::Vec4 c = tcu::Vec4(-1.0f, +1.0f, z, w); 767 const tcu::Vec4 d = tcu::Vec4(+1.0f, +1.0f, z, w); 768 769 vertices.push_back(a); 770 vertices.push_back(b); 771 vertices.push_back(c); 772 773 vertices.push_back(b); 774 vertices.push_back(c); 775 vertices.push_back(d); 776 777 break; 778 } 779 780 default: 781 TCU_THROW(InternalError, "Unknown stage"); 782 783 } 784 785 // Initialize vertex buffer 786 { 787 const VkDeviceSize vertexBufferSize = sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size(); 788 const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 789 790 m_vertexCount = static_cast<deUint32>(vertices.size()); 791 m_vertexBuffer = createBuffer(vkd, device, &vertexBufferCreateInfo); 792 m_vertexBufferAlloc = bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible); 793 794 deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize); 795 flushAlloc(vkd, device, *m_vertexBufferAlloc); 796 } 797} 798 799Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline (Context& context, 800 TestParams& testParams) 801{ 802 const DeviceInterface& vkd = context.getDeviceInterface(); 803 const VkDevice device = context.getDevice(); 804 const bool tessStageTest = (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT); 805 const VkPrimitiveTopology topology = tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 806 const deUint32 patchControlPoints = tessStageTest ? 3 : 0; 807 const std::vector<VkViewport> viewports (1, makeViewport(testParams.width, testParams.height)); 808 const std::vector<VkRect2D> scissors (1, makeRect2D(testParams.width, testParams.height)); 809 810 return vk::makeGraphicsPipeline (vkd, 811 device, 812 *m_pipelineLayout, 813 *m_vertShaderModule, 814 *m_tescShaderModule, 815 *m_teseShaderModule, 816 *m_geomShaderModule, 817 *m_fragShaderModule, 818 *m_renderPass, 819 viewports, 820 scissors, 821 topology, 822 0, 823 patchControlPoints); 824} 825 826void GraphicsConfiguration::initConfiguration (Context& context, 827 TestParams& testParams) 828{ 829 const InstanceInterface& vki = context.getInstanceInterface(); 830 const DeviceInterface& vkd = context.getDeviceInterface(); 831 const VkDevice device = context.getDevice(); 832 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 833 Allocator& allocator = context.getDefaultAllocator(); 834 vk::BinaryCollection& collection = context.getBinaryCollection(); 835 VkShaderStageFlags shaders = static_cast<VkShaderStageFlags>(0); 836 deUint32 shaderCount = 0; 837 838 VkPhysicalDeviceFeatures features; 839 vki.getPhysicalDeviceFeatures(physicalDevice, &features); 840 const bool pointSizeRequired = features.shaderTessellationAndGeometryPointSize; 841 842 if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT; 843 if (collection.contains(getGeomName(pointSizeRequired))) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT; 844 if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 845 if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 846 if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT; 847 848 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it) 849 shaderCount++; 850 851 if (collection.contains(getGeomName(!pointSizeRequired))) --shaderCount; 852 853 if (shaderCount != (deUint32)dePop32(shaders)) 854 TCU_THROW(InternalError, "Unused shaders detected in the collection"); 855 856 if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT)) m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0); 857 if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT)) m_geomShaderModule = createShaderModule(vkd, device, collection.get(getGeomName(pointSizeRequired)), 0); 858 if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)) m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0); 859 if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0); 860 if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT)) m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0); 861 862 m_descriptorSetLayout = DescriptorSetLayoutBuilder() 863 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS) 864 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS) 865 .build(vkd, device); 866 m_descriptorPool = DescriptorPoolBuilder() 867 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 868 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 869 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 870 m_descriptorSet = makeDescriptorSet (vkd, device, *m_descriptorPool, *m_descriptorSetLayout); 871 m_framebufferImage = makeImage (vkd, device, makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)); 872 m_framebufferImageAlloc = bindImage (vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any); 873 m_framebufferAttachment = makeImageView (vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)); 874 m_renderPass = makeRenderPass (vkd, device, m_framebufferFormat); 875 m_framebuffer = makeFramebuffer (vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height); 876 m_pipelineLayout = makePipelineLayout (vkd, device, m_descriptorSetLayout.get()); 877 m_pipeline = makeGraphicsPipeline (context, testParams); 878 879 initVertexBuffer(context, testParams); 880} 881 882void GraphicsConfiguration::fillCommandBuffer (Context& context, 883 TestParams& testParams, 884 VkCommandBuffer cmdBuffer, 885 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 886 const VkDescriptorImageInfo& resultImageInfo) 887{ 888 const DeviceInterface& vkd = context.getDeviceInterface(); 889 const VkDevice device = context.getDevice(); 890 const VkDeviceSize vertexBufferOffset = 0; 891 const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = 892 { 893 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 894 DE_NULL, // const void* pNext; 895 1u, // deUint32 accelerationStructureCount; 896 rayQueryTopAccelerationStructurePtr, // const VkAccelerationStructureKHR* pAccelerationStructures; 897 }; 898 899 DescriptorSetUpdateBuilder() 900 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo) 901 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet) 902 .update(vkd, device); 903 904 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL); 905 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 906 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset); 907 908 beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4()); 909 910 vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u); 911 912 endRenderPass(vkd, cmdBuffer); 913} 914 915class ComputeConfiguration : public PipelineConfiguration 916{ 917public: 918 ComputeConfiguration (); 919 virtual ~ComputeConfiguration () {} 920 921 static void checkSupport (Context& context, 922 const TestParams& testParams); 923 static void initPrograms (SourceCollections& programCollection, 924 const TestParams& testParams); 925 926 virtual void initConfiguration (Context& context, 927 TestParams& testParams) override; 928 virtual void fillCommandBuffer (Context& context, 929 TestParams& testParams, 930 VkCommandBuffer commandBuffer, 931 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 932 const VkDescriptorImageInfo& resultImageInfo) override; 933 934protected: 935 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 936 Move<VkDescriptorPool> m_descriptorPool; 937 Move<VkDescriptorSet> m_descriptorSet; 938 Move<VkPipelineLayout> m_pipelineLayout; 939 940 Move<VkShaderModule> m_shaderModule; 941 942 Move<VkPipeline> m_pipeline; 943}; 944 945ComputeConfiguration::ComputeConfiguration () 946 : PipelineConfiguration () 947 , m_descriptorSetLayout () 948 , m_descriptorPool () 949 , m_descriptorSet () 950 , m_pipelineLayout () 951 952 , m_shaderModule () 953 954 , m_pipeline () 955{ 956} 957 958void ComputeConfiguration::checkSupport (Context& context, 959 const TestParams& testParams) 960{ 961 DE_UNREF(context); 962 DE_UNREF(testParams); 963} 964 965void ComputeConfiguration::initPrograms (SourceCollections& programCollection, 966 const TestParams& testParams) 967{ 968 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 969 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams); 970 const std::string testBody = 971 " ivec3 pos = ivec3(gl_WorkGroupID);\n" 972 " ivec3 size = ivec3(gl_NumWorkGroups);\n" 973 + testShaderBody; 974 975 switch (testParams.stage) 976 { 977 case VK_SHADER_STAGE_COMPUTE_BIT: 978 { 979 std::stringstream css; 980 css << 981 "#version 460 core\n" 982 "#extension GL_EXT_ray_query : require\n" 983 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 984 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 985 "\n" 986 "void main()\n" 987 "{\n" 988 << testBody << 989 "}\n"; 990 991 programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(css.str())) << buildOptions; 992 993 break; 994 } 995 996 default: 997 TCU_THROW(InternalError, "Unknown stage"); 998 } 999} 1000 1001void ComputeConfiguration::initConfiguration (Context& context, 1002 TestParams& testParams) 1003{ 1004 DE_UNREF(testParams); 1005 1006 const DeviceInterface& vkd = context.getDeviceInterface(); 1007 const VkDevice device = context.getDevice(); 1008 vk::BinaryCollection& collection = context.getBinaryCollection(); 1009 1010 m_descriptorSetLayout = DescriptorSetLayoutBuilder() 1011 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1012 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT) 1013 .build(vkd, device); 1014 m_descriptorPool = DescriptorPoolBuilder() 1015 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 1016 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 1017 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1018 m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout); 1019 m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get()); 1020 m_shaderModule = createShaderModule(vkd, device, collection.get("comp"), 0); 1021 m_pipeline = makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule); 1022} 1023 1024void ComputeConfiguration::fillCommandBuffer (Context& context, 1025 TestParams& testParams, 1026 VkCommandBuffer cmdBuffer, 1027 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 1028 const VkDescriptorImageInfo& resultImageInfo) 1029{ 1030 const DeviceInterface& vkd = context.getDeviceInterface(); 1031 const VkDevice device = context.getDevice(); 1032 const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = 1033 { 1034 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 1035 DE_NULL, // const void* pNext; 1036 1u, // deUint32 accelerationStructureCount; 1037 rayQueryTopAccelerationStructurePtr, // const VkAccelerationStructureKHR* pAccelerationStructures; 1038 }; 1039 1040 DescriptorSetUpdateBuilder() 1041 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo) 1042 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet) 1043 .update(vkd, device); 1044 1045 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL); 1046 1047 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get()); 1048 1049 vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1); 1050} 1051 1052class RayTracingConfiguration : public PipelineConfiguration 1053{ 1054public: 1055 RayTracingConfiguration (); 1056 virtual ~RayTracingConfiguration () {} 1057 1058 static void checkSupport (Context& context, 1059 const TestParams& testParams); 1060 static void initPrograms (SourceCollections& programCollection, 1061 const TestParams& testParams); 1062 1063 virtual void initConfiguration (Context& context, 1064 TestParams& testParams) override; 1065 virtual void fillCommandBuffer (Context& context, 1066 TestParams& testParams, 1067 VkCommandBuffer commandBuffer, 1068 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 1069 const VkDescriptorImageInfo& resultImageInfo) override; 1070 1071protected: 1072 de::MovePtr<BufferWithMemory> createShaderBindingTable (const InstanceInterface& vki, 1073 const DeviceInterface& vkd, 1074 const VkDevice device, 1075 const VkPhysicalDevice physicalDevice, 1076 const VkPipeline pipeline, 1077 Allocator& allocator, 1078 de::MovePtr<RayTracingPipeline>& rayTracingPipeline, 1079 const deUint32 group); 1080 1081protected: 1082 deUint32 m_shaders; 1083 deUint32 m_raygenShaderGroup; 1084 deUint32 m_missShaderGroup; 1085 deUint32 m_hitShaderGroup; 1086 deUint32 m_callableShaderGroup; 1087 deUint32 m_shaderGroupCount; 1088 1089 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1090 Move<VkDescriptorPool> m_descriptorPool; 1091 Move<VkDescriptorSet> m_descriptorSet; 1092 Move<VkPipelineLayout> m_pipelineLayout; 1093 1094 de::MovePtr<RayTracingPipeline> m_rayTracingPipeline; 1095 Move<VkPipeline> m_pipeline; 1096 1097 de::MovePtr<BufferWithMemory> m_raygenShaderBindingTable; 1098 de::MovePtr<BufferWithMemory> m_hitShaderBindingTable; 1099 de::MovePtr<BufferWithMemory> m_missShaderBindingTable; 1100 de::MovePtr<BufferWithMemory> m_callableShaderBindingTable; 1101 1102 VkStridedDeviceAddressRegionKHR m_raygenShaderBindingTableRegion; 1103 VkStridedDeviceAddressRegionKHR m_missShaderBindingTableRegion; 1104 VkStridedDeviceAddressRegionKHR m_hitShaderBindingTableRegion; 1105 VkStridedDeviceAddressRegionKHR m_callableShaderBindingTableRegion; 1106 1107 de::SharedPtr<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructure; 1108 de::SharedPtr<TopLevelAccelerationStructure> m_topLevelAccelerationStructure; 1109}; 1110 1111RayTracingConfiguration::RayTracingConfiguration() 1112 : m_shaders (0) 1113 , m_raygenShaderGroup (~0u) 1114 , m_missShaderGroup (~0u) 1115 , m_hitShaderGroup (~0u) 1116 , m_callableShaderGroup (~0u) 1117 , m_shaderGroupCount (0) 1118 1119 , m_descriptorSetLayout () 1120 , m_descriptorPool () 1121 , m_descriptorSet () 1122 , m_pipelineLayout () 1123 1124 , m_rayTracingPipeline () 1125 , m_pipeline () 1126 1127 , m_raygenShaderBindingTable () 1128 , m_hitShaderBindingTable () 1129 , m_missShaderBindingTable () 1130 , m_callableShaderBindingTable () 1131 1132 , m_raygenShaderBindingTableRegion () 1133 , m_missShaderBindingTableRegion () 1134 , m_hitShaderBindingTableRegion () 1135 , m_callableShaderBindingTableRegion () 1136 1137 , m_bottomLevelAccelerationStructure () 1138 , m_topLevelAccelerationStructure () 1139{ 1140} 1141 1142void RayTracingConfiguration::checkSupport (Context& context, 1143 const TestParams& testParams) 1144{ 1145 DE_UNREF(testParams); 1146 1147 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 1148 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures(); 1149 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE) 1150 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline"); 1151} 1152 1153void RayTracingConfiguration::initPrograms (SourceCollections& programCollection, 1154 const TestParams& testParams) 1155{ 1156 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 1157 1158 const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams); 1159 const std::string testBody = 1160 " ivec3 pos = ivec3(gl_LaunchIDEXT);\n" 1161 " ivec3 size = ivec3(gl_LaunchSizeEXT);\n" 1162 + testShaderBody; 1163 1164 switch (testParams.stage) 1165 { 1166 case VK_SHADER_STAGE_RAYGEN_BIT_KHR: 1167 { 1168 std::stringstream css; 1169 css << 1170 "#version 460 core\n" 1171 "#extension GL_EXT_ray_tracing : require\n" 1172 "#extension GL_EXT_ray_query : require\n" 1173 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 1174 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 1175 "\n" 1176 "void main()\n" 1177 "{\n" 1178 << testBody << 1179 "}\n"; 1180 1181 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions; 1182 1183 break; 1184 } 1185 1186 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: 1187 { 1188 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions; 1189 1190 { 1191 std::stringstream css; 1192 css << 1193 "#version 460 core\n" 1194 "#extension GL_EXT_ray_tracing : require\n" 1195 "#extension GL_EXT_ray_query : require\n" 1196 "hitAttributeEXT vec3 attribs;\n" 1197 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 1198 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 1199 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 1200 "\n" 1201 "void main()\n" 1202 "{\n" 1203 << testBody << 1204 "}\n"; 1205 1206 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions; 1207 } 1208 1209 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1210 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions; 1211 1212 break; 1213 } 1214 1215 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: 1216 { 1217 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions; 1218 1219 { 1220 std::stringstream css; 1221 css << 1222 "#version 460 core\n" 1223 "#extension GL_EXT_ray_tracing : require\n" 1224 "#extension GL_EXT_ray_query : require\n" 1225 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 1226 "hitAttributeEXT vec3 attribs;\n" 1227 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 1228 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 1229 "\n" 1230 "void main()\n" 1231 "{\n" 1232 << testBody << 1233 "}\n"; 1234 1235 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions; 1236 } 1237 1238 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1239 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions; 1240 1241 break; 1242 } 1243 1244 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: 1245 { 1246 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions; 1247 1248 { 1249 std::stringstream css; 1250 css << 1251 "#version 460 core\n" 1252 "#extension GL_EXT_ray_tracing : require\n" 1253 "#extension GL_EXT_ray_query : require\n" 1254 "hitAttributeEXT vec3 hitAttribute;\n" 1255 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 1256 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 1257 "\n" 1258 "void main()\n" 1259 "{\n" 1260 << testBody << 1261 " hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n" 1262 " reportIntersectionEXT(1.0f, 0);\n" 1263 "}\n"; 1264 1265 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions; 1266 } 1267 1268 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1269 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1270 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions; 1271 1272 break; 1273 } 1274 1275 case VK_SHADER_STAGE_MISS_BIT_KHR: 1276 { 1277 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions; 1278 1279 { 1280 std::stringstream css; 1281 css << 1282 "#version 460 core\n" 1283 "#extension GL_EXT_ray_tracing : require\n" 1284 "#extension GL_EXT_ray_query : require\n" 1285 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 1286 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 1287 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 1288 "\n" 1289 "void main()\n" 1290 "{\n" 1291 << testBody << 1292 "}\n"; 1293 1294 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions; 1295 } 1296 1297 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1298 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1299 1300 break; 1301 } 1302 1303 case VK_SHADER_STAGE_CALLABLE_BIT_KHR: 1304 { 1305 { 1306 std::stringstream css; 1307 css << 1308 "#version 460 core\n" 1309 "#extension GL_EXT_ray_tracing : require\n" 1310 "#extension GL_EXT_ray_query : require\n" 1311 "layout(location = 0) callableDataEXT float dummy;" 1312 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n" 1313 "\n" 1314 "void main()\n" 1315 "{\n" 1316 " executeCallableEXT(0, 0);\n" 1317 "}\n"; 1318 1319 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions; 1320 } 1321 1322 { 1323 std::stringstream css; 1324 css << 1325 "#version 460 core\n" 1326 "#extension GL_EXT_ray_tracing : require\n" 1327 "#extension GL_EXT_ray_query : require\n" 1328 "layout(location = 0) callableDataInEXT float dummy;" 1329 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n" 1330 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n" 1331 "\n" 1332 "void main()\n" 1333 "{\n" 1334 << testBody << 1335 "}\n"; 1336 1337 programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions; 1338 } 1339 1340 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1341 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions; 1342 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions; 1343 1344 break; 1345 } 1346 1347 default: 1348 TCU_THROW(InternalError, "Unknown stage"); 1349 } 1350} 1351 1352de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable (const InstanceInterface& vki, 1353 const DeviceInterface& vkd, 1354 const VkDevice device, 1355 const VkPhysicalDevice physicalDevice, 1356 const VkPipeline pipeline, 1357 Allocator& allocator, 1358 de::MovePtr<RayTracingPipeline>& rayTracingPipeline, 1359 const deUint32 group) 1360{ 1361 de::MovePtr<BufferWithMemory> shaderBindingTable; 1362 1363 if (group < m_shaderGroupCount) 1364 { 1365 const deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice); 1366 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice); 1367 1368 shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u); 1369 } 1370 1371 return shaderBindingTable; 1372} 1373 1374void RayTracingConfiguration::initConfiguration (Context& context, 1375 TestParams& testParams) 1376{ 1377 DE_UNREF(testParams); 1378 1379 const InstanceInterface& vki = context.getInstanceInterface(); 1380 const DeviceInterface& vkd = context.getDeviceInterface(); 1381 const VkDevice device = context.getDevice(); 1382 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1383 vk::BinaryCollection& collection = context.getBinaryCollection(); 1384 Allocator& allocator = context.getDefaultAllocator(); 1385 const deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice); 1386 const VkShaderStageFlags hitStages = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR; 1387 deUint32 shaderCount = 0; 1388 1389 m_shaderGroupCount = 0; 1390 1391 if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR; 1392 if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR; 1393 if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; 1394 if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR; 1395 if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR; 1396 if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; 1397 1398 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it) 1399 shaderCount++; 1400 1401 if (shaderCount != (deUint32)dePop32(m_shaders)) 1402 TCU_THROW(InternalError, "Unused shaders detected in the collection"); 1403 1404 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR)) 1405 m_raygenShaderGroup = m_shaderGroupCount++; 1406 1407 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR)) 1408 m_missShaderGroup = m_shaderGroupCount++; 1409 1410 if (0 != (m_shaders & hitStages)) 1411 m_hitShaderGroup = m_shaderGroupCount++; 1412 1413 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR)) 1414 m_callableShaderGroup = m_shaderGroupCount++; 1415 1416 m_rayTracingPipeline = de::newMovePtr<RayTracingPipeline>(); 1417 1418 m_descriptorSetLayout = DescriptorSetLayoutBuilder() 1419 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES) 1420 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES) 1421 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES) 1422 .build(vkd, device); 1423 m_descriptorPool = DescriptorPoolBuilder() 1424 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 1425 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 1426 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 1427 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1428 m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout); 1429 1430 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR , createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup); 1431 if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup); 1432 if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup); 1433 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR , createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup); 1434 if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR , createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup); 1435 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR)) m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR , createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup); 1436 1437 m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get()); 1438 m_pipeline = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout); 1439 1440 m_raygenShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup); 1441 m_missShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup); 1442 m_hitShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup); 1443 m_callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup); 1444 1445 m_raygenShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable), shaderGroupHandleSize); 1446 m_missShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable), shaderGroupHandleSize); 1447 m_hitShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable), shaderGroupHandleSize); 1448 m_callableShaderBindingTableRegion = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable), shaderGroupHandleSize); 1449} 1450 1451void RayTracingConfiguration::fillCommandBuffer (Context& context, 1452 TestParams& testParams, 1453 VkCommandBuffer commandBuffer, 1454 const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr, 1455 const VkDescriptorImageInfo& resultImageInfo) 1456{ 1457 const DeviceInterface& vkd = context.getDeviceInterface(); 1458 const VkDevice device = context.getDevice(); 1459 Allocator& allocator = context.getDefaultAllocator(); 1460 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 1461 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure = makeTopLevelAccelerationStructure(); 1462 1463 m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()); 1464 m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage); 1465 m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator); 1466 1467 m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release()); 1468 m_topLevelAccelerationStructure->setInstanceCount(1); 1469 m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure); 1470 m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator); 1471 1472 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = m_topLevelAccelerationStructure.get(); 1473 const VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = 1474 { 1475 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 1476 DE_NULL, // const void* pNext; 1477 1u, // deUint32 accelerationStructureCount; 1478 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures; 1479 }; 1480 const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = 1481 { 1482 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 1483 DE_NULL, // const void* pNext; 1484 1u, // deUint32 accelerationStructureCount; 1485 rayQueryTopAccelerationStructurePtr, // const VkAccelerationStructureKHR* pAccelerationStructures; 1486 }; 1487 1488 DescriptorSetUpdateBuilder() 1489 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo) 1490 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet) 1491 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet) 1492 .update(vkd, device); 1493 1494 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL); 1495 1496 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get()); 1497 1498 cmdTraceRays(vkd, 1499 commandBuffer, 1500 &m_raygenShaderBindingTableRegion, 1501 &m_missShaderBindingTableRegion, 1502 &m_hitShaderBindingTableRegion, 1503 &m_callableShaderBindingTableRegion, 1504 testParams.width, testParams.height, 1); 1505} 1506 1507 1508const std::string getShaderBodyText (const TestParams& testParams) 1509{ 1510 if (testParams.geomType == GEOM_TYPE_AABBS) 1511 { 1512 const std::string result = 1513 " uint rayFlags = 0;\n" 1514 " uint cullMask = 0xFF;\n" 1515 " float tmin = 0.0;\n" 1516 " float tmax = 9.0;\n" 1517 " vec3 origin = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n" 1518 " vec3 direct = vec3(0.0, 0.0, -1.0);\n" 1519 " uint count = 0;\n" 1520 " rayQueryEXT rayQuery;\n" 1521 "\n" 1522 " rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n" 1523 "\n" 1524 " while(rayQueryProceedEXT(rayQuery))\n" 1525 " {\n" 1526 " if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n" 1527 " {\n" 1528 " rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n" 1529 " count++;\n" 1530 " }\n" 1531 " }\n" 1532 " imageStore(result, pos, ivec4(count, 0, 0, 0));\n" 1533 "\n"; 1534 1535 return result; 1536 } 1537 else if (testParams.geomType == GEOM_TYPE_TRIANGLES) 1538 { 1539 const std::string result = 1540 " uint rayFlags = gl_RayFlagsNoOpaqueEXT;\n" 1541 " uint cullMask = 0xFF;\n" 1542 " float tmin = 0.0;\n" 1543 " float tmax = 9.0;\n" 1544 " vec3 origin = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n" 1545 " vec3 direct = vec3(0.0, 0.0, -1.0);\n" 1546 " uint count = 0;\n" 1547 " rayQueryEXT rayQuery;\n" 1548 "\n" 1549 " rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n" 1550 "\n" 1551 " while(rayQueryProceedEXT(rayQuery))\n" 1552 " {\n" 1553 " if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n" 1554 " {\n" 1555 " rayQueryConfirmIntersectionEXT(rayQuery);\n" 1556 " count++;\n" 1557 " }\n" 1558 " }\n" 1559 " imageStore(result, pos, ivec4(count, 0, 0, 0));\n" 1560 "\n"; 1561 1562 return result; 1563 } 1564 else 1565 { 1566 TCU_THROW(InternalError, "Unknown geometry type"); 1567 } 1568} 1569 1570 1571class TestConfigurationNoMiss : public TestConfiguration 1572{ 1573public: 1574 virtual const VkAccelerationStructureKHR* initAccelerationStructures (Context& context, 1575 TestParams& testParams, 1576 VkCommandBuffer cmdBuffer) override; 1577 1578 virtual bool verify (BufferWithMemory* resultBuffer, 1579 Context& context, 1580 TestParams& testParams) override; 1581private: 1582 deUint32 chooseAABB (de::Random& rng, 1583 const std::vector<tcu::Vec2>& vertices, 1584 const std::vector<tcu::UVec2>& aabbs); 1585 deUint32 chooseTriangle (de::Random& rng, 1586 const std::vector<tcu::Vec2>& vertices, 1587 const std::vector<tcu::UVec3>& triangles); 1588}; 1589 1590deUint32 TestConfigurationNoMiss::chooseAABB (de::Random& rng, 1591 const std::vector<tcu::Vec2>& vertices, 1592 const std::vector<tcu::UVec2>& aabbs) 1593{ 1594 while (true) 1595 { 1596 const deUint32 n = (deUint32)rng.getInt(0, (deUint32)aabbs.size() - 1); 1597 const tcu::UVec2& t = aabbs[n]; 1598 const tcu::Vec2& a = vertices[t.x()]; 1599 const tcu::Vec2& b = vertices[t.y()]; 1600 1601 if (deFloatAbs(a.x() - b.x()) < MIN_AABB_SIDE_LENGTH || deFloatAbs(a.y() - b.y()) < MIN_AABB_SIDE_LENGTH) 1602 continue; 1603 1604 return n; 1605 } 1606} 1607 1608deUint32 TestConfigurationNoMiss::chooseTriangle (de::Random& rng, 1609 const std::vector<tcu::Vec2>& vertices, 1610 const std::vector<tcu::UVec3>& triangles) 1611{ 1612 while (true) 1613 { 1614 const deUint32 n = (deUint32)rng.getInt(0, (deUint32)triangles.size() - 1); 1615 const tcu::UVec3& t = triangles[n]; 1616 const tcu::Vec2& a = vertices[t.x()]; 1617 const tcu::Vec2& b = vertices[t.y()]; 1618 const tcu::Vec2& c = vertices[t.z()]; 1619 const float ab = triangleEdgeLength(a, b); 1620 const float bc = triangleEdgeLength(b, c); 1621 const float ca = triangleEdgeLength(c, a); 1622 1623 if (ab < MIN_TRIANGLE_EDGE_LENGTH || bc < MIN_TRIANGLE_EDGE_LENGTH || ca < MIN_TRIANGLE_EDGE_LENGTH || triangleArea(ab, bc, ca) < MIN_TRIANGLE_AREA_SIZE) 1624 continue; 1625 1626 return n; 1627 } 1628} 1629 1630const VkAccelerationStructureKHR* TestConfigurationNoMiss::initAccelerationStructures (Context& context, 1631 TestParams& testParams, 1632 VkCommandBuffer cmdBuffer) 1633{ 1634 const DeviceInterface& vkd = context.getDeviceInterface(); 1635 const VkDevice device = context.getDevice(); 1636 Allocator& allocator = context.getDefaultAllocator(); 1637 const tcu::Vec2 centerPixelCenter = tcu::Vec2(0.5f - 0.5f / float(testParams.width), 0.5f - 0.5f / float(testParams.height)); 1638 de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 1639 de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure(); 1640 de::Random rng (testParams.randomSeed); 1641 std::vector<tcu::Vec3> geometryData; 1642 1643 if (testParams.geomType == GEOM_TYPE_AABBS) 1644 { 1645 std::vector<tcu::UVec2> aabbs; 1646 std::vector<tcu::Vec2> vertices; 1647 1648 vertices.reserve(2u * testParams.squaresGroupCount); 1649 aabbs.reserve(testParams.squaresGroupCount); 1650 1651 { 1652 // a---g---+ 1653 // | | | 1654 // e---d---h 1655 // | | | 1656 // +---f---b 1657 // 1658 // a-d, d-b, e-f, g-h 1659 1660 const tcu::Vec2 d = centerPixelCenter; 1661 const tcu::Vec2 a = tcu::Vec2(0.0f, 0.0f); 1662 const tcu::Vec2 b = tcu::Vec2(1.0f, 1.0f); 1663 const tcu::Vec2 e = tcu::Vec2(a.x(), d.y()); 1664 const tcu::Vec2 f = tcu::Vec2(d.x(), b.y()); 1665 const tcu::Vec2 g = tcu::Vec2(d.x(), a.y()); 1666 const tcu::Vec2 h = tcu::Vec2(b.x(), d.y()); 1667 const deUint32 A = 0; 1668 const deUint32 B = 1; 1669 const deUint32 D = 2; 1670 const deUint32 E = 3; 1671 const deUint32 F = 4; 1672 const deUint32 G = 5; 1673 const deUint32 H = 6; 1674 1675 vertices.push_back(a); 1676 vertices.push_back(b); 1677 vertices.push_back(d); 1678 vertices.push_back(e); 1679 vertices.push_back(f); 1680 vertices.push_back(g); 1681 vertices.push_back(h); 1682 1683 aabbs.push_back(tcu::UVec2(A, D)); 1684 aabbs.push_back(tcu::UVec2(D, B)); 1685 aabbs.push_back(tcu::UVec2(E, F)); 1686 aabbs.push_back(tcu::UVec2(G, H)); 1687 } 1688 1689 while (aabbs.size() < testParams.squaresGroupCount) 1690 { 1691 // a-------+ a---g---+ 1692 // | | | | | 1693 // | | -> e---d---h 1694 // | | | | | 1695 // +-------b +---f---b 1696 // 1697 // a-b -> a-d, d-b, e-f, g-h 1698 1699 const deUint32 n = chooseAABB(rng, vertices, aabbs); 1700 tcu::UVec2& t = aabbs[n]; 1701 const tcu::Vec2& a = vertices[t.x()]; 1702 const tcu::Vec2& b = vertices[t.y()]; 1703 const float alfa = rng.getFloat(0.2f, 0.8f); 1704 const float beta = rng.getFloat(0.2f, 0.8f); 1705 const tcu::Vec2 d = mixCoordsVec2(a, b, alfa, beta); 1706 const tcu::Vec2 e = tcu::Vec2(a.x(), d.y()); 1707 const tcu::Vec2 f = tcu::Vec2(d.x(), b.y()); 1708 const tcu::Vec2 g = tcu::Vec2(d.x(), a.y()); 1709 const tcu::Vec2 h = tcu::Vec2(b.x(), d.y()); 1710 const deUint32 B = t.y(); 1711 const deUint32 D = (deUint32)vertices.size(); 1712 const deUint32 E = D + 1; 1713 const deUint32 F = D + 2; 1714 const deUint32 G = D + 3; 1715 const deUint32 H = D + 4; 1716 1717 if (d.x() <= a.x() || d.x() >= b.x() || d.y() <= a.y() || d.y() >= b.y()) 1718 continue; 1719 1720 vertices.push_back(d); 1721 vertices.push_back(e); 1722 vertices.push_back(f); 1723 vertices.push_back(g); 1724 vertices.push_back(h); 1725 1726 t.y() = D; 1727 aabbs.push_back(tcu::UVec2(D, B)); 1728 aabbs.push_back(tcu::UVec2(E, F)); 1729 aabbs.push_back(tcu::UVec2(G, H)); 1730 } 1731 1732 geometryData.reserve(2u * aabbs.size()); 1733 1734 for (size_t i = 0; i < aabbs.size(); ++i) 1735 { 1736 const tcu::Vec2& a = vertices[aabbs[i].x()]; 1737 const tcu::Vec2& b = vertices[aabbs[i].y()]; 1738 const float az = -rng.getFloat(0.1f, 0.5f); 1739 const float bz = az + 0.01f; 1740 const tcu::Vec3 A = tcu::Vec3(a.x(), a.y(), az); 1741 const tcu::Vec3 B = tcu::Vec3(b.x(), b.y(), bz); 1742 1743 geometryData.push_back(A); 1744 geometryData.push_back(B); 1745 } 1746 } 1747 else if (testParams.geomType == GEOM_TYPE_TRIANGLES) 1748 { 1749 std::vector<tcu::UVec3> triangles; 1750 std::vector<tcu::Vec2> vertices; 1751 std::vector<float> verticesZ; 1752 1753 vertices.reserve(3u * testParams.squaresGroupCount); 1754 triangles.reserve(testParams.squaresGroupCount); 1755 1756 { 1757 // Initial triangle set: aeb, bec, cef, fei, ieh, heg, ged, dea 1758 // e - is not math middle, but centrum of one of the pixels 1759 // a---b---c 1760 // | \ | / | 1761 // d---e---f 1762 // | / | \ | 1763 // g---h---i 1764 1765 const tcu::Vec2 e = centerPixelCenter; 1766 const tcu::Vec2 a = tcu::Vec2( 0.0f, 0.0f); 1767 const tcu::Vec2 i = tcu::Vec2( 1.0f, 1.0f); 1768 const tcu::Vec2 c = tcu::Vec2(i.x(), a.y()); 1769 const tcu::Vec2 g = tcu::Vec2(a.x(), i.y()); 1770 const tcu::Vec2 b = tcu::Vec2(e.x(), a.y()); 1771 const tcu::Vec2 d = tcu::Vec2(a.x(), e.y()); 1772 const tcu::Vec2 f = tcu::Vec2(i.x(), e.y()); 1773 const tcu::Vec2 h = tcu::Vec2(e.x(), i.y()); 1774 const deUint32 A = 0; 1775 const deUint32 B = 1; 1776 const deUint32 C = 2; 1777 const deUint32 D = 3; 1778 const deUint32 E = 4; 1779 const deUint32 F = 5; 1780 const deUint32 G = 6; 1781 const deUint32 H = 7; 1782 const deUint32 I = 8; 1783 1784 vertices.push_back(a); 1785 vertices.push_back(b); 1786 vertices.push_back(c); 1787 vertices.push_back(d); 1788 vertices.push_back(e); 1789 vertices.push_back(f); 1790 vertices.push_back(g); 1791 vertices.push_back(h); 1792 vertices.push_back(i); 1793 1794 triangles.push_back(tcu::UVec3(A, E, B)); 1795 triangles.push_back(tcu::UVec3(B, E, C)); 1796 triangles.push_back(tcu::UVec3(C, E, F)); 1797 triangles.push_back(tcu::UVec3(F, E, I)); 1798 triangles.push_back(tcu::UVec3(I, E, H)); 1799 triangles.push_back(tcu::UVec3(H, E, G)); 1800 triangles.push_back(tcu::UVec3(G, E, D)); 1801 triangles.push_back(tcu::UVec3(D, E, A)); 1802 } 1803 1804 while (triangles.size() < testParams.squaresGroupCount) 1805 { 1806 const deUint32 n = chooseTriangle(rng, vertices, triangles); 1807 tcu::UVec3& t = triangles[n]; 1808 const tcu::Vec2& a = vertices[t.x()]; 1809 const tcu::Vec2& b = vertices[t.y()]; 1810 const tcu::Vec2& c = vertices[t.z()]; 1811 const float alfa = rng.getFloat(0.2f, 0.8f); 1812 const float beta = rng.getFloat(0.2f, 0.8f); 1813 const tcu::Vec2 d = mixVec2(mixVec2(a, b, alfa), c, beta); 1814 const deUint32& p = t.x(); 1815 const deUint32& q = t.y(); 1816 deUint32& r = t.z(); 1817 const deUint32 R = (deUint32)vertices.size(); 1818 1819 vertices.push_back(d); 1820 1821 triangles.push_back(tcu::UVec3(q, r, R)); 1822 triangles.push_back(tcu::UVec3(p, r, R)); 1823 r = R; 1824 } 1825 1826 verticesZ.reserve(vertices.size()); 1827 for (size_t i = 0; i < vertices.size(); ++i) 1828 verticesZ.push_back(-rng.getFloat(0.01f, 0.99f)); 1829 1830 geometryData.reserve(3u * triangles.size()); 1831 1832 for (size_t i = 0; i < triangles.size(); ++i) 1833 { 1834 const deUint32 a = triangles[i].x(); 1835 const deUint32 b = triangles[i].y(); 1836 const deUint32 c = triangles[i].z(); 1837 1838 geometryData.push_back(tcu::Vec3(vertices[a].x(), vertices[a].y(), verticesZ[a])); 1839 geometryData.push_back(tcu::Vec3(vertices[b].x(), vertices[b].y(), verticesZ[b])); 1840 geometryData.push_back(tcu::Vec3(vertices[c].x(), vertices[c].y(), verticesZ[c])); 1841 } 1842 } 1843 else 1844 { 1845 TCU_THROW(InternalError, "Unknown geometry type"); 1846 } 1847 1848 rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u); 1849 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, testParams.geomType == GEOM_TYPE_TRIANGLES); 1850 rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator); 1851 m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release())); 1852 m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release()); 1853 m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back()); 1854 m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator); 1855 1856 return m_topAccelerationStructure.get()->getPtr(); 1857} 1858 1859bool TestConfigurationNoMiss::verify (BufferWithMemory* resultBuffer, 1860 Context& context, 1861 TestParams& testParams) 1862{ 1863 tcu::TestLog& log = context.getTestContext().getLog(); 1864 const deUint32 width = testParams.width; 1865 const deUint32 height = testParams.height; 1866 const deInt32* resultPtr = (deInt32*)resultBuffer->getAllocation().getHostPtr(); 1867 deUint32 failures = 0; 1868 deUint32 pos = 0; 1869 1870 for (deUint32 y = 0; y < height; ++y) 1871 for (deUint32 x = 0; x < width; ++x) 1872 { 1873 if (resultPtr[pos] <= 0) 1874 failures++; 1875 1876 pos++; 1877 } 1878 1879 if (failures != 0) 1880 { 1881 std::stringstream css; 1882 1883 pos = 0; 1884 1885 for (deUint32 y = 0; y < height; ++y) 1886 { 1887 for (deUint32 x = 0; x < width; ++x) 1888 { 1889 if (resultPtr[pos] <= 0) 1890 css << std::setw(3) << resultPtr[pos] << ","; 1891 else 1892 css << "___,"; 1893 1894 pos++; 1895 } 1896 1897 css << std::endl; 1898 } 1899 1900 log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage; 1901 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage; 1902 } 1903 1904 return (failures == 0); 1905} 1906 1907 1908class TestConfigurationSingleHit : public TestConfigurationNoMiss 1909{ 1910public: 1911 virtual bool verify (BufferWithMemory* resultBuffer, 1912 Context& context, 1913 TestParams& testParams) override; 1914}; 1915 1916bool TestConfigurationSingleHit::verify (BufferWithMemory* resultBuffer, 1917 Context& context, 1918 TestParams& testParams) 1919{ 1920 tcu::TestLog& log = context.getTestContext().getLog(); 1921 const deUint32 width = testParams.width; 1922 const deUint32 height = testParams.height; 1923 const deInt32* resultPtr = (deInt32*)resultBuffer->getAllocation().getHostPtr(); 1924 const deInt32 expectedValue = 1; 1925 deUint32 failures = 0; 1926 deUint32 pos = 0; 1927 1928 for (deUint32 y = 0; y < height; ++y) 1929 for (deUint32 x = 0; x < width; ++x) 1930 { 1931 if (resultPtr[pos] != expectedValue) 1932 failures++; 1933 1934 pos++; 1935 } 1936 1937 if (failures != 0) 1938 { 1939 std::stringstream css; 1940 1941 pos = 0; 1942 1943 for (deUint32 y = 0; y < height; ++y) 1944 { 1945 for (deUint32 x = 0; x < width; ++x) 1946 { 1947 if (resultPtr[pos] != expectedValue) 1948 css << std::setw(3) << resultPtr[pos] << ","; 1949 else 1950 css << "___,"; 1951 1952 pos++; 1953 } 1954 1955 css << std::endl; 1956 } 1957 1958 log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage; 1959 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage; 1960 } 1961 1962 return (failures == 0); 1963} 1964 1965 1966class RayQueryBuiltinTestInstance : public TestInstance 1967{ 1968public: 1969 RayQueryBuiltinTestInstance (Context& context, const TestParams& data); 1970 virtual ~RayQueryBuiltinTestInstance (void); 1971 tcu::TestStatus iterate (void); 1972 1973private: 1974 TestParams m_data; 1975 de::MovePtr<TestConfiguration> m_testConfig; 1976 de::MovePtr<PipelineConfiguration> m_pipelineConfig; 1977}; 1978 1979RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance (Context& context, const TestParams& data) 1980 : vkt::TestInstance (context) 1981 , m_data (data) 1982{ 1983 switch (m_data.testType) 1984 { 1985 case TEST_TYPE_NO_MISS: m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNoMiss()); break; 1986 case TEST_TYPE_SINGLE_HIT: m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationSingleHit()); break; 1987 default: TCU_THROW(InternalError, "Unknown test type"); 1988 } 1989 1990 switch (m_data.stage) 1991 { 1992 case VK_SHADER_STAGE_VERTEX_BIT: 1993 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 1994 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 1995 case VK_SHADER_STAGE_GEOMETRY_BIT: 1996 case VK_SHADER_STAGE_FRAGMENT_BIT: 1997 { 1998 m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration()); 1999 break; 2000 } 2001 2002 case VK_SHADER_STAGE_COMPUTE_BIT: 2003 { 2004 m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration()); 2005 break; 2006 } 2007 2008 case VK_SHADER_STAGE_RAYGEN_BIT_KHR: 2009 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: 2010 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: 2011 case VK_SHADER_STAGE_MISS_BIT_KHR: 2012 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: 2013 case VK_SHADER_STAGE_CALLABLE_BIT_KHR: 2014 { 2015 m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration()); 2016 break; 2017 } 2018 2019 default: 2020 TCU_THROW(InternalError, "Unknown shader stage"); 2021 } 2022} 2023 2024RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance (void) 2025{ 2026} 2027 2028tcu::TestStatus RayQueryBuiltinTestInstance::iterate (void) 2029{ 2030 const DeviceInterface& vkd = m_context.getDeviceInterface(); 2031 const VkDevice device = m_context.getDevice(); 2032 const VkQueue queue = m_context.getUniversalQueue(); 2033 Allocator& allocator = m_context.getDefaultAllocator(); 2034 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 2035 2036 const deUint32 width = m_data.width; 2037 const deUint32 height = m_data.height; 2038 const deUint32 depth = m_data.depth; 2039 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.format, width, height, depth); 2040 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 2041 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any)); 2042 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange); 2043 2044 const deUint32 pixelSize = mapVkFormat(m_data.format).getPixelSize(); 2045 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT); 2046 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u); 2047 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers); 2048 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible)); 2049 2050 const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL); 2051 2052 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex); 2053 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2054 const VkAccelerationStructureKHR* topAccelerationStructurePtr = DE_NULL; 2055 2056 m_pipelineConfig->initConfiguration(m_context, m_data); 2057 2058 beginCommandBuffer(vkd, *cmdBuffer, 0u); 2059 { 2060 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange); 2061 const VkClearValue clearValue = makeClearValueColorU32(0u, 0u, 0u, 0u); 2062 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange); 2063 const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); 2064 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 2065 2066 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier); 2067 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange); 2068 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier); 2069 2070 topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_context, m_data, *cmdBuffer); 2071 2072 m_pipelineConfig->fillCommandBuffer(m_context, m_data, *cmdBuffer, topAccelerationStructurePtr, resultImageInfo); 2073 2074 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier); 2075 2076 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion); 2077 2078 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier); 2079 } 2080 endCommandBuffer(vkd, *cmdBuffer); 2081 2082 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 2083 2084 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE); 2085 2086 if (m_testConfig->verify(resultBuffer.get(), m_context, m_data)) 2087 return tcu::TestStatus::pass("Pass"); 2088 else 2089 return tcu::TestStatus::fail("Fail"); 2090} 2091 2092class RayQueryBuiltinTestCase : public TestCase 2093{ 2094 public: 2095 RayQueryBuiltinTestCase (tcu::TestContext& context, const char* name, const TestParams data); 2096 ~RayQueryBuiltinTestCase (void); 2097 2098 virtual void checkSupport (Context& context) const; 2099 virtual void initPrograms (SourceCollections& programCollection) const; 2100 virtual TestInstance* createInstance (Context& context) const; 2101 2102private: 2103 TestParams m_data; 2104}; 2105 2106RayQueryBuiltinTestCase::RayQueryBuiltinTestCase (tcu::TestContext& context, const char* name, const TestParams data) 2107 : vkt::TestCase (context, name) 2108 , m_data (data) 2109{ 2110} 2111 2112RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase (void) 2113{ 2114} 2115 2116void RayQueryBuiltinTestCase::checkSupport (Context& context) const 2117{ 2118 context.requireDeviceFunctionality("VK_KHR_acceleration_structure"); 2119 context.requireDeviceFunctionality("VK_KHR_ray_query"); 2120 2121 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures(); 2122 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE) 2123 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery"); 2124 2125 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures(); 2126 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE) 2127 TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure"); 2128 2129 m_data.pipelineCheckSupport(context, m_data); 2130} 2131 2132TestInstance* RayQueryBuiltinTestCase::createInstance (Context& context) const 2133{ 2134 return new RayQueryBuiltinTestInstance(context, m_data); 2135} 2136 2137void RayQueryBuiltinTestCase::initPrograms (SourceCollections& programCollection) const 2138{ 2139 m_data.pipelineInitPrograms(programCollection, m_data); 2140} 2141 2142static inline CheckSupportFunc getPipelineCheckSupport (const VkShaderStageFlagBits stage) 2143{ 2144 switch (stage) 2145 { 2146 case VK_SHADER_STAGE_VERTEX_BIT: 2147 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 2148 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 2149 case VK_SHADER_STAGE_GEOMETRY_BIT: 2150 case VK_SHADER_STAGE_FRAGMENT_BIT: 2151 return GraphicsConfiguration::checkSupport; 2152 2153 case VK_SHADER_STAGE_COMPUTE_BIT: 2154 return ComputeConfiguration::checkSupport; 2155 2156 case VK_SHADER_STAGE_RAYGEN_BIT_KHR: 2157 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: 2158 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: 2159 case VK_SHADER_STAGE_MISS_BIT_KHR: 2160 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: 2161 case VK_SHADER_STAGE_CALLABLE_BIT_KHR: 2162 return RayTracingConfiguration::checkSupport; 2163 2164 default: 2165 TCU_THROW(InternalError, "Unknown shader stage"); 2166 } 2167} 2168 2169static inline InitProgramsFunc getPipelineInitPrograms (const VkShaderStageFlagBits stage) 2170{ 2171 switch (stage) 2172 { 2173 case VK_SHADER_STAGE_VERTEX_BIT: 2174 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 2175 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 2176 case VK_SHADER_STAGE_GEOMETRY_BIT: 2177 case VK_SHADER_STAGE_FRAGMENT_BIT: 2178 return GraphicsConfiguration::initPrograms; 2179 2180 case VK_SHADER_STAGE_COMPUTE_BIT: 2181 return ComputeConfiguration::initPrograms; 2182 2183 case VK_SHADER_STAGE_RAYGEN_BIT_KHR: 2184 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: 2185 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: 2186 case VK_SHADER_STAGE_MISS_BIT_KHR: 2187 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: 2188 case VK_SHADER_STAGE_CALLABLE_BIT_KHR: 2189 return RayTracingConfiguration::initPrograms; 2190 2191 default: 2192 TCU_THROW(InternalError, "Unknown shader stage"); 2193 } 2194} 2195 2196static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType) 2197{ 2198 switch (testType) 2199 { 2200 case TEST_TYPE_NO_MISS: return getShaderBodyText; 2201 case TEST_TYPE_SINGLE_HIT: return getShaderBodyText; 2202 default: TCU_THROW(InternalError, "Unknown test type"); 2203 } 2204} 2205 2206} // anonymous 2207 2208tcu::TestCaseGroup* createWatertightnessTests (tcu::TestContext& testCtx) 2209{ 2210 const deUint32 seed = (deUint32)(testCtx.getCommandLine().getBaseSeed()); 2211 // Tests watertightness of ray query 2212 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "watertightness")); 2213 2214 const struct PipelineStages 2215 { 2216 VkShaderStageFlagBits stage; 2217 const char* name; 2218 } 2219 pipelineStages[] = 2220 { 2221 { VK_SHADER_STAGE_VERTEX_BIT, "vert" }, 2222 { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc" }, 2223 { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese" }, 2224 { VK_SHADER_STAGE_GEOMETRY_BIT, "geom" }, 2225 { VK_SHADER_STAGE_FRAGMENT_BIT, "frag" }, 2226 { VK_SHADER_STAGE_COMPUTE_BIT, "comp" }, 2227 { VK_SHADER_STAGE_RAYGEN_BIT_KHR, "rgen" }, 2228 { VK_SHADER_STAGE_ANY_HIT_BIT_KHR, "ahit" }, 2229 { VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, "chit" }, 2230 { VK_SHADER_STAGE_MISS_BIT_KHR, "miss" }, 2231 { VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "sect" }, 2232 { VK_SHADER_STAGE_CALLABLE_BIT_KHR, "call" }, 2233 }; 2234 const struct TestTypes 2235 { 2236 TestType testType; 2237 const char* name; 2238 } 2239 testTypes[] = 2240 { 2241 { TEST_TYPE_NO_MISS, "nomiss" }, 2242 { TEST_TYPE_SINGLE_HIT, "singlehit" }, 2243 }; 2244 const struct GeomTypes 2245 { 2246 GeomType geomType; 2247 const char* name; 2248 } 2249 geomTypes[] = 2250 { 2251 { GEOM_TYPE_TRIANGLES, "triangles" }, 2252 { GEOM_TYPE_AABBS, "aabbs" }, 2253 }; 2254 2255 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx) 2256 { 2257 de::MovePtr<tcu::TestCaseGroup> testTypeGroup (new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name)); 2258 const TestType testType = testTypes[testTypeNdx].testType; 2259 const ShaderBodyTextFunc shaderBodyTextFunc = getShaderBodyTextFunc(testType); 2260 const deUint32 imageDepth = 1; 2261 2262 for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx) 2263 { 2264 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup (new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name)); 2265 const VkShaderStageFlagBits stage = pipelineStages[pipelineStageNdx].stage; 2266 const CheckSupportFunc pipelineCheckSupport = getPipelineCheckSupport(stage); 2267 const InitProgramsFunc pipelineInitPrograms = getPipelineInitPrograms(stage); 2268 const deUint32 instancesGroupCount = 1; 2269 const deUint32 geometriesGroupCount = 1; 2270 const deUint32 squaresGroupCount = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount; 2271 2272 DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT); 2273 2274 for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx) 2275 { 2276 const GeomType geomType = geomTypes[geomTypeNdx].geomType; 2277 const TestParams testParams = 2278 { 2279 TEST_WIDTH, // deUint32 width; 2280 TEST_HEIGHT, // deUint32 height; 2281 imageDepth, // deUint32 depth; 2282 seed, // deUint32 randomSeed; 2283 testType, // TestType testType; 2284 stage, // VkShaderStageFlagBits stage; 2285 geomType, // GeomType geomType; 2286 squaresGroupCount, // deUint32 squaresGroupCount; 2287 geometriesGroupCount, // deUint32 geometriesGroupCount; 2288 instancesGroupCount, // deUint32 instancesGroupCount; 2289 VK_FORMAT_R32_SINT, // VkFormat format; 2290 pipelineCheckSupport, // CheckSupportFunc pipelineCheckSupport; 2291 pipelineInitPrograms, // InitProgramsFunc pipelineInitPrograms; 2292 shaderBodyTextFunc, // ShaderTestTextFunc testConfigShaderBodyText; 2293 }; 2294 2295 if (testType == TEST_TYPE_SINGLE_HIT && geomType == GEOM_TYPE_AABBS) 2296 continue; 2297 2298 sourceTypeGroup->addChild(new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, testParams)); 2299 } 2300 2301 testTypeGroup->addChild(sourceTypeGroup.release()); 2302 } 2303 2304 group->addChild(testTypeGroup.release()); 2305 } 2306 2307 return group.release(); 2308} 2309 2310} // RayQuery 2311} // vkt 2312