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 Testing acceleration structures in ray query extension 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktRayQueryAccelerationStructuresTests.hpp" 25 26#include <array> 27#include <set> 28#include <limits> 29 30#include "vkDefs.hpp" 31#include "deClock.h" 32#include "vktTestCase.hpp" 33#include "vktTestGroupUtil.hpp" 34#include "vkCmdUtil.hpp" 35#include "vkObjUtil.hpp" 36#include "vkBuilderUtil.hpp" 37#include "vkBarrierUtil.hpp" 38#include "vkBufferWithMemory.hpp" 39#include "vkImageWithMemory.hpp" 40#include "vkTypeUtil.hpp" 41#include "vkImageUtil.hpp" 42#include "vkRayTracingUtil.hpp" 43#include "deRandom.hpp" 44#include "tcuTexture.hpp" 45#include "tcuTextureUtil.hpp" 46#include "tcuTestLog.hpp" 47#include "tcuImageCompare.hpp" 48#include "tcuFloat.hpp" 49#include "deModularCounter.hpp" 50 51namespace vkt 52{ 53namespace RayQuery 54{ 55namespace 56{ 57using namespace vk; 58using namespace vkt; 59 60static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR 61 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR 62 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR 63 | VK_SHADER_STAGE_MISS_BIT_KHR 64 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR 65 | VK_SHADER_STAGE_CALLABLE_BIT_KHR; 66 67enum ShaderSourcePipeline 68{ 69 SSP_GRAPHICS_PIPELINE, 70 SSP_COMPUTE_PIPELINE, 71 SSP_RAY_TRACING_PIPELINE 72}; 73 74enum ShaderSourceType 75{ 76 SST_VERTEX_SHADER, 77 SST_TESSELATION_CONTROL_SHADER, 78 SST_TESSELATION_EVALUATION_SHADER, 79 SST_GEOMETRY_SHADER, 80 SST_FRAGMENT_SHADER, 81 SST_COMPUTE_SHADER, 82 SST_RAY_GENERATION_SHADER, 83 SST_INTERSECTION_SHADER, 84 SST_ANY_HIT_SHADER, 85 SST_CLOSEST_HIT_SHADER, 86 SST_MISS_SHADER, 87 SST_CALLABLE_SHADER, 88}; 89 90enum ShaderTestType 91{ 92 STT_GENERATE_INTERSECTION = 0, 93 STT_SKIP_INTERSECTION = 1, 94}; 95 96enum class BottomTestType 97{ 98 TRIANGLES = 0, 99 AABBS = 1, 100}; 101 102enum class TopTestType 103{ 104 IDENTICAL_INSTANCES, 105 DIFFERENT_INSTANCES, 106 UPDATED_INSTANCES 107}; 108 109enum OperationTarget 110{ 111 OT_NONE, 112 OT_TOP_ACCELERATION, 113 OT_BOTTOM_ACCELERATION 114}; 115 116enum OperationType 117{ 118 OP_NONE, 119 OP_COPY, 120 OP_COMPACT, 121 OP_SERIALIZE, 122 OP_UPDATE, 123 OP_UPDATE_IN_PLACE 124}; 125 126enum class InstanceCullFlags 127{ 128 NONE, 129 CULL_DISABLE, 130 COUNTERCLOCKWISE, 131 ALL, 132}; 133 134enum class EmptyAccelerationStructureCase 135{ 136 NOT_EMPTY = 0, 137 INACTIVE_TRIANGLES = 1, 138 INACTIVE_INSTANCES = 2, 139 NO_GEOMETRIES_BOTTOM = 3, // geometryCount zero when building. 140 NO_PRIMITIVES_BOTTOM = 4, // primitiveCount zero when building. 141 NO_PRIMITIVES_TOP = 5, // primitiveCount zero when building. 142}; 143 144const deUint32 TEST_WIDTH = 8; 145const deUint32 TEST_HEIGHT = 8; 146 147struct TestParams; 148 149class TestConfiguration 150{ 151public: 152 virtual ~TestConfiguration (); 153 virtual void initConfiguration (Context& context, 154 TestParams& testParams) = 0; 155 virtual void fillCommandBuffer (Context& context, 156 TestParams& testParams, 157 VkCommandBuffer commandBuffer, 158 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 159 const VkDescriptorImageInfo& resultImageInfo) = 0; 160 virtual bool verifyImage (BufferWithMemory* resultBuffer, 161 Context& context, 162 TestParams& testParams) = 0; 163 virtual VkFormat getResultImageFormat () = 0; 164 virtual size_t getResultImageFormatSize () = 0; 165 virtual VkClearValue getClearValue () = 0; 166}; 167 168TestConfiguration::~TestConfiguration() 169{ 170} 171 172class SceneBuilder 173{ 174public: 175 virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (Context& context, 176 TestParams& testParams) = 0; 177 virtual de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (Context& context, 178 TestParams& testParams, 179 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) = 0; 180}; 181 182struct TestParams 183{ 184 ShaderSourceType shaderSourceType; 185 ShaderSourcePipeline shaderSourcePipeline; 186 vk::VkAccelerationStructureBuildTypeKHR buildType; // are we making AS on CPU or GPU 187 VkFormat vertexFormat; 188 bool padVertices; 189 VkIndexType indexType; 190 BottomTestType bottomTestType; // what kind of geometry is stored in bottom AS 191 InstanceCullFlags cullFlags; // Flags for instances, if needed. 192 bool bottomUsesAOP; // does bottom AS use arrays, or arrays of pointers 193 bool bottomGeneric; // Bottom created as generic AS type. 194 bool bottomUnboundedCreation; // Bottom created with unbounded buffer memory. 195 TopTestType topTestType; // If instances are identical then bottom geometries must have different vertices/aabbs 196 bool topUsesAOP; // does top AS use arrays, or arrays of pointers 197 bool topGeneric; // Top created as generic AS type. 198 bool topUnboundedCreation; // Top created with unbounded buffer memory. 199 VkBuildAccelerationStructureFlagsKHR buildFlags; 200 OperationTarget operationTarget; 201 OperationType operationType; 202 deUint32 width; 203 deUint32 height; 204 deUint32 workerThreadsCount; 205 EmptyAccelerationStructureCase emptyASCase; 206}; 207 208deUint32 getShaderGroupHandleSize (const InstanceInterface& vki, 209 const VkPhysicalDevice physicalDevice) 210{ 211 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR; 212 213 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice); 214 return rayTracingPropertiesKHR->getShaderGroupHandleSize(); 215} 216 217deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki, 218 const VkPhysicalDevice physicalDevice) 219{ 220 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR; 221 222 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice); 223 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment(); 224} 225 226VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format) 227{ 228 const VkImageCreateInfo imageCreateInfo = 229 { 230 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 231 DE_NULL, // const void* pNext; 232 (VkImageCreateFlags)0u, // VkImageCreateFlags flags; 233 VK_IMAGE_TYPE_3D, // VkImageType imageType; 234 format, // VkFormat format; 235 makeExtent3D(width, height, depth), // VkExtent3D extent; 236 1u, // deUint32 mipLevels; 237 1u, // deUint32 arrayLayers; 238 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 239 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 240 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 241 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 242 0u, // deUint32 queueFamilyIndexCount; 243 DE_NULL, // const deUint32* pQueueFamilyIndices; 244 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 245 }; 246 247 return imageCreateInfo; 248} 249 250Move<VkQueryPool> makeQueryPool(const DeviceInterface& vk, 251 const VkDevice device, 252 const VkQueryType queryType, 253 deUint32 queryCount) 254{ 255 const VkQueryPoolCreateInfo queryPoolCreateInfo = 256 { 257 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType 258 DE_NULL, // pNext 259 (VkQueryPoolCreateFlags)0, // flags 260 queryType, // queryType 261 queryCount, // queryCount 262 0u, // pipelineStatistics 263 }; 264 return createQueryPool(vk, device, &queryPoolCreateInfo); 265} 266 267 268bool registerShaderModule (const DeviceInterface& vkd, 269 const VkDevice device, 270 Context& context, 271 std::vector<de::SharedPtr<Move<VkShaderModule>>>& shaderModules, 272 std::vector<VkPipelineShaderStageCreateInfo>& shaderCreateInfos, 273 VkShaderStageFlagBits stage, 274 const std::string& externalNamePart, 275 const std::string& internalNamePart) 276{ 277 char fullShaderName[40]; 278 snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str()); 279 std::string fsn = fullShaderName; 280 if (fsn.empty()) 281 return false; 282 283 shaderModules.push_back(makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0))); 284 285 shaderCreateInfos.push_back( 286 { 287 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 288 DE_NULL, 289 (VkPipelineShaderStageCreateFlags)0, 290 stage, // stage 291 shaderModules.back()->get(), // shader 292 "main", 293 DE_NULL, // pSpecializationInfo 294 }); 295 296 return true; 297} 298 299bool registerShaderModule (const DeviceInterface& vkd, 300 const VkDevice device, 301 Context& context, 302 RayTracingPipeline& rayTracingPipeline, 303 VkShaderStageFlagBits shaderStage, 304 const std::string& externalNamePart, 305 const std::string& internalNamePart, 306 deUint32 groupIndex) 307{ 308 char fullShaderName[40]; 309 snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str()); 310 std::string fsn = fullShaderName; 311 if (fsn.empty()) 312 return false; 313 Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0); 314 if (*shaderModule == DE_NULL) 315 return false; 316 rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex); 317 return true; 318} 319 320VkGeometryInstanceFlagsKHR getCullFlags (InstanceCullFlags flags) 321{ 322 VkGeometryInstanceFlagsKHR cullFlags = 0u; 323 324 if (flags == InstanceCullFlags::CULL_DISABLE || flags == InstanceCullFlags::ALL) 325 cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; 326 327 if (flags == InstanceCullFlags::COUNTERCLOCKWISE || flags == InstanceCullFlags::ALL) 328 cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR; 329 330 return cullFlags; 331} 332 333class GraphicsConfiguration : public TestConfiguration 334{ 335public: 336 virtual ~GraphicsConfiguration (); 337 void initConfiguration (Context& context, 338 TestParams& testParams) override; 339 void fillCommandBuffer (Context& context, 340 TestParams& testParams, 341 VkCommandBuffer commandBuffer, 342 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 343 const VkDescriptorImageInfo& resultImageInfo) override; 344 bool verifyImage (BufferWithMemory* resultBuffer, 345 Context& context, 346 TestParams& testParams) override; 347 VkFormat getResultImageFormat () override; 348 size_t getResultImageFormatSize () override; 349 VkClearValue getClearValue () override; 350protected: 351 Move<VkDescriptorSetLayout> descriptorSetLayout; 352 Move<VkDescriptorPool> descriptorPool; 353 Move<VkDescriptorSet> descriptorSet; 354 Move<VkPipelineLayout> pipelineLayout; 355 Move<VkRenderPass> renderPass; 356 Move<VkFramebuffer> framebuffer; 357 std::vector<de::SharedPtr<Move<VkShaderModule> > > shaderModules; 358 Move<VkPipeline> pipeline; 359 std::vector<tcu::Vec3> vertices; 360 Move<VkBuffer> vertexBuffer; 361 de::MovePtr<Allocation> vertexAlloc; 362}; 363 364GraphicsConfiguration::~GraphicsConfiguration() 365{ 366 shaderModules.clear(); 367} 368 369void GraphicsConfiguration::initConfiguration (Context& context, 370 TestParams& testParams) 371{ 372 const DeviceInterface& vkd = context.getDeviceInterface(); 373 const VkDevice device = context.getDevice(); 374 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 375 Allocator& allocator = context.getDefaultAllocator(); 376 377 descriptorSetLayout = DescriptorSetLayoutBuilder() 378 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS) 379 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS) 380 .build(vkd, device); 381 descriptorPool = DescriptorPoolBuilder() 382 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 383 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 384 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 385 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout); 386 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); 387 388 std::vector<std::string> rayQueryTestName; 389 rayQueryTestName.push_back("as_triangle"); 390 rayQueryTestName.push_back("as_aabb"); 391 392 const std::map<ShaderSourceType,std::vector<std::string>> shaderNames = 393 { 394 //idx: 0 1 2 3 4 395 //shader: vert, tesc, tese, geom, frag, 396 { SST_VERTEX_SHADER, { "vert_%s", "", "", "", "", } }, 397 { SST_TESSELATION_CONTROL_SHADER, { "vert", "tesc_%s", "tese", "", "", } }, 398 { SST_TESSELATION_EVALUATION_SHADER, { "vert", "tesc", "tese_%s", "", "", } }, 399 { SST_GEOMETRY_SHADER, { "vert_vid", "", "", "geom_%s", "", } }, 400 { SST_FRAGMENT_SHADER, { "vert", "", "", "", "frag_%s", } }, 401 }; 402 403 auto shaderNameIt = shaderNames.find(testParams.shaderSourceType); 404 if(shaderNameIt == end(shaderNames)) 405 TCU_THROW(InternalError, "Wrong shader source type"); 406 407 std::vector<VkPipelineShaderStageCreateInfo> shaderCreateInfos; 408 bool tescX, teseX, fragX; 409 const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType); 410 registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_VERTEX_BIT, shaderNameIt->second[0], rayQueryTestName[bottomTestTypeIdx]); 411 tescX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, shaderNameIt->second[1], rayQueryTestName[bottomTestTypeIdx]); 412 teseX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, shaderNameIt->second[2], rayQueryTestName[bottomTestTypeIdx]); 413 registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_GEOMETRY_BIT, shaderNameIt->second[3], rayQueryTestName[bottomTestTypeIdx]); 414 fragX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_FRAGMENT_BIT, shaderNameIt->second[4], rayQueryTestName[bottomTestTypeIdx]); 415 416 const vk::VkSubpassDescription subpassDesc = 417 { 418 (vk::VkSubpassDescriptionFlags)0, 419 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint 420 0u, // inputCount 421 DE_NULL, // pInputAttachments 422 0u, // colorCount 423 DE_NULL, // pColorAttachments 424 DE_NULL, // pResolveAttachments 425 DE_NULL, // depthStencilAttachment 426 0u, // preserveCount 427 DE_NULL, // pPreserveAttachments 428 }; 429 const vk::VkRenderPassCreateInfo renderPassParams = 430 { 431 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType 432 DE_NULL, // pNext 433 (vk::VkRenderPassCreateFlags)0, 434 0u, // attachmentCount 435 DE_NULL, // pAttachments 436 1u, // subpassCount 437 &subpassDesc, // pSubpasses 438 0u, // dependencyCount 439 DE_NULL, // pDependencies 440 }; 441 442 renderPass = createRenderPass(vkd, device, &renderPassParams); 443 444 const vk::VkFramebufferCreateInfo framebufferParams = 445 { 446 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType 447 DE_NULL, // pNext 448 (vk::VkFramebufferCreateFlags)0, 449 *renderPass, // renderPass 450 0u, // attachmentCount 451 DE_NULL, // pAttachments 452 testParams.width, // width 453 testParams.height, // height 454 1u, // layers 455 }; 456 457 framebuffer = createFramebuffer(vkd, device, &framebufferParams); 458 459 VkPrimitiveTopology testTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 460 tcu::Vec3 v0(0.0f, 0.0f, 0.0f); 461 tcu::Vec3 v1(float(testParams.width) - 1.0f, 0.0f, 0.0f); 462 tcu::Vec3 v2(0.0f, float(testParams.height) - 1.0f, 0.0f); 463 tcu::Vec3 v3(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0f); 464 465 switch (testParams.shaderSourceType) 466 { 467 case SST_TESSELATION_CONTROL_SHADER: 468 case SST_TESSELATION_EVALUATION_SHADER: 469 testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; 470 vertices.push_back(v0); 471 vertices.push_back(v1); 472 vertices.push_back(v2); 473 vertices.push_back(v1); 474 vertices.push_back(v3); 475 vertices.push_back(v2); 476 break; 477 case SST_VERTEX_SHADER: 478 case SST_GEOMETRY_SHADER: 479 vertices.push_back(v0); 480 vertices.push_back(v1); 481 vertices.push_back(v2); 482 vertices.push_back(v3); 483 break; 484 case SST_FRAGMENT_SHADER: 485 vertices.push_back( tcu::Vec3(-1.0f, 1.0f, 0.0f) ); 486 vertices.push_back( tcu::Vec3(-1.0f, -1.0f, 0.0f) ); 487 vertices.push_back( tcu::Vec3( 1.0f, 1.0f, 0.0f) ); 488 vertices.push_back( tcu::Vec3( 1.0f, -1.0f, 0.0f) ); 489 break; 490 default: 491 TCU_THROW(InternalError, "Wrong shader source type"); 492 } 493 494 const VkVertexInputBindingDescription vertexInputBindingDescription = 495 { 496 0u, // uint32_t binding; 497 sizeof(tcu::Vec3), // uint32_t stride; 498 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 499 }; 500 501 const VkVertexInputAttributeDescription vertexInputAttributeDescription = 502 { 503 0u, // uint32_t location; 504 0u, // uint32_t binding; 505 VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format; 506 0u, // uint32_t offset; 507 }; 508 509 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = 510 { 511 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 512 DE_NULL, // const void* pNext; 513 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 514 1u, // deUint32 vertexBindingDescriptionCount; 515 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 516 1u, // deUint32 vertexAttributeDescriptionCount; 517 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 518 }; 519 520 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = 521 { 522 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 523 DE_NULL, // const void* pNext; 524 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 525 testTopology, // VkPrimitiveTopology topology; 526 VK_FALSE // VkBool32 primitiveRestartEnable; 527 }; 528 529 const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo = 530 { 531 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 532 DE_NULL, // const void* pNext; 533 VkPipelineTessellationStateCreateFlags(0u), // VkPipelineTessellationStateCreateFlags flags; 534 3u // deUint32 patchControlPoints; 535 }; 536 537 VkViewport viewport = makeViewport(testParams.width, testParams.height); 538 VkRect2D scissor = makeRect2D(testParams.width, testParams.height); 539 540 const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = 541 { 542 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType 543 DE_NULL, // const void* pNext 544 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags 545 1u, // deUint32 viewportCount 546 &viewport, // const VkViewport* pViewports 547 1u, // deUint32 scissorCount 548 &scissor // const VkRect2D* pScissors 549 }; 550 551 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = 552 { 553 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 554 DE_NULL, // const void* pNext; 555 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 556 VK_FALSE, // VkBool32 depthClampEnable; 557 fragX ? VK_FALSE : VK_TRUE, // VkBool32 rasterizerDiscardEnable; 558 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 559 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 560 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace; 561 VK_FALSE, // VkBool32 depthBiasEnable; 562 0.0f, // float depthBiasConstantFactor; 563 0.0f, // float depthBiasClamp; 564 0.0f, // float depthBiasSlopeFactor; 565 1.0f // float lineWidth; 566 }; 567 568 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = 569 { 570 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 571 DE_NULL, // const void* pNext; 572 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 573 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 574 VK_FALSE, // VkBool32 sampleShadingEnable; 575 0.0f, // float minSampleShading; 576 DE_NULL, // const VkSampleMask* pSampleMask; 577 VK_FALSE, // VkBool32 alphaToCoverageEnable; 578 VK_FALSE // VkBool32 alphaToOneEnable; 579 }; 580 581 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = 582 { 583 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 584 DE_NULL, // const void* pNext; 585 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 586 DE_FALSE, // VkBool32 logicOpEnable; 587 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 588 0, // deUint32 attachmentCount; 589 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments; 590 { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4]; 591 }; 592 593 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = 594 { 595 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 596 DE_NULL, // const void* pNext; 597 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 598 static_cast<deUint32>(shaderCreateInfos.size()), // deUint32 stageCount; 599 shaderCreateInfos.data(), // const VkPipelineShaderStageCreateInfo* pStages; 600 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 601 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 602 (tescX||teseX) ? &tessellationStateCreateInfo : DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 603 fragX ? &viewportStateCreateInfo : DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState; 604 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 605 fragX ? &multisampleStateCreateInfo : DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 606 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 607 fragX ? &colorBlendStateCreateInfo : DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 608 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 609 pipelineLayout.get(), // VkPipelineLayout layout; 610 renderPass.get(), // VkRenderPass renderPass; 611 0u, // deUint32 subpass; 612 DE_NULL, // VkPipeline basePipelineHandle; 613 0 // int basePipelineIndex; 614 }; 615 616 pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo); 617 618 const VkBufferCreateInfo vertexBufferParams = 619 { 620 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 621 DE_NULL, // const void* pNext; 622 0u, // VkBufferCreateFlags flags; 623 VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()), // VkDeviceSize size; 624 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | 625 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 626 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 627 1u, // deUint32 queueFamilyIndexCount; 628 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 629 }; 630 631 vertexBuffer = createBuffer(vkd, device, &vertexBufferParams); 632 vertexAlloc = allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible); 633 VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset())); 634 635 // Upload vertex data 636 deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3)); 637 flushAlloc(vkd, device, *vertexAlloc); 638} 639 640void GraphicsConfiguration::fillCommandBuffer (Context& context, 641 TestParams& testParams, 642 VkCommandBuffer commandBuffer, 643 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 644 const VkDescriptorImageInfo& resultImageInfo) 645{ 646 const DeviceInterface& vkd = context.getDeviceInterface(); 647 const VkDevice device = context.getDevice(); 648 649 DescriptorSetUpdateBuilder() 650 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo) 651 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet) 652 .update(vkd, device); 653 654 const VkRenderPassBeginInfo renderPassBeginInfo = 655 { 656 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 657 DE_NULL, // const void* pNext; 658 *renderPass, // VkRenderPass renderPass; 659 *framebuffer, // VkFramebuffer framebuffer; 660 makeRect2D(testParams.width, testParams.height), // VkRect2D renderArea; 661 0u, // uint32_t clearValueCount; 662 DE_NULL // const VkClearValue* pClearValues; 663 }; 664 VkDeviceSize vertexBufferOffset = 0u; 665 666 vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 667 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 668 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 669 vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); 670 vkd.cmdDraw(commandBuffer, deUint32(vertices.size()), 1, 0, 0); 671 vkd.cmdEndRenderPass(commandBuffer); 672} 673 674bool GraphicsConfiguration::verifyImage (BufferWithMemory* resultBuffer, 675 Context& context, 676 TestParams& testParams) 677{ 678 // create result image 679 const bool allMiss = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY); 680 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat()); 681 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr()); 682 683 // create reference image 684 std::vector<deUint32> reference(testParams.width * testParams.height * 2); 685 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data()); 686 687 std::vector<std::vector<deUint32>> primitives = 688 { 689 {0, 1, 2}, 690 {1, 3, 2} 691 }; 692 693 tcu::UVec4 hitValue0 = tcu::UVec4(1, 0, 0, 0); 694 tcu::UVec4 hitValue1 = tcu::UVec4(1, 0, 0, 0); 695 tcu::UVec4 missValue = tcu::UVec4(0, 0, 0, 0); 696 tcu::UVec4 clearValue = tcu::UVec4(0xFF, 0, 0, 0); 697 698 switch (testParams.shaderSourceType) 699 { 700 case SST_VERTEX_SHADER: 701 tcu::clear(referenceAccess, clearValue); 702 for (deUint32 vertexNdx = 0; vertexNdx < 4; ++vertexNdx) 703 { 704 if (!allMiss && (vertexNdx == 1 || vertexNdx == 2)) 705 { 706 referenceAccess.setPixel(hitValue0, vertexNdx, 0, 0); 707 referenceAccess.setPixel(hitValue1, vertexNdx, 0, 1); 708 } 709 else 710 { 711 referenceAccess.setPixel(missValue, vertexNdx, 0, 0); 712 referenceAccess.setPixel(missValue, vertexNdx, 0, 1); 713 } 714 } 715 break; 716 case SST_TESSELATION_EVALUATION_SHADER: 717 case SST_TESSELATION_CONTROL_SHADER: 718 case SST_GEOMETRY_SHADER: 719 tcu::clear(referenceAccess, clearValue); 720 for (deUint32 primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx) 721 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx) 722 { 723 deUint32 vNdx = primitives[primitiveNdx][vertexNdx]; 724 if (!allMiss && (vNdx==1 || vNdx==2)) 725 { 726 referenceAccess.setPixel(hitValue0, primitiveNdx, vertexNdx, 0); 727 referenceAccess.setPixel(hitValue1, primitiveNdx, vertexNdx, 1); 728 } 729 else 730 { 731 referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 0); 732 referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 1); 733 } 734 } 735 break; 736 case SST_FRAGMENT_SHADER: 737 tcu::clear(referenceAccess, missValue); 738 for (deUint32 y = 0; y < testParams.height; ++y) 739 for (deUint32 x = 0; x < testParams.width; ++x) 740 { 741 if (allMiss || ((x + y) % 2) == 0) 742 continue; 743 744 referenceAccess.setPixel(hitValue0, x, y, 0); 745 referenceAccess.setPixel(hitValue1, x, y, 1); 746 } 747 break; 748 default: 749 TCU_THROW(InternalError, "Wrong shader source type"); 750 } 751 752 // compare result and reference 753 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT); 754} 755 756VkFormat GraphicsConfiguration::getResultImageFormat () 757{ 758 return VK_FORMAT_R32_UINT; 759} 760 761size_t GraphicsConfiguration::getResultImageFormatSize () 762{ 763 return sizeof(deUint32); 764} 765 766VkClearValue GraphicsConfiguration::getClearValue () 767{ 768 return makeClearValueColorU32(0xFF, 0u, 0u, 0u); 769} 770 771class ComputeConfiguration : public TestConfiguration 772{ 773public: 774 virtual ~ComputeConfiguration (); 775 void initConfiguration (Context& context, 776 TestParams& testParams) override; 777 void fillCommandBuffer (Context& context, 778 TestParams& testParams, 779 VkCommandBuffer commandBuffer, 780 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 781 const VkDescriptorImageInfo& resultImageInfo) override; 782 bool verifyImage (BufferWithMemory* resultBuffer, 783 Context& context, 784 TestParams& testParams) override; 785 VkFormat getResultImageFormat () override; 786 size_t getResultImageFormatSize () override; 787 VkClearValue getClearValue () override; 788protected: 789 Move<VkDescriptorSetLayout> descriptorSetLayout; 790 Move<VkDescriptorPool> descriptorPool; 791 Move<VkDescriptorSet> descriptorSet; 792 Move<VkPipelineLayout> pipelineLayout; 793 Move<VkShaderModule> shaderModule; 794 Move<VkPipeline> pipeline; 795}; 796 797ComputeConfiguration::~ComputeConfiguration() 798{ 799} 800 801void ComputeConfiguration::initConfiguration (Context& context, 802 TestParams& testParams) 803{ 804 const DeviceInterface& vkd = context.getDeviceInterface(); 805 const VkDevice device = context.getDevice(); 806 807 descriptorSetLayout = DescriptorSetLayoutBuilder() 808 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 809 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT) 810 .build(vkd, device); 811 descriptorPool = DescriptorPoolBuilder() 812 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 813 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 814 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 815 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout); 816 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); 817 818 std::vector<std::string> rayQueryTestName; 819 rayQueryTestName.push_back("comp_as_triangle"); 820 rayQueryTestName.push_back("comp_as_aabb"); 821 822 const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType); 823 shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[bottomTestTypeIdx]), 0u); 824 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = 825 { 826 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 827 DE_NULL, // const void* pNext; 828 0u, // VkPipelineShaderStageCreateFlags flags; 829 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 830 *shaderModule, // VkShaderModule module; 831 "main", // const char* pName; 832 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 833 }; 834 const VkComputePipelineCreateInfo pipelineCreateInfo = 835 { 836 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 837 DE_NULL, // const void* pNext; 838 0u, // VkPipelineCreateFlags flags; 839 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage; 840 *pipelineLayout, // VkPipelineLayout layout; 841 DE_NULL, // VkPipeline basePipelineHandle; 842 0, // deInt32 basePipelineIndex; 843 }; 844 845 pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo); 846} 847 848void ComputeConfiguration::fillCommandBuffer (Context& context, 849 TestParams& testParams, 850 VkCommandBuffer commandBuffer, 851 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 852 const VkDescriptorImageInfo& resultImageInfo) 853{ 854 const DeviceInterface& vkd = context.getDeviceInterface(); 855 const VkDevice device = context.getDevice(); 856 857 DescriptorSetUpdateBuilder() 858 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo) 859 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet) 860 .update(vkd, device); 861 862 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); 863 864 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 865 866 vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1); 867} 868 869bool ComputeConfiguration::verifyImage (BufferWithMemory* resultBuffer, 870 Context& context, 871 TestParams& testParams) 872{ 873 // create result image 874 const bool allMiss = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY); 875 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat()); 876 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr()); 877 878 // create reference image 879 std::vector<deUint32> reference(testParams.width * testParams.height * 2); 880 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data()); 881 882 tcu::UVec4 hitValue0 = tcu::UVec4(1, 0, 0, 0); 883 tcu::UVec4 hitValue1 = tcu::UVec4(1, 0, 0, 0); 884 tcu::UVec4 missValue = tcu::UVec4(0, 0, 0, 0); 885 886 tcu::clear(referenceAccess, missValue); 887 888 for (deUint32 y = 0; y < testParams.height; ++y) 889 for (deUint32 x = 0; x < testParams.width; ++x) 890 { 891 if (allMiss || ((x + y) % 2) == 0) 892 continue; 893 894 referenceAccess.setPixel(hitValue0, x, y, 0); 895 referenceAccess.setPixel(hitValue1, x, y, 1); 896 } 897 898 // compare result and reference 899 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT); 900} 901 902VkFormat ComputeConfiguration::getResultImageFormat () 903{ 904 return VK_FORMAT_R32_UINT; 905} 906 907size_t ComputeConfiguration::getResultImageFormatSize () 908{ 909 return sizeof(deUint32); 910} 911 912VkClearValue ComputeConfiguration::getClearValue () 913{ 914 return makeClearValueColorU32(0xFF, 0u, 0u, 0u); 915} 916 917class RayTracingConfiguration : public TestConfiguration 918{ 919public: 920 virtual ~RayTracingConfiguration (); 921 void initConfiguration (Context& context, 922 TestParams& testParams) override; 923 void fillCommandBuffer (Context& context, 924 TestParams& testParams, 925 VkCommandBuffer commandBuffer, 926 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 927 const VkDescriptorImageInfo& resultImageInfo) override; 928 bool verifyImage (BufferWithMemory* resultBuffer, 929 Context& context, 930 TestParams& testParams) override; 931 VkFormat getResultImageFormat () override; 932 size_t getResultImageFormatSize () override; 933 VkClearValue getClearValue () override; 934protected: 935 Move<VkDescriptorSetLayout> descriptorSetLayout; 936 Move<VkDescriptorPool> descriptorPool; 937 Move<VkDescriptorSet> descriptorSet; 938 Move<VkPipelineLayout> pipelineLayout; 939 940 de::MovePtr<RayTracingPipeline> rayTracingPipeline; 941 Move<VkPipeline> rtPipeline; 942 943 de::MovePtr<BufferWithMemory> raygenShaderBindingTable; 944 de::MovePtr<BufferWithMemory> hitShaderBindingTable; 945 de::MovePtr<BufferWithMemory> missShaderBindingTable; 946 de::MovePtr<BufferWithMemory> callableShaderBindingTable; 947 948 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelAccelerationStructures; 949 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure; 950}; 951 952RayTracingConfiguration::~RayTracingConfiguration() 953{ 954} 955 956void RayTracingConfiguration::initConfiguration (Context& context, 957 TestParams& testParams) 958{ 959 const InstanceInterface& vki = context.getInstanceInterface(); 960 const DeviceInterface& vkd = context.getDeviceInterface(); 961 const VkDevice device = context.getDevice(); 962 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 963 Allocator& allocator = context.getDefaultAllocator(); 964 965 descriptorSetLayout = DescriptorSetLayoutBuilder() 966 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES) 967 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES) 968 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES) 969 .build(vkd, device); 970 descriptorPool = DescriptorPoolBuilder() 971 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 972 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 973 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) 974 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 975 descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout); 976 pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); 977 978 rayTracingPipeline = de::newMovePtr<RayTracingPipeline>(); 979 980 const std::map<ShaderSourceType,std::vector<std::string>> shaderNames = 981 { 982 //idx: 0 1 2 3 4 5 983 //shader: rgen, isect, ahit, chit, miss, call 984 //group: 0 1 1 1 2 3 985 { SST_RAY_GENERATION_SHADER, { "rgen_%s", "", "", "", "", "" } }, 986 { SST_INTERSECTION_SHADER, { "rgen", "isect_%s", "", "chit_isect", "miss", "" } }, 987 { SST_ANY_HIT_SHADER, { "rgen", "isect", "ahit_%s", "", "miss", "" } }, 988 { SST_CLOSEST_HIT_SHADER, { "rgen", "isect", "", "chit_%s", "miss", "" } }, 989 { SST_MISS_SHADER, { "rgen", "isect", "", "chit", "miss_%s", "" } }, 990 { SST_CALLABLE_SHADER, { "rgen_call", "", "", "chit", "miss", "call_%s" } }, 991 }; 992 993 std::vector<std::string> rayQueryTestName; 994 rayQueryTestName.push_back("as_triangle"); 995 rayQueryTestName.push_back("as_aabb"); 996 997 auto shaderNameIt = shaderNames.find(testParams.shaderSourceType); 998 if(shaderNameIt == end(shaderNames)) 999 TCU_THROW(InternalError, "Wrong shader source type"); 1000 1001 bool rgenX, isectX, ahitX, chitX, missX, callX; 1002 const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType); 1003 rgenX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_RAYGEN_BIT_KHR, shaderNameIt->second[0], rayQueryTestName[bottomTestTypeIdx], 0); 1004 if (testParams.shaderSourceType == SST_INTERSECTION_SHADER) 1005 isectX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_INTERSECTION_BIT_KHR, shaderNameIt->second[1], rayQueryTestName[bottomTestTypeIdx], 1); 1006 else 1007 isectX = false; 1008 ahitX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_ANY_HIT_BIT_KHR, shaderNameIt->second[2], rayQueryTestName[bottomTestTypeIdx], 1); 1009 chitX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, shaderNameIt->second[3], rayQueryTestName[bottomTestTypeIdx], 1); 1010 missX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_MISS_BIT_KHR, shaderNameIt->second[4], rayQueryTestName[bottomTestTypeIdx], 2); 1011 callX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CALLABLE_BIT_KHR, shaderNameIt->second[5], rayQueryTestName[bottomTestTypeIdx], 3); 1012 bool hitX = isectX || ahitX || chitX; 1013 1014 rtPipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout); 1015 1016 deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice); 1017 deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice); 1018 1019 if (rgenX) raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1); 1020 if (hitX) hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1); 1021 if (missX) missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1); 1022 if (callX) callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1); 1023} 1024 1025void RayTracingConfiguration::fillCommandBuffer (Context& context, 1026 TestParams& testParams, 1027 VkCommandBuffer commandBuffer, 1028 const VkWriteDescriptorSetAccelerationStructureKHR& rayQueryAccelerationStructureWriteDescriptorSet, 1029 const VkDescriptorImageInfo& resultImageInfo) 1030{ 1031 const InstanceInterface& vki = context.getInstanceInterface(); 1032 const DeviceInterface& vkd = context.getDeviceInterface(); 1033 const VkDevice device = context.getDevice(); 1034 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1035 Allocator& allocator = context.getDefaultAllocator(); 1036 1037 { 1038 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 1039 bottomLevelAccelerationStructure->setGeometryCount(1); 1040 1041 de::SharedPtr<RaytracedGeometryBase> geometry; 1042 if (testParams.shaderSourceType != SST_INTERSECTION_SHADER) 1043 { 1044 tcu::Vec3 v0(0.0f, float(testParams.height), 0.0f); 1045 tcu::Vec3 v1(0.0f, 0.0f, 0.0f); 1046 tcu::Vec3 v2(float(testParams.width), float(testParams.height), 0.0f); 1047 tcu::Vec3 v3(float(testParams.width), 0.0f, 0.0f); 1048 tcu::Vec3 missOffset(0.0f, 0.0f, 0.0f); 1049 if (testParams.shaderSourceType == SST_MISS_SHADER) 1050 missOffset = tcu::Vec3(1.0f + float(testParams.width), 0.0f, 0.0f); 1051 1052 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR); 1053 geometry->addVertex(v0 + missOffset); 1054 geometry->addVertex(v1 + missOffset); 1055 geometry->addVertex(v2 + missOffset); 1056 geometry->addVertex(v2 + missOffset); 1057 geometry->addVertex(v1 + missOffset); 1058 geometry->addVertex(v3 + missOffset); 1059 } 1060 else // testParams.shaderSourceType == SST_INTERSECTION_SHADER 1061 { 1062 tcu::Vec3 v0(0.0f, 0.0f, -0.1f); 1063 tcu::Vec3 v1(float(testParams.width), float(testParams.height), 0.1f); 1064 1065 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR); 1066 geometry->addVertex(v0); 1067 geometry->addVertex(v1); 1068 } 1069 bottomLevelAccelerationStructure->addGeometry(geometry); 1070 bottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release())); 1071 1072 for (auto& blas : bottomLevelAccelerationStructures) 1073 blas->createAndBuild(vkd, device, commandBuffer, allocator); 1074 } 1075 1076 topLevelAccelerationStructure = makeTopLevelAccelerationStructure(); 1077 topLevelAccelerationStructure->setInstanceCount(1); 1078 topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]); 1079 topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator); 1080 1081 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get(); 1082 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = 1083 { 1084 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 1085 DE_NULL, // const void* pNext; 1086 1u, // deUint32 accelerationStructureCount; 1087 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures; 1088 }; 1089 1090 DescriptorSetUpdateBuilder() 1091 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo) 1092 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet) 1093 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet) 1094 .update(vkd, device); 1095 1096 vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL); 1097 1098 vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline); 1099 1100 deUint32 shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice); 1101 VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = raygenShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1102 VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = hitShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1103 VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = missShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1104 VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = callableShaderBindingTable.get() != DE_NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1105 1106 cmdTraceRays(vkd, 1107 commandBuffer, 1108 &raygenShaderBindingTableRegion, 1109 &missShaderBindingTableRegion, 1110 &hitShaderBindingTableRegion, 1111 &callableShaderBindingTableRegion, 1112 testParams.width, testParams.height, 1); 1113} 1114 1115bool RayTracingConfiguration::verifyImage (BufferWithMemory* resultBuffer, 1116 Context& context, 1117 TestParams& testParams) 1118{ 1119 // create result image 1120 const bool allMiss = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY); 1121 tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat()); 1122 tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr()); 1123 1124 // create reference image 1125 std::vector<deUint32> reference(testParams.width * testParams.height * 2); 1126 tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data()); 1127 1128 tcu::UVec4 missValue (0, 0, 0, 0); 1129 tcu::UVec4 hitValue (1, 0, 0, 0); 1130 1131 for (deUint32 y = 0; y < testParams.height; ++y) 1132 for (deUint32 x = 0; x < testParams.width; ++x) 1133 { 1134 if (allMiss || ((x + y) % 2) == 0) 1135 { 1136 referenceAccess.setPixel(missValue, x, y, 0); 1137 referenceAccess.setPixel(missValue, x, y, 1); 1138 } 1139 else 1140 { 1141 referenceAccess.setPixel(hitValue, x, y, 0); 1142 referenceAccess.setPixel(hitValue, x, y, 1); 1143 } 1144 } 1145 1146 // compare result and reference 1147 return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT); 1148} 1149 1150VkFormat RayTracingConfiguration::getResultImageFormat () 1151{ 1152 return VK_FORMAT_R32_UINT; 1153} 1154 1155size_t RayTracingConfiguration::getResultImageFormatSize () 1156{ 1157 return sizeof(deUint32); 1158} 1159 1160VkClearValue RayTracingConfiguration::getClearValue () 1161{ 1162 return makeClearValueColorU32(0xFF, 0u, 0u, 0u); 1163} 1164 1165de::SharedPtr<TestConfiguration> createTestConfiguration(const ShaderSourcePipeline& shaderSourcePipeline) 1166{ 1167 switch (shaderSourcePipeline) 1168 { 1169 case SSP_GRAPHICS_PIPELINE: 1170 return de::SharedPtr<TestConfiguration>(new GraphicsConfiguration()); 1171 case SSP_COMPUTE_PIPELINE: 1172 return de::SharedPtr<TestConfiguration>(new ComputeConfiguration()); 1173 case SSP_RAY_TRACING_PIPELINE: 1174 return de::SharedPtr<TestConfiguration>(new RayTracingConfiguration()); 1175 default: 1176 TCU_THROW(InternalError, "Wrong shader source pipeline"); 1177 } 1178 return de::SharedPtr<TestConfiguration>(); 1179} 1180 1181class CheckerboardSceneBuilder : public SceneBuilder 1182{ 1183public: 1184 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (Context& context, 1185 TestParams& testParams) override; 1186 de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (Context& context, 1187 TestParams& testParams, 1188 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) override; 1189}; 1190 1191std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> CheckerboardSceneBuilder::initBottomAccelerationStructures (Context& context, 1192 TestParams& testParams) 1193{ 1194 DE_UNREF(context); 1195 1196 // Cull flags can only be used with triangles. 1197 DE_ASSERT(testParams.cullFlags == InstanceCullFlags::NONE || testParams.bottomTestType == BottomTestType::TRIANGLES); 1198 1199 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> > result; 1200 1201 const auto instanceFlags = getCullFlags(testParams.cullFlags); 1202 1203 tcu::Vec3 v0(0.0, 1.0, 0.0); 1204 tcu::Vec3 v1(0.0, 0.0, 0.0); 1205 tcu::Vec3 v2(1.0, 1.0, 0.0); 1206 tcu::Vec3 v3(1.0, 0.0, 0.0); 1207 1208 // Different vertex configurations of a triangle whose parameter x is set to NaN during inactive_triangles tests 1209 const bool nanConfig[4][4] = 1210 { 1211 { true, true, true, true }, 1212 { false, true, true, false }, 1213 { false, false, true, false }, 1214 { false, true, false, false }, 1215 }; 1216 1217 unsigned int geometryCount = testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES ? 4U : 1U; 1218 1219 if (testParams.topTestType == TopTestType::DIFFERENT_INSTANCES) 1220 { 1221 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 1222 bottomLevelAccelerationStructure->setGeometryCount(1u); 1223 de::SharedPtr<RaytracedGeometryBase> geometry; 1224 if (testParams.bottomTestType == BottomTestType::TRIANGLES) 1225 { 1226 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices); 1227 if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR) 1228 { 1229 if (instanceFlags == 0u) 1230 { 1231 geometry->addVertex(v0); 1232 geometry->addVertex(v1); 1233 geometry->addVertex(v2); 1234 geometry->addVertex(v2); 1235 geometry->addVertex(v1); 1236 geometry->addVertex(v3); 1237 } 1238 else // Counterclockwise so the flags will be needed for the geometry to be visible. 1239 { 1240 geometry->addVertex(v2); 1241 geometry->addVertex(v1); 1242 geometry->addVertex(v0); 1243 geometry->addVertex(v3); 1244 geometry->addVertex(v1); 1245 geometry->addVertex(v2); 1246 } 1247 } 1248 else // m_data.indexType != VK_INDEX_TYPE_NONE_KHR 1249 { 1250 geometry->addVertex(v0); 1251 geometry->addVertex(v1); 1252 geometry->addVertex(v2); 1253 geometry->addVertex(v3); 1254 1255 if (instanceFlags == 0u) 1256 { 1257 geometry->addIndex(0); 1258 geometry->addIndex(1); 1259 geometry->addIndex(2); 1260 geometry->addIndex(2); 1261 geometry->addIndex(1); 1262 geometry->addIndex(3); 1263 } 1264 else // Counterclockwise so the flags will be needed for the geometry to be visible. 1265 { 1266 geometry->addIndex(2); 1267 geometry->addIndex(1); 1268 geometry->addIndex(0); 1269 geometry->addIndex(3); 1270 geometry->addIndex(1); 1271 geometry->addIndex(2); 1272 } 1273 1274 } 1275 } 1276 else // m_data.bottomTestType == BTT_AABBS 1277 { 1278 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices); 1279 1280 if (!testParams.padVertices) 1281 { 1282 // Single AABB. 1283 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f)); 1284 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f)); 1285 } 1286 else 1287 { 1288 // Multiple AABBs covering the same space. 1289 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f)); 1290 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, 0.1f)); 1291 1292 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, -0.1f)); 1293 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f)); 1294 1295 geometry->addVertex(tcu::Vec3(0.0f, 0.5f, -0.1f)); 1296 geometry->addVertex(tcu::Vec3(0.5f, 1.0f, 0.1f)); 1297 1298 geometry->addVertex(tcu::Vec3(0.5f, 0.0f, -0.1f)); 1299 geometry->addVertex(tcu::Vec3(1.0f, 0.5f, 0.1f)); 1300 } 1301 } 1302 1303 bottomLevelAccelerationStructure->addGeometry(geometry); 1304 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release())); 1305 } 1306 else // m_data.topTestType == TTT_IDENTICAL_INSTANCES 1307 { 1308 tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat); 1309 tcu::Vec3 scale ( 1.0f, 1.0f, 1.0f ); 1310 if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) 1311 scale = tcu::Vec3(1.0f / float(testParams.width), 1.0f / float(testParams.height), 1.0f); 1312 1313 // triangle and aabb tests use geometries/aabbs with different vertex positions and the same identity matrix in each instance data 1314 for (deUint32 y = 0; y < testParams.height; ++y) 1315 for (deUint32 x = 0; x < testParams.width; ++x) 1316 { 1317 // let's build a chessboard of geometries 1318 if (((x + y) % 2) == 0) 1319 continue; 1320 tcu::Vec3 xyz((float)x, (float)y, 0.0f); 1321 1322 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 1323 bottomLevelAccelerationStructure->setGeometryCount(geometryCount); 1324 1325 if (testParams.bottomTestType == BottomTestType::TRIANGLES) 1326 { 1327 for (unsigned int i = 0; i < geometryCount; i++) 1328 { 1329 de::SharedPtr<RaytracedGeometryBase> geometry; 1330 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices); 1331 1332 if (testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES) 1333 { 1334 const auto nanValue = tcu::Float32::nan().asFloat(); 1335 1336 if (nanConfig[i][0]) 1337 v0.x() = nanValue; 1338 if (nanConfig[i][1]) 1339 v1.x() = nanValue; 1340 if (nanConfig[i][2]) 1341 v2.x() = nanValue; 1342 if (nanConfig[i][3]) 1343 v3.x() = nanValue; 1344 } 1345 1346 if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR) 1347 { 1348 if (instanceFlags == 0u) 1349 { 1350 geometry->addVertex(scale * (xyz + v0)); 1351 geometry->addVertex(scale * (xyz + v1)); 1352 geometry->addVertex(scale * (xyz + v2)); 1353 geometry->addVertex(scale * (xyz + v2)); 1354 geometry->addVertex(scale * (xyz + v1)); 1355 geometry->addVertex(scale * (xyz + v3)); 1356 } 1357 else // Counterclockwise so the flags will be needed for the geometry to be visible. 1358 { 1359 geometry->addVertex(scale * (xyz + v2)); 1360 geometry->addVertex(scale * (xyz + v1)); 1361 geometry->addVertex(scale * (xyz + v0)); 1362 geometry->addVertex(scale * (xyz + v3)); 1363 geometry->addVertex(scale * (xyz + v1)); 1364 geometry->addVertex(scale * (xyz + v2)); 1365 } 1366 } 1367 1368 else 1369 { 1370 geometry->addVertex(scale * (xyz + v0)); 1371 geometry->addVertex(scale * (xyz + v1)); 1372 geometry->addVertex(scale * (xyz + v2)); 1373 geometry->addVertex(scale * (xyz + v3)); 1374 1375 if (instanceFlags == 0u) 1376 { 1377 geometry->addIndex(0); 1378 geometry->addIndex(1); 1379 geometry->addIndex(2); 1380 geometry->addIndex(2); 1381 geometry->addIndex(1); 1382 geometry->addIndex(3); 1383 } 1384 else // Counterclockwise so the flags will be needed for the geometry to be visible. 1385 { 1386 geometry->addIndex(2); 1387 geometry->addIndex(1); 1388 geometry->addIndex(0); 1389 geometry->addIndex(3); 1390 geometry->addIndex(1); 1391 geometry->addIndex(2); 1392 } 1393 } 1394 1395 bottomLevelAccelerationStructure->addGeometry(geometry); 1396 } 1397 } 1398 else // testParams.bottomTestType == BTT_AABBS 1399 { 1400 de::SharedPtr<RaytracedGeometryBase> geometry; 1401 geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices); 1402 1403 if (!testParams.padVertices) 1404 { 1405 // Single AABB. 1406 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f))); 1407 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f))); 1408 } 1409 else 1410 { 1411 // Multiple AABBs covering the same space. 1412 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f))); 1413 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, 0.1f))); 1414 1415 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, -0.1f))); 1416 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f))); 1417 1418 geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.5f, -0.1f))); 1419 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 1.0f, 0.1f))); 1420 1421 geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.0f, -0.1f))); 1422 geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 0.5f, 0.1f))); 1423 } 1424 1425 bottomLevelAccelerationStructure->addGeometry(geometry); 1426 } 1427 1428 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release())); 1429 } 1430 } 1431 1432 return result; 1433} 1434 1435de::MovePtr<TopLevelAccelerationStructure> CheckerboardSceneBuilder::initTopAccelerationStructure (Context& context, 1436 TestParams& testParams, 1437 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures) 1438{ 1439 DE_UNREF(context); 1440 1441 const auto instanceCount = testParams.width * testParams.height / 2u; 1442 const auto instanceFlags = getCullFlags(testParams.cullFlags); 1443 1444 de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure(); 1445 result->setInstanceCount(instanceCount); 1446 1447 if (testParams.topTestType == TopTestType::DIFFERENT_INSTANCES) 1448 { 1449 1450 for (deUint32 y = 0; y < testParams.height; ++y) 1451 for (deUint32 x = 0; x < testParams.width; ++x) 1452 { 1453 if (((x + y) % 2) == 0) 1454 continue; 1455 const VkTransformMatrixKHR transformMatrixKHR = 1456 { 1457 { // float matrix[3][4]; 1458 { 1.0f, 0.0f, 0.0f, (float)x }, 1459 { 0.0f, 1.0f, 0.0f, (float)y }, 1460 { 0.0f, 0.0f, 1.0f, 0.0f }, 1461 } 1462 }; 1463 result->addInstance(bottomLevelAccelerationStructures[0], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags); 1464 } 1465 } 1466 else // testParams.topTestType == TTT_IDENTICAL_INSTANCES 1467 { 1468 tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat); 1469 tcu::Vec3 scale ( 1.0f, 1.0f, 1.0f ); 1470 if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) 1471 scale = tcu::Vec3(float(testParams.width), float(testParams.height), 1.0f); 1472 1473 const VkTransformMatrixKHR transformMatrixKHR = 1474 { 1475 { // float matrix[3][4]; 1476 { scale.x(), 0.0f, 0.0f, 0.0f }, 1477 { 0.0f, scale.y(), 0.0f, 0.0f }, 1478 { 0.0f, 0.0f, scale.z(), 0.0f }, 1479 } 1480 }; 1481 1482 deUint32 currentInstanceIndex = 0; 1483 1484 for (deUint32 y = 0; y < testParams.height; ++y) 1485 for (deUint32 x = 0; x < testParams.width; ++x) 1486 { 1487 if (((x + y) % 2) == 0) 1488 continue; 1489 result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags); 1490 } 1491 } 1492 1493 return result; 1494} 1495 1496void commonASTestsCheckSupport(Context& context) 1497{ 1498 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2"); 1499 context.requireDeviceFunctionality("VK_KHR_acceleration_structure"); 1500 context.requireDeviceFunctionality("VK_KHR_ray_query"); 1501 1502 const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures(); 1503 if (rayQueryFeaturesKHR.rayQuery == DE_FALSE) 1504 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery"); 1505 1506 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures(); 1507 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE) 1508 TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure"); 1509} 1510 1511class RayQueryASBasicTestCase : public TestCase 1512{ 1513public: 1514 RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const TestParams& data); 1515 ~RayQueryASBasicTestCase (void); 1516 1517 virtual void checkSupport (Context& context) const; 1518 virtual void initPrograms (SourceCollections& programCollection) const; 1519 virtual TestInstance* createInstance (Context& context) const; 1520protected: 1521 TestParams m_data; 1522}; 1523 1524class RayQueryASFuncArgTestCase : public RayQueryASBasicTestCase 1525{ 1526public: 1527 RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const TestParams& data); 1528 ~RayQueryASFuncArgTestCase (void) {} 1529 1530 virtual void initPrograms (SourceCollections& programCollection) const; 1531}; 1532 1533class RayQueryASBasicTestInstance : public TestInstance 1534{ 1535public: 1536 RayQueryASBasicTestInstance (Context& context, 1537 const TestParams& data); 1538 ~RayQueryASBasicTestInstance (void); 1539 tcu::TestStatus iterate (void); 1540protected: 1541 bool iterateNoWorkers (void); 1542 bool iterateWithWorkers (void); 1543 de::MovePtr<BufferWithMemory> runTest (TestConfiguration* testConfiguration, 1544 SceneBuilder* sceneBuilder, 1545 const deUint32 workerThreadsCount); 1546 1547 1548private: 1549 TestParams m_data; 1550}; 1551 1552RayQueryASBasicTestCase::RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const TestParams& data) 1553 : vkt::TestCase (context, name) 1554 , m_data (data) 1555{ 1556} 1557 1558RayQueryASBasicTestCase::~RayQueryASBasicTestCase (void) 1559{ 1560} 1561 1562void RayQueryASBasicTestCase::checkSupport (Context& context) const 1563{ 1564 commonASTestsCheckSupport(context); 1565 1566 const VkPhysicalDeviceFeatures2& features2 = context.getDeviceFeatures2(); 1567 1568 if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER || 1569 m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) && 1570 features2.features.tessellationShader == DE_FALSE ) 1571 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader"); 1572 1573 if (m_data.shaderSourceType == SST_GEOMETRY_SHADER && 1574 features2.features.geometryShader == DE_FALSE ) 1575 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader"); 1576 1577 if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER || 1578 m_data.shaderSourceType == SST_INTERSECTION_SHADER || 1579 m_data.shaderSourceType == SST_ANY_HIT_SHADER || 1580 m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER || 1581 m_data.shaderSourceType == SST_MISS_SHADER || 1582 m_data.shaderSourceType == SST_CALLABLE_SHADER) 1583 { 1584 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 1585 1586 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures(); 1587 1588 if(rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE ) 1589 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline"); 1590 } 1591 1592 switch (m_data.shaderSourceType) 1593 { 1594 case SST_VERTEX_SHADER: 1595 case SST_TESSELATION_CONTROL_SHADER: 1596 case SST_TESSELATION_EVALUATION_SHADER: 1597 case SST_GEOMETRY_SHADER: 1598 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 1599 break; 1600 default: 1601 break; 1602 } 1603 1604 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures(); 1605 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE) 1606 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands"); 1607 1608 // Check supported vertex format. 1609 checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.vertexFormat); 1610} 1611 1612void RayQueryASBasicTestCase::initPrograms (SourceCollections& programCollection) const 1613{ 1614 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 1615 1616 // create parts of programs responsible for test execution 1617 std::vector<std::string> rayQueryTest; 1618 std::vector<std::string> rayQueryTestName; 1619 rayQueryTestName.push_back("as_triangle"); 1620 rayQueryTestName.push_back("as_aabb"); 1621 1622 { 1623 std::stringstream css; 1624 css << 1625 " float tmin = 0.0;\n" 1626 " float tmax = 1.0;\n" 1627 " vec3 direct = vec3(0.0, 0.0, -1.0);\n" 1628 " rayQueryEXT rq;\n" 1629 " rayQueryInitializeEXT(rq, rqTopLevelAS, " << ((m_data.cullFlags == InstanceCullFlags::NONE) ? "0" : "gl_RayFlagsCullBackFacingTrianglesEXT") << ", 0xFF, origin, tmin, direct, tmax);\n" 1630 " if(rayQueryProceedEXT(rq))\n" 1631 " {\n" 1632 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n" 1633 " {\n" 1634 " hitValue.y = 1;\n" 1635 " hitValue.x = 1;\n" 1636 " }\n" 1637 " }\n"; 1638 rayQueryTest.push_back(css.str()); 1639 } 1640 { 1641 std::stringstream css; 1642 css << 1643 " float tmin = 0.0;\n" 1644 " float tmax = 1.0;\n" 1645 " vec3 direct = vec3(0.0, 0.0, -1.0);\n" 1646 " rayQueryEXT rq;\n" 1647 " rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n" 1648 " if(rayQueryProceedEXT(rq))\n" 1649 " {\n" 1650 " if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n" 1651 " {\n" 1652 " hitValue.y = 1;\n" 1653 " hitValue.x = 1;\n" 1654 " }\n" 1655 " }\n"; 1656 rayQueryTest.push_back(css.str()); 1657 } 1658 1659 const auto bottomTestTypeIdx = static_cast<int>(m_data.bottomTestType); 1660 1661 // create all programs 1662 if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE) 1663 { 1664 { 1665 std::stringstream css; 1666 css << 1667 "#version 460 core\n" 1668 "layout (location = 0) in vec3 position;\n" 1669 "out gl_PerVertex\n" 1670 "{\n" 1671 " vec4 gl_Position;\n" 1672 "};\n" 1673 "void main()\n" 1674 "{\n" 1675 " gl_Position = vec4(position, 1.0);\n" 1676 "}\n"; 1677 programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions; 1678 } 1679 1680 { 1681 std::stringstream css; 1682 css << 1683 "#version 460 core\n" 1684 "layout (location = 0) in vec3 position;\n" 1685 "out gl_PerVertex\n" 1686 "{\n" 1687 " vec4 gl_Position;\n" 1688 "};\n" 1689 "layout(location = 0) out int vertexIndex;\n" 1690 "void main()\n" 1691 "{\n" 1692 " gl_Position = vec4(position, 1.0);\n" 1693 " vertexIndex = gl_VertexIndex;\n" 1694 "}\n"; 1695 programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str()) << buildOptions; 1696 } 1697 1698 { 1699 std::stringstream css; 1700 css << 1701 "#version 460 core\n" 1702 "#extension GL_EXT_ray_query : require\n" 1703 "layout (location = 0) in vec3 position;\n" 1704 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1705 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n" 1706 "void main()\n" 1707 "{\n" 1708 " vec3 origin = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n" 1709 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1710 rayQueryTest[bottomTestTypeIdx] << 1711 " imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1712 " imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1713 " gl_Position = vec4(position,1);\n" 1714 "}\n"; 1715 std::stringstream cssName; 1716 cssName << "vert_" << rayQueryTestName[bottomTestTypeIdx]; 1717 1718 programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions; 1719 } 1720 1721 { 1722 std::stringstream css; 1723 css << 1724 "#version 460 core\n" 1725 "#extension GL_EXT_tessellation_shader : require\n" 1726 "in gl_PerVertex {\n" 1727 " vec4 gl_Position;\n" 1728 "} gl_in[];\n" 1729 "layout(vertices = 3) out;\n" 1730 "void main (void)\n" 1731 "{\n" 1732 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 1733 " gl_TessLevelInner[0] = 1;\n" 1734 " gl_TessLevelOuter[0] = 1;\n" 1735 " gl_TessLevelOuter[1] = 1;\n" 1736 " gl_TessLevelOuter[2] = 1;\n" 1737 "}\n"; 1738 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions; 1739 } 1740 1741 { 1742 std::stringstream css; 1743 css << 1744 "#version 460 core\n" 1745 "#extension GL_EXT_tessellation_shader : require\n" 1746 "#extension GL_EXT_ray_query : require\n" 1747 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1748 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n" 1749 "in gl_PerVertex {\n" 1750 " vec4 gl_Position;\n" 1751 "} gl_in[];\n" 1752 "layout(vertices = 3) out;\n" 1753 "void main (void)\n" 1754 "{\n" 1755 " vec3 origin = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n" 1756 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1757 rayQueryTest[bottomTestTypeIdx] << 1758 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1759 " imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1760 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 1761 " gl_TessLevelInner[0] = 1;\n" 1762 " gl_TessLevelOuter[0] = 1;\n" 1763 " gl_TessLevelOuter[1] = 1;\n" 1764 " gl_TessLevelOuter[2] = 1;\n" 1765 "}\n"; 1766 std::stringstream cssName; 1767 cssName << "tesc_" << rayQueryTestName[bottomTestTypeIdx]; 1768 1769 programCollection.glslSources.add(cssName.str()) << glu::TessellationControlSource(css.str()) << buildOptions; 1770 } 1771 1772 { 1773 std::stringstream css; 1774 css << 1775 "#version 460 core\n" 1776 "#extension GL_EXT_tessellation_shader : require\n" 1777 "#extension GL_EXT_ray_query : require\n" 1778 "layout(triangles, equal_spacing, ccw) in;\n" 1779 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1780 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n" 1781 "void main (void)\n" 1782 "{\n" 1783 " for (int i = 0; i < 3; ++i)\n" 1784 " {\n" 1785 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n" 1786 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1787 rayQueryTest[bottomTestTypeIdx] << 1788 " imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1789 " imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1790 " }\n" 1791 " gl_Position = gl_in[0].gl_Position;\n" 1792 "}\n"; 1793 std::stringstream cssName; 1794 cssName << "tese_" << rayQueryTestName[bottomTestTypeIdx]; 1795 1796 programCollection.glslSources.add(cssName.str()) << glu::TessellationEvaluationSource(css.str()) << buildOptions; 1797 } 1798 1799 { 1800 std::stringstream css; 1801 css << 1802 "#version 460 core\n" 1803 "#extension GL_EXT_tessellation_shader : require\n" 1804 "layout(triangles, equal_spacing, ccw) in;\n" 1805 "void main (void)\n" 1806 "{\n" 1807 " gl_Position = gl_in[0].gl_Position;\n" 1808 "}\n"; 1809 1810 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions; 1811 } 1812 1813 { 1814 std::stringstream css; 1815 css << 1816 "#version 460 core\n" 1817 "#extension GL_EXT_ray_query : require\n" 1818 "layout(triangles) in;\n" 1819 "layout (triangle_strip, max_vertices = 4) out;\n" 1820 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1821 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n" 1822 "\n" 1823 "in gl_PerVertex {\n" 1824 " vec4 gl_Position;\n" 1825 "} gl_in[];\n" 1826 "layout(location = 0) in int vertexIndex[];\n" 1827 "out gl_PerVertex {\n" 1828 " vec4 gl_Position;\n" 1829 "};\n" 1830 "void main (void)\n" 1831 "{\n" 1832 " // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n" 1833 " // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n" 1834 " // smallest vertex index value.\n" 1835 " int minVertexIndex = 10000;" 1836 " int firstVertex;" 1837 " for (int i = 0; i < gl_in.length(); ++i)\n" 1838 " {\n" 1839 " if (minVertexIndex > vertexIndex[i])\n" 1840 " {\n" 1841 " minVertexIndex = vertexIndex[i];\n" 1842 " firstVertex = i;\n" 1843 " }\n" 1844 " }\n" 1845 " for (int j = 0; j < gl_in.length(); ++j)\n" 1846 " {\n" 1847 " // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n" 1848 " // always iterated starting from the smallest vertex index, as found above.\n" 1849 " int i = (firstVertex + j) % gl_in.length();\n" 1850 " vec3 origin = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n" 1851 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1852 rayQueryTest[bottomTestTypeIdx] << 1853 " imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1854 " imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1855 " gl_Position = gl_in[i].gl_Position;\n" 1856 " EmitVertex();\n" 1857 " }\n" 1858 " EndPrimitive();\n" 1859 "}\n"; 1860 std::stringstream cssName; 1861 cssName << "geom_" << rayQueryTestName[bottomTestTypeIdx]; 1862 1863 programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions; 1864 } 1865 1866 { 1867 std::stringstream css; 1868 css << 1869 "#version 460 core\n" 1870 "#extension GL_EXT_ray_query : require\n" 1871 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1872 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n" 1873 "void main()\n" 1874 "{\n" 1875 " vec3 origin = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n" 1876 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1877 rayQueryTest[bottomTestTypeIdx] << 1878 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n" 1879 " imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n" 1880 "}\n"; 1881 std::stringstream cssName; 1882 cssName << "frag_" << rayQueryTestName[bottomTestTypeIdx]; 1883 1884 programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions; 1885 } 1886 } 1887 else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE) 1888 { 1889 { 1890 std::stringstream css; 1891 css << 1892 "#version 460 core\n" 1893 "#extension GL_EXT_ray_query : require\n" 1894 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1895 "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n" 1896 "void main()\n" 1897 "{\n" 1898 " vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);\n" 1899 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1900 rayQueryTest[bottomTestTypeIdx] << 1901 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1902 " imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1903 "}\n"; 1904 std::stringstream cssName; 1905 cssName << "comp_" << rayQueryTestName[bottomTestTypeIdx]; 1906 1907 programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions; 1908 } 1909 } 1910 else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE) 1911 { 1912 { 1913 std::stringstream css; 1914 css << 1915 "#version 460 core\n" 1916 "#extension GL_EXT_ray_tracing : require\n" 1917 "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n" 1918 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1919 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n" 1920 "void main()\n" 1921 "{\n" 1922 " float tmin = 0.0;\n" 1923 " float tmax = 1.0;\n" 1924 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n" 1925 " vec3 direct = vec3(0.0, 0.0, -1.0);\n" 1926 " hitValue = uvec4(0,0,0,0);\n" 1927 " traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n" 1928 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1929 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1930 "}\n"; 1931 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions; 1932 } 1933 1934 { 1935 std::stringstream css; 1936 css << 1937 "#version 460 core\n" 1938 "#extension GL_EXT_ray_tracing : require\n" 1939 "#extension GL_EXT_ray_query : require\n" 1940 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1941 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n" 1942 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n" 1943 "void main()\n" 1944 "{\n" 1945 " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n" 1946 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 1947 rayQueryTest[bottomTestTypeIdx] << 1948 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n" 1949 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n" 1950 "}\n"; 1951 std::stringstream cssName; 1952 cssName << "rgen_" << rayQueryTestName[bottomTestTypeIdx]; 1953 1954 programCollection.glslSources.add(cssName.str()) << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions; 1955 } 1956 1957 { 1958 std::stringstream css; 1959 css << 1960 "#version 460 core\n" 1961 "#extension GL_EXT_ray_tracing : require\n" 1962 "struct CallValue\n{\n" 1963 " vec3 origin;\n" 1964 " uvec4 hitValue;\n" 1965 "};\n" 1966 "layout(location = 0) callableDataEXT CallValue param;\n" 1967 "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" 1968 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n" 1969 "void main()\n" 1970 "{\n" 1971 " param.origin = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n" 1972 " param.hitValue = uvec4(0, 0, 0, 0);\n" 1973 " executeCallableEXT(0, 0);\n" 1974 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n" 1975 " imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n" 1976 "}\n"; 1977 programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions; 1978 } 1979 1980 { 1981 std::stringstream css; 1982 css << 1983 "#version 460 core\n" 1984 "#extension GL_EXT_ray_tracing : require\n" 1985 "hitAttributeEXT uvec4 hitValue;\n" 1986 "void main()\n" 1987 "{\n" 1988 " reportIntersectionEXT(0.5f, 0);\n" 1989 "}\n"; 1990 1991 programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions; 1992 } 1993 1994 { 1995 std::stringstream css; 1996 css << 1997 "#version 460 core\n" 1998 "#extension GL_EXT_ray_tracing : require\n" 1999 "#extension GL_EXT_ray_query : require\n" 2000 "hitAttributeEXT uvec4 hitValue;\n" 2001 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n" 2002 "void main()\n" 2003 "{\n" 2004 " vec3 origin = gl_WorldRayOriginEXT;\n" 2005 " hitValue = uvec4(0,0,0,0);\n" << 2006 rayQueryTest[bottomTestTypeIdx] << 2007 " reportIntersectionEXT(0.5f, 0);\n" 2008 "}\n"; 2009 std::stringstream cssName; 2010 cssName << "isect_" << rayQueryTestName[bottomTestTypeIdx]; 2011 2012 programCollection.glslSources.add(cssName.str()) << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions; 2013 } 2014 2015 { 2016 std::stringstream css; 2017 css << 2018 "#version 460 core\n" 2019 "#extension GL_EXT_ray_tracing : require\n" 2020 "#extension GL_EXT_ray_query : require\n" 2021 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" 2022 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n" 2023 "void main()\n" 2024 "{\n" 2025 " vec3 origin = gl_WorldRayOriginEXT;\n" << 2026 rayQueryTest[bottomTestTypeIdx] << 2027 "}\n"; 2028 std::stringstream cssName; 2029 cssName << "ahit_" << rayQueryTestName[bottomTestTypeIdx]; 2030 2031 programCollection.glslSources.add(cssName.str()) << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions; 2032 } 2033 2034 { 2035 std::stringstream css; 2036 css << 2037 "#version 460 core\n" 2038 "#extension GL_EXT_ray_tracing : require\n" 2039 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" 2040 "void main()\n" 2041 "{\n" 2042 " hitValue.y = 3;\n" 2043 "}\n"; 2044 2045 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions; 2046 } 2047 2048 { 2049 std::stringstream css; 2050 css << 2051 "#version 460 core\n" 2052 "#extension GL_EXT_ray_tracing : require\n" 2053 "#extension GL_EXT_ray_query : require\n" 2054 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" 2055 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n" 2056 "void main()\n" 2057 "{\n" 2058 " vec3 origin = gl_WorldRayOriginEXT;\n" << 2059 rayQueryTest[bottomTestTypeIdx] << 2060 "}\n"; 2061 std::stringstream cssName; 2062 cssName << "chit_" << rayQueryTestName[bottomTestTypeIdx]; 2063 2064 programCollection.glslSources.add(cssName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions; 2065 } 2066 2067 { 2068 std::stringstream css; 2069 css << 2070 "#version 460 core\n" 2071 "#extension GL_EXT_ray_tracing : require\n" 2072 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" 2073 "hitAttributeEXT uvec4 hitAttrib;\n" 2074 "void main()\n" 2075 "{\n" 2076 " hitValue = hitAttrib;\n" 2077 "}\n"; 2078 2079 programCollection.glslSources.add("chit_isect") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions; 2080 } 2081 2082 { 2083 std::stringstream css; 2084 css << 2085 "#version 460 core\n" 2086 "#extension GL_EXT_ray_tracing : require\n" 2087 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" 2088 "void main()\n" 2089 "{\n" 2090 " hitValue.x = 4;\n" 2091 "}\n"; 2092 2093 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions; 2094 } 2095 2096 { 2097 std::stringstream css; 2098 css << 2099 "#version 460 core\n" 2100 "#extension GL_EXT_ray_tracing : require\n" 2101 "#extension GL_EXT_ray_query : require\n" 2102 "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" 2103 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n" 2104 "void main()\n" 2105 "{\n" 2106 " vec3 origin = gl_WorldRayOriginEXT;\n" << 2107 rayQueryTest[bottomTestTypeIdx] << 2108 "}\n"; 2109 std::stringstream cssName; 2110 cssName << "miss_" << rayQueryTestName[bottomTestTypeIdx]; 2111 2112 programCollection.glslSources.add(cssName.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions; 2113 } 2114 2115 { 2116 std::stringstream css; 2117 css << 2118 "#version 460 core\n" 2119 "#extension GL_EXT_ray_tracing : require\n" 2120 "#extension GL_EXT_ray_query : require\n" 2121 "struct CallValue\n{\n" 2122 " vec3 origin;\n" 2123 " uvec4 hitValue;\n" 2124 "};\n" 2125 "layout(location = 0) callableDataInEXT CallValue result;\n" 2126 "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n" 2127 "void main()\n" 2128 "{\n" 2129 " vec3 origin = result.origin;\n" 2130 " uvec4 hitValue = uvec4(0,0,0,0);\n" << 2131 rayQueryTest[bottomTestTypeIdx] << 2132 " result.hitValue = hitValue;\n" 2133 "}\n"; 2134 std::stringstream cssName; 2135 cssName << "call_" << rayQueryTestName[bottomTestTypeIdx]; 2136 2137 programCollection.glslSources.add(cssName.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions; 2138 } 2139 } 2140} 2141 2142TestInstance* RayQueryASBasicTestCase::createInstance (Context& context) const 2143{ 2144 return new RayQueryASBasicTestInstance(context, m_data); 2145} 2146 2147RayQueryASFuncArgTestCase::RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const TestParams& data) 2148 : RayQueryASBasicTestCase (context, name, data) 2149{ 2150} 2151 2152void RayQueryASFuncArgTestCase::initPrograms (SourceCollections& programCollection) const 2153{ 2154 const vk::SpirVAsmBuildOptions spvBuildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true); 2155 2156 DE_ASSERT(m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE); 2157 DE_ASSERT(m_data.bottomTestType == BottomTestType::TRIANGLES); 2158 2159 // The SPIR-V assembly shader below is based on the following GLSL code. 2160 // In it, rayQueryInitializeBottomWrapper has been modified to take a 2161 // bare AS as the second argument, instead of a pointer. 2162 // 2163 // #version 460 core 2164 // #extension GL_EXT_ray_query : require 2165 // layout(r32ui, set = 0, binding = 0) uniform uimage3D result; 2166 // layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS; 2167 // 2168 // void rayQueryInitializeBottomWrapper(rayQueryEXT rayQuery, 2169 // accelerationStructureEXT topLevel, 2170 // uint rayFlags, uint cullMask, vec3 origin, 2171 // float tMin, vec3 direction, float tMax) 2172 // { 2173 // rayQueryInitializeEXT(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax); 2174 // } 2175 // 2176 // void rayQueryInitializeTopWrapper(rayQueryEXT rayQuery, 2177 // accelerationStructureEXT topLevel, 2178 // uint rayFlags, uint cullMask, vec3 origin, 2179 // float tMin, vec3 direction, float tMax) 2180 // { 2181 // rayQueryInitializeBottomWrapper(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax); 2182 // } 2183 // 2184 // void main() 2185 // { 2186 // vec3 origin = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5); 2187 // uvec4 hitValue = uvec4(0,0,0,0); 2188 // float tmin = 0.0; 2189 // float tmax = 1.0; 2190 // vec3 direct = vec3(0.0, 0.0, -1.0); 2191 // rayQueryEXT rq; 2192 // rayQueryInitializeTopWrapper(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax); 2193 // if(rayQueryProceedEXT(rq)) 2194 // { 2195 // if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT) 2196 // { 2197 // hitValue.y = 1; 2198 // hitValue.x = 1; 2199 // } 2200 // } 2201 // imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0)); 2202 // imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0)); 2203 // } 2204 2205 std::stringstream css; 2206 css 2207 << "; SPIR-V\n" 2208 << "; Version: 1.4\n" 2209 << "; Generator: Khronos Glslang Reference Front End; 10\n" 2210 << "; Bound: 139\n" 2211 << "; Schema: 0\n" 2212 << "OpCapability Shader\n" 2213 << "OpCapability RayQueryKHR\n" 2214 << "OpExtension \"SPV_KHR_ray_query\"\n" 2215 << "%1 = OpExtInstImport \"GLSL.std.450\"\n" 2216 << "OpMemoryModel Logical GLSL450\n" 2217 << "OpEntryPoint GLCompute %4 \"main\" %60 %86 %114\n" 2218 << "OpExecutionMode %4 LocalSize 1 1 1\n" 2219 << "OpDecorate %60 BuiltIn GlobalInvocationId\n" 2220 << "OpDecorate %86 DescriptorSet 0\n" 2221 << "OpDecorate %86 Binding 1\n" 2222 << "OpDecorate %114 DescriptorSet 0\n" 2223 << "OpDecorate %114 Binding 0\n" 2224 << "%2 = OpTypeVoid\n" 2225 << "%3 = OpTypeFunction %2\n" 2226 2227 // Bare query type 2228 << "%6 = OpTypeRayQueryKHR\n" 2229 2230 // Pointer to query. 2231 << "%7 = OpTypePointer Function %6\n" 2232 2233 // Bare AS type. 2234 << "%8 = OpTypeAccelerationStructureKHR\n" 2235 2236 // Pointer to AS. 2237 << "%9 = OpTypePointer UniformConstant %8\n" 2238 2239 << "%10 = OpTypeInt 32 0\n" 2240 << "%11 = OpTypePointer Function %10\n" 2241 << "%12 = OpTypeFloat 32\n" 2242 << "%13 = OpTypeVector %12 3\n" 2243 << "%14 = OpTypePointer Function %13\n" 2244 << "%15 = OpTypePointer Function %12\n" 2245 2246 // This is the function type for rayQueryInitializeTopWrapper and the old rayQueryInitializeBottomWrapper. 2247 << "%16 = OpTypeFunction %2 %7 %9 %11 %11 %14 %15 %14 %15\n" 2248 2249 // This is the new function type for the modified rayQueryInitializeBottomWrapper that uses a bare AS. 2250 //<< "%16b = OpTypeFunction %2 %6 %8 %11 %11 %14 %15 %14 %15\n" 2251 << "%16b = OpTypeFunction %2 %7 %8 %11 %11 %14 %15 %14 %15\n" 2252 2253 << "%58 = OpTypeVector %10 3\n" 2254 << "%59 = OpTypePointer Input %58\n" 2255 << "%60 = OpVariable %59 Input\n" 2256 << "%61 = OpConstant %10 0\n" 2257 << "%62 = OpTypePointer Input %10\n" 2258 << "%66 = OpConstant %12 0.5\n" 2259 << "%68 = OpConstant %10 1\n" 2260 << "%74 = OpTypeVector %10 4\n" 2261 << "%75 = OpTypePointer Function %74\n" 2262 << "%77 = OpConstantComposite %74 %61 %61 %61 %61\n" 2263 << "%79 = OpConstant %12 0\n" 2264 << "%81 = OpConstant %12 1\n" 2265 << "%83 = OpConstant %12 -1\n" 2266 << "%84 = OpConstantComposite %13 %79 %79 %83\n" 2267 << "%86 = OpVariable %9 UniformConstant\n" 2268 << "%87 = OpConstant %10 255\n" 2269 << "%99 = OpTypeBool\n" 2270 << "%103 = OpConstantFalse %99\n" 2271 << "%104 = OpTypeInt 32 1\n" 2272 << "%105 = OpConstant %104 0\n" 2273 << "%112 = OpTypeImage %10 3D 0 0 0 2 R32ui\n" 2274 << "%113 = OpTypePointer UniformConstant %112\n" 2275 << "%114 = OpVariable %113 UniformConstant\n" 2276 << "%116 = OpTypeVector %10 2\n" 2277 << "%119 = OpTypeVector %104 2\n" 2278 << "%121 = OpTypeVector %104 3\n" 2279 << "%132 = OpConstant %104 1\n" 2280 2281 // This is main(). 2282 << "%4 = OpFunction %2 None %3\n" 2283 << "%5 = OpLabel\n" 2284 << "%57 = OpVariable %14 Function\n" 2285 << "%76 = OpVariable %75 Function\n" 2286 << "%78 = OpVariable %15 Function\n" 2287 << "%80 = OpVariable %15 Function\n" 2288 << "%82 = OpVariable %14 Function\n" 2289 << "%85 = OpVariable %7 Function\n" 2290 << "%88 = OpVariable %11 Function\n" 2291 << "%89 = OpVariable %11 Function\n" 2292 << "%90 = OpVariable %14 Function\n" 2293 << "%92 = OpVariable %15 Function\n" 2294 << "%94 = OpVariable %14 Function\n" 2295 << "%96 = OpVariable %15 Function\n" 2296 << "%63 = OpAccessChain %62 %60 %61\n" 2297 << "%64 = OpLoad %10 %63\n" 2298 << "%65 = OpConvertUToF %12 %64\n" 2299 << "%67 = OpFAdd %12 %65 %66\n" 2300 << "%69 = OpAccessChain %62 %60 %68\n" 2301 << "%70 = OpLoad %10 %69\n" 2302 << "%71 = OpConvertUToF %12 %70\n" 2303 << "%72 = OpFAdd %12 %71 %66\n" 2304 << "%73 = OpCompositeConstruct %13 %67 %72 %66\n" 2305 << "OpStore %57 %73\n" 2306 << "OpStore %76 %77\n" 2307 << "OpStore %78 %79\n" 2308 << "OpStore %80 %81\n" 2309 << "OpStore %82 %84\n" 2310 << "OpStore %88 %61\n" 2311 << "OpStore %89 %87\n" 2312 << "%91 = OpLoad %13 %57\n" 2313 << "OpStore %90 %91\n" 2314 << "%93 = OpLoad %12 %78\n" 2315 << "OpStore %92 %93\n" 2316 << "%95 = OpLoad %13 %82\n" 2317 << "OpStore %94 %95\n" 2318 << "%97 = OpLoad %12 %80\n" 2319 << "OpStore %96 %97\n" 2320 << "%98 = OpFunctionCall %2 %35 %85 %86 %88 %89 %90 %92 %94 %96\n" 2321 << "%100 = OpRayQueryProceedKHR %99 %85\n" 2322 << "OpSelectionMerge %102 None\n" 2323 << "OpBranchConditional %100 %101 %102\n" 2324 << "%101 = OpLabel\n" 2325 << "%106 = OpRayQueryGetIntersectionTypeKHR %10 %85 %105\n" 2326 << "%107 = OpIEqual %99 %106 %61\n" 2327 << "OpSelectionMerge %109 None\n" 2328 << "OpBranchConditional %107 %108 %109\n" 2329 << "%108 = OpLabel\n" 2330 << "%110 = OpAccessChain %11 %76 %68\n" 2331 << "OpStore %110 %68\n" 2332 << "%111 = OpAccessChain %11 %76 %61\n" 2333 << "OpStore %111 %68\n" 2334 << "OpBranch %109\n" 2335 << "%109 = OpLabel\n" 2336 << "OpBranch %102\n" 2337 << "%102 = OpLabel\n" 2338 << "%115 = OpLoad %112 %114\n" 2339 << "%117 = OpLoad %58 %60\n" 2340 << "%118 = OpVectorShuffle %116 %117 %117 0 1\n" 2341 << "%120 = OpBitcast %119 %118\n" 2342 << "%122 = OpCompositeExtract %104 %120 0\n" 2343 << "%123 = OpCompositeExtract %104 %120 1\n" 2344 << "%124 = OpCompositeConstruct %121 %122 %123 %105\n" 2345 << "%125 = OpAccessChain %11 %76 %61\n" 2346 << "%126 = OpLoad %10 %125\n" 2347 << "%127 = OpCompositeConstruct %74 %126 %61 %61 %61\n" 2348 << "OpImageWrite %115 %124 %127 ZeroExtend\n" 2349 << "%128 = OpLoad %112 %114\n" 2350 << "%129 = OpLoad %58 %60\n" 2351 << "%130 = OpVectorShuffle %116 %129 %129 0 1\n" 2352 << "%131 = OpBitcast %119 %130\n" 2353 << "%133 = OpCompositeExtract %104 %131 0\n" 2354 << "%134 = OpCompositeExtract %104 %131 1\n" 2355 << "%135 = OpCompositeConstruct %121 %133 %134 %132\n" 2356 << "%136 = OpAccessChain %11 %76 %68\n" 2357 << "%137 = OpLoad %10 %136\n" 2358 << "%138 = OpCompositeConstruct %74 %137 %61 %61 %61\n" 2359 << "OpImageWrite %128 %135 %138 ZeroExtend\n" 2360 << "OpReturn\n" 2361 << "OpFunctionEnd\n" 2362 2363 // This is rayQueryInitializeBottomWrapper, calling OpRayQueryInitializeKHR. 2364 // We have modified the function type so it takes bare arguments. 2365 //%25 = OpFunction %2 None %16 2366 << "%25 = OpFunction %2 None %16b\n" 2367 2368 // These is the modified parameter. 2369 << "%17 = OpFunctionParameter %7\n" 2370 //<< "%17 = OpFunctionParameter %6\n" 2371 //%18 = OpFunctionParameter %9 2372 << "%18 = OpFunctionParameter %8\n" 2373 2374 << "%19 = OpFunctionParameter %11\n" 2375 << "%20 = OpFunctionParameter %11\n" 2376 << "%21 = OpFunctionParameter %14\n" 2377 << "%22 = OpFunctionParameter %15\n" 2378 << "%23 = OpFunctionParameter %14\n" 2379 << "%24 = OpFunctionParameter %15\n" 2380 << "%26 = OpLabel\n" 2381 2382 // We no longer need to load this parameter. 2383 //%37 = OpLoad %8 %18 2384 2385 << "%38 = OpLoad %10 %19\n" 2386 << "%39 = OpLoad %10 %20\n" 2387 << "%40 = OpLoad %13 %21\n" 2388 << "%41 = OpLoad %12 %22\n" 2389 << "%42 = OpLoad %13 %23\n" 2390 << "%43 = OpLoad %12 %24\n" 2391 2392 // We call OpRayQueryInitializeKHR with bare arguments. 2393 // Note: some experimental lines to pass a bare rayQuery as the first argument have been commented out. 2394 //OpRayQueryInitializeKHR %17 %37 %38 %39 %40 %41 %42 %43 2395 << "OpRayQueryInitializeKHR %17 %18 %38 %39 %40 %41 %42 %43\n" 2396 2397 << "OpReturn\n" 2398 << "OpFunctionEnd\n" 2399 2400 // This is rayQueryInitializeTopWrapper, calling rayQueryInitializeBottomWrapper. 2401 << "%35 = OpFunction %2 None %16\n" 2402 << "%27 = OpFunctionParameter %7\n" 2403 << "%28 = OpFunctionParameter %9\n" 2404 << "%29 = OpFunctionParameter %11\n" 2405 << "%30 = OpFunctionParameter %11\n" 2406 << "%31 = OpFunctionParameter %14\n" 2407 << "%32 = OpFunctionParameter %15\n" 2408 << "%33 = OpFunctionParameter %14\n" 2409 << "%34 = OpFunctionParameter %15\n" 2410 << "%36 = OpLabel\n" 2411 << "%44 = OpVariable %11 Function\n" 2412 << "%46 = OpVariable %11 Function\n" 2413 << "%48 = OpVariable %14 Function\n" 2414 << "%50 = OpVariable %15 Function\n" 2415 << "%52 = OpVariable %14 Function\n" 2416 << "%54 = OpVariable %15 Function\n" 2417 2418 // We need to load the second argument. 2419 //<< "%27b = OpLoad %6 %27\n" 2420 << "%28b = OpLoad %8 %28\n" 2421 2422 << "%45 = OpLoad %10 %29\n" 2423 << "OpStore %44 %45\n" 2424 << "%47 = OpLoad %10 %30\n" 2425 << "OpStore %46 %47\n" 2426 << "%49 = OpLoad %13 %31\n" 2427 << "OpStore %48 %49\n" 2428 << "%51 = OpLoad %12 %32\n" 2429 << "OpStore %50 %51\n" 2430 << "%53 = OpLoad %13 %33\n" 2431 << "OpStore %52 %53\n" 2432 << "%55 = OpLoad %12 %34\n" 2433 << "OpStore %54 %55\n" 2434 2435 // We call rayQueryInitializeBottomWrapper with the loaded argument. 2436 //%56 = OpFunctionCall %2 %25 %27 %28 %44 %46 %48 %50 %52 %54 2437 //<< "%56 = OpFunctionCall %2 %25 %27b %28b %44 %46 %48 %50 %52 %54\n" 2438 << "%56 = OpFunctionCall %2 %25 %27 %28b %44 %46 %48 %50 %52 %54\n" 2439 2440 << "OpReturn\n" 2441 << "OpFunctionEnd\n" 2442 ; 2443 2444 programCollection.spirvAsmSources.add("comp_as_triangle") << spvBuildOptions << css.str(); 2445} 2446 2447RayQueryASBasicTestInstance::RayQueryASBasicTestInstance (Context& context, const TestParams& data) 2448 : vkt::TestInstance (context) 2449 , m_data (data) 2450{ 2451} 2452 2453RayQueryASBasicTestInstance::~RayQueryASBasicTestInstance (void) 2454{ 2455} 2456 2457de::MovePtr<BufferWithMemory> RayQueryASBasicTestInstance::runTest (TestConfiguration* testConfiguration, 2458 SceneBuilder* sceneBuilder, 2459 const deUint32 workerThreadsCount) 2460{ 2461 testConfiguration->initConfiguration(m_context, m_data); 2462 2463 const DeviceInterface& vkd = m_context.getDeviceInterface(); 2464 const VkDevice device = m_context.getDevice(); 2465 const VkQueue queue = m_context.getUniversalQueue(); 2466 Allocator& allocator = m_context.getDefaultAllocator(); 2467 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 2468 2469 const bool htCopy = (workerThreadsCount != 0) && (m_data.operationType == OP_COPY); 2470 const bool htSerialize = (workerThreadsCount != 0) && (m_data.operationType == OP_SERIALIZE); 2471 2472 2473 const VkFormat imageFormat = testConfiguration->getResultImageFormat(); 2474 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat); 2475 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 2476 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any)); 2477 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange); 2478 2479 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT); 2480 const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u); 2481 const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers); 2482 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible)); 2483 2484 const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL); 2485 2486 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex); 2487 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2488 2489 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures; 2490 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure; 2491 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructureCopies; 2492 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructureCopy; 2493 std::vector<de::SharedPtr<SerialStorage>> bottomSerialized; 2494 std::vector<de::SharedPtr<SerialStorage>> topSerialized; 2495 std::vector<VkDeviceSize> accelerationCompactedSizes; 2496 std::vector<VkDeviceSize> accelerationSerialSizes; 2497 Move<VkQueryPool> m_queryPoolCompact; 2498 Move<VkQueryPool> m_queryPoolSerial; 2499 2500 beginCommandBuffer(vkd, *cmdBuffer, 0u); 2501 { 2502 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, 2503 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 2504 **image, imageSubresourceRange); 2505 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier); 2506 2507 const VkClearValue clearValue = testConfiguration->getClearValue(); 2508 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange); 2509 2510 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, 2511 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 2512 **image, imageSubresourceRange); 2513 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier); 2514 2515 // build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures ) 2516 bool bottomCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION; 2517 bool bottomSerial = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION; 2518 const bool buildWithoutGeom = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM); 2519 const bool bottomNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM); 2520 const bool topNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP); 2521 const bool inactiveInstances = (m_data.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_INSTANCES); 2522 bottomLevelAccelerationStructures = sceneBuilder->initBottomAccelerationStructures(m_context, m_data); 2523 VkBuildAccelerationStructureFlagsKHR allowCompactionFlag = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR; 2524 VkBuildAccelerationStructureFlagsKHR emptyCompactionFlag = VkBuildAccelerationStructureFlagsKHR(0); 2525 VkBuildAccelerationStructureFlagsKHR bottomCompactFlags = (bottomCompact ? allowCompactionFlag : emptyCompactionFlag); 2526 VkBuildAccelerationStructureFlagsKHR bottomBuildFlags = m_data.buildFlags | bottomCompactFlags; 2527 std::vector<VkAccelerationStructureKHR> accelerationStructureHandles; 2528 std::vector<VkDeviceSize> bottomBlasCompactSize; 2529 std::vector<VkDeviceSize> bottomBlasSerialSize; 2530 2531 for (auto& blas : bottomLevelAccelerationStructures) 2532 { 2533 blas->setBuildType (m_data.buildType); 2534 blas->setBuildFlags (bottomBuildFlags); 2535 blas->setUseArrayOfPointers (m_data.bottomUsesAOP); 2536 blas->setCreateGeneric (m_data.bottomGeneric); 2537 blas->setCreationBufferUnbounded (m_data.bottomUnboundedCreation); 2538 blas->setBuildWithoutGeometries (buildWithoutGeom); 2539 blas->setBuildWithoutPrimitives (bottomNoPrimitives); 2540 blas->createAndBuild (vkd, device, *cmdBuffer, allocator); 2541 accelerationStructureHandles.push_back (*(blas->getPtr())); 2542 } 2543 2544 if (m_data.operationType == OP_COMPACT) 2545 { 2546 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u; 2547 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2548 m_queryPoolCompact = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount); 2549 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION) 2550 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize); 2551 } 2552 if (m_data.operationType == OP_SERIALIZE) 2553 { 2554 deUint32 queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u; 2555 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2556 m_queryPoolSerial = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount); 2557 if (m_data.operationTarget == OT_BOTTOM_ACCELERATION) 2558 queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize); 2559 } 2560 2561 // if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU 2562 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial)) 2563 { 2564 endCommandBuffer(vkd, *cmdBuffer); 2565 2566 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 2567 2568 if (bottomCompact) 2569 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(bottomBlasCompactSize.size()), sizeof(VkDeviceSize) * bottomBlasCompactSize.size(), bottomBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)); 2570 if (bottomSerial) 2571 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(bottomBlasSerialSize.size()), sizeof(VkDeviceSize) * bottomBlasSerialSize.size(), bottomBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)); 2572 2573 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); 2574 beginCommandBuffer(vkd, *cmdBuffer, 0u); 2575 } 2576 2577 auto bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructures; 2578 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION) 2579 { 2580 switch (m_data.operationType) 2581 { 2582 case OP_COPY: 2583 { 2584 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i) 2585 { 2586 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure(); 2587 asCopy->setDeferredOperation(htCopy, workerThreadsCount); 2588 asCopy->setBuildType(m_data.buildType); 2589 asCopy->setBuildFlags(m_data.buildFlags); 2590 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP); 2591 asCopy->setCreateGeneric(m_data.bottomGeneric); 2592 asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation); 2593 asCopy->setBuildWithoutGeometries(buildWithoutGeom); 2594 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives); 2595 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), 0u, 0u); 2596 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release())); 2597 } 2598 break; 2599 } 2600 case OP_COMPACT: 2601 { 2602 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i) 2603 { 2604 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure(); 2605 asCopy->setBuildType(m_data.buildType); 2606 asCopy->setBuildFlags(m_data.buildFlags); 2607 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP); 2608 asCopy->setCreateGeneric(m_data.bottomGeneric); 2609 asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation); 2610 asCopy->setBuildWithoutGeometries(buildWithoutGeom); 2611 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives); 2612 asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), bottomBlasCompactSize[i], 0u); 2613 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release())); 2614 } 2615 break; 2616 } 2617 case OP_SERIALIZE: 2618 { 2619 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i) 2620 { 2621 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, bottomBlasSerialSize[i])); 2622 2623 bottomLevelAccelerationStructures[i]->setDeferredOperation(htSerialize, workerThreadsCount); 2624 bottomLevelAccelerationStructures[i]->serialize(vkd, device, *cmdBuffer, storage.get()); 2625 bottomSerialized.push_back(storage); 2626 2627 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2628 { 2629 endCommandBuffer(vkd, *cmdBuffer); 2630 2631 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 2632 2633 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); 2634 beginCommandBuffer(vkd, *cmdBuffer, 0u); 2635 } 2636 2637 de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure(); 2638 asCopy->setBuildType(m_data.buildType); 2639 asCopy->setBuildFlags(m_data.buildFlags); 2640 asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP); 2641 asCopy->setCreateGeneric(m_data.bottomGeneric); 2642 asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation); 2643 asCopy->setBuildWithoutGeometries(buildWithoutGeom); 2644 asCopy->setBuildWithoutPrimitives(bottomNoPrimitives); 2645 asCopy->setDeferredOperation(htSerialize, workerThreadsCount); 2646 asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u); 2647 bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release())); 2648 } 2649 break; 2650 } 2651 default: 2652 DE_ASSERT(DE_FALSE); 2653 } 2654 bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies; 2655 } 2656 2657 // build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures ) 2658 bool topCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION; 2659 bool topSerial = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION; 2660 VkBuildAccelerationStructureFlagsKHR topCompactFlags = (topCompact ? allowCompactionFlag : emptyCompactionFlag); 2661 VkBuildAccelerationStructureFlagsKHR topBuildFlags = m_data.buildFlags | topCompactFlags; 2662 std::vector<VkAccelerationStructureKHR> topLevelStructureHandles; 2663 std::vector<VkDeviceSize> topBlasCompactSize; 2664 std::vector<VkDeviceSize> topBlasSerialSize; 2665 2666 topLevelAccelerationStructure = sceneBuilder->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr); 2667 topLevelAccelerationStructure->setBuildType (m_data.buildType); 2668 topLevelAccelerationStructure->setBuildFlags (topBuildFlags); 2669 topLevelAccelerationStructure->setBuildWithoutPrimitives (topNoPrimitives); 2670 topLevelAccelerationStructure->setUseArrayOfPointers (m_data.topUsesAOP); 2671 topLevelAccelerationStructure->setCreateGeneric (m_data.topGeneric); 2672 topLevelAccelerationStructure->setCreationBufferUnbounded (m_data.topUnboundedCreation); 2673 topLevelAccelerationStructure->setInactiveInstances (inactiveInstances); 2674 topLevelAccelerationStructure->createAndBuild (vkd, device, *cmdBuffer, allocator); 2675 topLevelStructureHandles.push_back (*(topLevelAccelerationStructure->getPtr())); 2676 2677 if (topCompact) 2678 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize); 2679 if (topSerial) 2680 queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize); 2681 2682 // if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU 2683 if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial)) 2684 { 2685 endCommandBuffer(vkd, *cmdBuffer); 2686 2687 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 2688 2689 if (topCompact) 2690 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(topBlasCompactSize.size()), sizeof(VkDeviceSize) * topBlasCompactSize.size(), topBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)); 2691 if (topSerial) 2692 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(topBlasSerialSize.size()), sizeof(VkDeviceSize) * topBlasSerialSize.size(), topBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)); 2693 2694 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); 2695 beginCommandBuffer(vkd, *cmdBuffer, 0u); 2696 } 2697 2698 const TopLevelAccelerationStructure* topLevelRayTracedPtr = topLevelAccelerationStructure.get(); 2699 if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION) 2700 { 2701 switch (m_data.operationType) 2702 { 2703 case OP_COPY: 2704 { 2705 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure(); 2706 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount); 2707 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType); 2708 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags); 2709 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives); 2710 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances); 2711 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP); 2712 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric); 2713 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation); 2714 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), 0u, 0u); 2715 break; 2716 } 2717 case OP_COMPACT: 2718 { 2719 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure(); 2720 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType); 2721 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags); 2722 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives); 2723 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances); 2724 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP); 2725 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric); 2726 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation); 2727 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], 0u); 2728 break; 2729 } 2730 case OP_SERIALIZE: 2731 { 2732 de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, topBlasSerialSize[0])); 2733 2734 topLevelAccelerationStructure->setDeferredOperation(htSerialize, workerThreadsCount); 2735 topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get()); 2736 topSerialized.push_back(storage); 2737 2738 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) 2739 { 2740 endCommandBuffer(vkd, *cmdBuffer); 2741 2742 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 2743 2744 vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); 2745 beginCommandBuffer(vkd, *cmdBuffer, 0u); 2746 } 2747 2748 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure(); 2749 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType); 2750 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags); 2751 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives); 2752 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances); 2753 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP); 2754 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric); 2755 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation); 2756 topLevelAccelerationStructureCopy->setDeferredOperation(htSerialize, workerThreadsCount); 2757 topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u); 2758 break; 2759 } 2760 case OP_UPDATE: 2761 { 2762 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure(); 2763 topLevelAccelerationStructureCopy->create(vkd, device, allocator, 0u, 0u); 2764 // Update AS based on topLevelAccelerationStructure 2765 topLevelAccelerationStructureCopy->build(vkd, device, *cmdBuffer, topLevelAccelerationStructure.get()); 2766 break; 2767 } 2768 case OP_UPDATE_IN_PLACE: 2769 { 2770 // Update in place 2771 topLevelAccelerationStructure->build(vkd, device, *cmdBuffer, topLevelAccelerationStructure.get()); 2772 // Make a coppy 2773 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure(); 2774 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount); 2775 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType); 2776 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags); 2777 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives); 2778 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances); 2779 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP); 2780 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric); 2781 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), 0u, 0u); 2782 break; 2783 } 2784 default: 2785 DE_ASSERT(DE_FALSE); 2786 2787 } 2788 topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get(); 2789 } 2790 2791 const VkMemoryBarrier preTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT); 2792 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &preTraceMemoryBarrier); 2793 2794 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = 2795 { 2796 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 2797 DE_NULL, // const void* pNext; 2798 1u, // deUint32 accelerationStructureCount; 2799 topLevelRayTracedPtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures; 2800 }; 2801 2802 testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet, resultImageInfo); 2803 2804 const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); 2805 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 2806 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier); 2807 2808 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion); 2809 2810 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier); 2811 } 2812 endCommandBuffer(vkd, *cmdBuffer); 2813 2814 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 2815 2816 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE); 2817 2818 return resultBuffer; 2819} 2820 2821bool RayQueryASBasicTestInstance::iterateNoWorkers (void) 2822{ 2823 de::SharedPtr<TestConfiguration> testConfiguration = createTestConfiguration(m_data.shaderSourcePipeline); 2824 de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder()); 2825 2826 const de::MovePtr<BufferWithMemory> buffer = runTest(testConfiguration.get(), sceneBuilder.get(), 0); 2827 2828 return testConfiguration->verifyImage(buffer.get(), m_context, m_data); 2829} 2830 2831bool RayQueryASBasicTestInstance::iterateWithWorkers (void) 2832{ 2833 de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder()); 2834 2835 de::SharedPtr<TestConfiguration> testConfigurationS = createTestConfiguration(m_data.shaderSourcePipeline); 2836 de::MovePtr<BufferWithMemory> singleThreadBufferCPU = runTest(testConfigurationS.get(), sceneBuilder.get(), 0); 2837 const bool singleThreadValidation = testConfigurationS->verifyImage(singleThreadBufferCPU.get(), m_context, m_data); 2838 testConfigurationS.clear(); 2839 2840 de::SharedPtr<TestConfiguration> testConfigurationM = createTestConfiguration(m_data.shaderSourcePipeline); 2841 de::MovePtr<BufferWithMemory> multiThreadBufferCPU = runTest(testConfigurationM.get(), sceneBuilder.get(), m_data.workerThreadsCount); 2842 const bool multiThreadValidation = testConfigurationM->verifyImage(multiThreadBufferCPU.get(), m_context, m_data); 2843 testConfigurationM.clear(); 2844 2845 const deUint32 result = singleThreadValidation && multiThreadValidation; 2846 2847 return result; 2848} 2849 2850tcu::TestStatus RayQueryASBasicTestInstance::iterate(void) 2851{ 2852 bool result; 2853 if (m_data.workerThreadsCount != 0) 2854 result = iterateWithWorkers(); 2855 else 2856 result = iterateNoWorkers(); 2857 2858 if (result) 2859 return tcu::TestStatus::pass("Pass"); 2860 else 2861 return tcu::TestStatus::fail("Fail"); 2862} 2863 2864// Tests dynamic indexing of acceleration structures 2865class RayQueryASDynamicIndexingTestCase : public TestCase 2866{ 2867public: 2868 RayQueryASDynamicIndexingTestCase (tcu::TestContext& context, const char* name); 2869 ~RayQueryASDynamicIndexingTestCase (void) = default; 2870 2871 void checkSupport (Context& context) const override; 2872 void initPrograms (SourceCollections& programCollection) const override; 2873 TestInstance* createInstance (Context& context) const override; 2874}; 2875 2876class RayQueryASDynamicIndexingTestInstance : public TestInstance 2877{ 2878public: 2879 RayQueryASDynamicIndexingTestInstance (Context& context); 2880 ~RayQueryASDynamicIndexingTestInstance (void) = default; 2881 tcu::TestStatus iterate (void) override; 2882}; 2883 2884RayQueryASDynamicIndexingTestCase::RayQueryASDynamicIndexingTestCase(tcu::TestContext& context, const char* name) 2885 : TestCase(context, name) 2886{ 2887} 2888 2889void RayQueryASDynamicIndexingTestCase::checkSupport(Context& context) const 2890{ 2891 commonASTestsCheckSupport(context); 2892 context.requireDeviceFunctionality("VK_EXT_descriptor_indexing"); 2893} 2894 2895void RayQueryASDynamicIndexingTestCase::initPrograms(SourceCollections& programCollection) const 2896{ 2897 const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true); 2898 2899 // compute shader is defined in spir-v as it requires possing pointer to TLAS that was read from ssbo; 2900 // original spir-v code was generated using following glsl code but resulting spir-v code was modiifed 2901 2902 // #version 460 core 2903 // #extension GL_EXT_ray_query : require 2904 // #extension GL_EXT_nonuniform_qualifier : enable 2905 2906 // #define ARRAY_SIZE 500 2907 // layout(set = 0, binding = 0) uniform accelerationStructureEXT tlasArray[ARRAY_SIZE]; 2908 // layout(set = 0, binding = 1) readonly buffer topLevelASPointers { 2909 // uvec2 ptr[]; 2910 // } tlasPointers; 2911 // layout(set = 0, binding = 2) readonly buffer topLevelASIndices { 2912 // uint idx[]; 2913 // } tlasIndices; 2914 // layout(set = 0, binding = 3, std430) writeonly buffer Result { 2915 // uint value[]; 2916 // } result; 2917 2918 // void main() 2919 // { 2920 // float tmin = 0.0; 2921 // float tmax = 2.0; 2922 // vec3 origin = vec3(0.25f, 0.5f, 1.0); 2923 // vec3 direction = vec3(0.0,0.0,-1.0); 2924 // uint tlasIndex = tlasIndices.idx[nonuniformEXT(gl_GlobalInvocationID.x)]; 2925 2926 // rayQueryEXT rq; 2927 // rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax); 2928 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x)], 2); 2929 2930 // if (rayQueryProceedEXT(rq)) 2931 // { 2932 // if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT) 2933 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x)], 3); 2934 // } 2935 2936 // //rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax); 2937 // rayQueryInitializeEXT(rq, *tlasPointers.ptr[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax); 2938 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 2)], 5); 2939 2940 // if (rayQueryProceedEXT(rq)) 2941 // { 2942 // if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT) 2943 // atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 3)], 7); 2944 // } 2945 // } 2946 2947 const std::string compSource = 2948 "OpCapability Shader\n" 2949 "OpCapability RayQueryKHR\n" 2950 "OpCapability ShaderNonUniform\n" 2951 "OpExtension \"SPV_EXT_descriptor_indexing\"\n" 2952 "OpExtension \"SPV_KHR_ray_query\"\n" 2953 "%1 = OpExtInstImport \"GLSL.std.450\"\n" 2954 "OpMemoryModel Logical GLSL450\n" 2955 "OpEntryPoint GLCompute %4 \"main\" %var_index_ssbo %33 %var_as_arr_uni_ptr %64 %83 %var_as_pointers_ssbo\n" 2956 "OpExecutionMode %4 LocalSize 1 1 1\n" 2957 "OpDecorate %25 ArrayStride 4\n" 2958 "OpMemberDecorate %26 0 NonWritable\n" 2959 "OpMemberDecorate %26 0 Offset 0\n" 2960 "OpDecorate %26 Block\n" 2961 "OpDecorate %var_index_ssbo DescriptorSet 0\n" 2962 "OpDecorate %var_index_ssbo Binding 2\n" 2963 "OpDecorate %33 BuiltIn GlobalInvocationId\n" 2964 "OpDecorate %38 NonUniform\n" 2965 "OpDecorate %40 NonUniform\n" 2966 "OpDecorate %41 NonUniform\n" 2967 "OpDecorate %var_as_arr_uni_ptr DescriptorSet 0\n" 2968 "OpDecorate %var_as_arr_uni_ptr Binding 0\n" 2969 "OpDecorate %51 NonUniform\n" 2970 "OpDecorate %53 NonUniform\n" 2971 "OpDecorate %54 NonUniform\n" 2972 "OpDecorate %61 ArrayStride 4\n" 2973 "OpMemberDecorate %62 0 NonReadable\n" 2974 "OpMemberDecorate %62 0 Offset 0\n" 2975 "OpDecorate %62 Block\n" 2976 "OpDecorate %64 DescriptorSet 0\n" 2977 "OpDecorate %64 Binding 3\n" 2978 "OpDecorate %67 NonUniform\n" 2979 "OpDecorate %83 BuiltIn NumWorkgroups\n" 2980 "OpDecorate %87 NonUniform\n" 2981 "OpDecorate %as_index NonUniform\n" 2982 "OpDecorate %as_device_addres NonUniform\n" 2983 "OpDecorate %105 NonUniform\n" 2984 "OpDecorate %122 NonUniform\n" 2985 "OpDecorate %127 ArrayStride 8\n" 2986 "OpMemberDecorate %128 0 NonWritable\n" 2987 "OpMemberDecorate %128 0 Offset 0\n" 2988 "OpDecorate %128 Block\n" 2989 "OpDecorate %var_as_pointers_ssbo DescriptorSet 0\n" 2990 "OpDecorate %var_as_pointers_ssbo Binding 1\n" 2991 "%2 = OpTypeVoid\n" 2992 "%3 = OpTypeFunction %2\n" 2993 "%6 = OpTypeFloat 32\n" 2994 "%7 = OpTypePointer Function %6\n" 2995 "%9 = OpConstant %6 0\n" 2996 "%11 = OpConstant %6 2\n" 2997 "%12 = OpTypeVector %6 3\n" 2998 "%13 = OpTypePointer Function %12\n" 2999 "%15 = OpConstant %6 0.25\n" 3000 "%16 = OpConstant %6 0.5\n" 3001 "%17 = OpConstant %6 1\n" 3002 "%18 = OpConstantComposite %12 %15 %16 %17\n" 3003 "%20 = OpConstant %6 -1\n" 3004 "%21 = OpConstantComposite %12 %9 %9 %20\n" 3005 "%type_uint32 = OpTypeInt 32 0\n" 3006 "%23 = OpTypePointer Function %type_uint32\n" 3007 "%25 = OpTypeRuntimeArray %type_uint32\n" 3008 "%26 = OpTypeStruct %25\n" 3009 "%27 = OpTypePointer StorageBuffer %26\n" 3010 "%var_index_ssbo = OpVariable %27 StorageBuffer\n" 3011 "%29 = OpTypeInt 32 1\n" 3012 "%c_int32_0 = OpConstant %29 0\n" 3013 "%31 = OpTypeVector %type_uint32 3\n" 3014 "%32 = OpTypePointer Input %31\n" 3015 "%33 = OpVariable %32 Input\n" 3016 "%34 = OpConstant %type_uint32 0\n" 3017 "%35 = OpTypePointer Input %type_uint32\n" 3018 "%type_uint32_ssbo_ptr = OpTypePointer StorageBuffer %type_uint32\n" 3019 "%42 = OpTypeRayQueryKHR\n" 3020 "%43 = OpTypePointer Function %42\n" 3021 "%type_as = OpTypeAccelerationStructureKHR\n" 3022 "%46 = OpConstant %type_uint32 500\n" 3023 "%type_as_arr = OpTypeArray %type_as %46\n" 3024 "%type_as_arr_uni_ptr = OpTypePointer UniformConstant %type_as_arr\n" 3025 "%var_as_arr_uni_ptr = OpVariable %type_as_arr_uni_ptr UniformConstant\n" 3026 "%type_as_uni_ptr = OpTypePointer UniformConstant %type_as\n" 3027 "%55 = OpConstant %type_uint32 16\n" 3028 "%56 = OpConstant %type_uint32 255\n" 3029 "%61 = OpTypeRuntimeArray %type_uint32\n" 3030 "%62 = OpTypeStruct %61\n" 3031 "%63 = OpTypePointer StorageBuffer %62\n" 3032 "%64 = OpVariable %63 StorageBuffer\n" 3033 "%69 = OpConstant %type_uint32 2\n" 3034 "%70 = OpConstant %type_uint32 1\n" 3035 "%72 = OpTypeBool\n" 3036 "%76 = OpConstantFalse %72\n" 3037 "%83 = OpVariable %32 Input\n" 3038 "%89 = OpConstant %type_uint32 3\n" 3039 "%107 = OpConstant %type_uint32 5\n" 3040 "%124 = OpConstant %type_uint32 7\n" 3041 3042 // <changed_section> 3043 "%v2uint = OpTypeVector %type_uint32 2\n" 3044 "%127 = OpTypeRuntimeArray %v2uint\n" 3045 "%128 = OpTypeStruct %127\n" 3046 "%129 = OpTypePointer StorageBuffer %128\n" 3047 "%var_as_pointers_ssbo = OpVariable %129 StorageBuffer\n" 3048 "%type_uint64_ssbo_ptr = OpTypePointer StorageBuffer %v2uint\n" 3049 // </changed_section> 3050 3051 // void main() 3052 "%4 = OpFunction %2 None %3\n" 3053 "%5 = OpLabel\n" 3054 "%8 = OpVariable %7 Function\n" 3055 "%10 = OpVariable %7 Function\n" 3056 "%14 = OpVariable %13 Function\n" 3057 "%19 = OpVariable %13 Function\n" 3058 "%24 = OpVariable %23 Function\n" 3059 "%var_ray_query = OpVariable %43 Function\n" 3060 "OpStore %8 %9\n" 3061 "OpStore %10 %11\n" 3062 "OpStore %14 %18\n" 3063 "OpStore %19 %21\n" 3064 "%36 = OpAccessChain %35 %33 %34\n" 3065 "%37 = OpLoad %type_uint32 %36\n" 3066 "%38 = OpCopyObject %type_uint32 %37\n" 3067 "%40 = OpAccessChain %type_uint32_ssbo_ptr %var_index_ssbo %c_int32_0 %38\n" 3068 "%41 = OpLoad %type_uint32 %40\n" 3069 "OpStore %24 %41\n" 3070 3071 // rayQueryInitializeEXT using AS that was read from array 3072 "%50 = OpLoad %type_uint32 %24\n" 3073 "%51 = OpCopyObject %type_uint32 %50\n" 3074 "%53 = OpAccessChain %type_as_uni_ptr %var_as_arr_uni_ptr %51\n" 3075 "%54 = OpLoad %type_as %53\n" 3076 "%57 = OpLoad %12 %14\n" 3077 "%58 = OpLoad %6 %8\n" 3078 "%59 = OpLoad %12 %19\n" 3079 "%60 = OpLoad %6 %10\n" 3080 "OpRayQueryInitializeKHR %var_ray_query %54 %55 %56 %57 %58 %59 %60\n" 3081 3082 "%65 = OpAccessChain %35 %33 %34\n" 3083 "%66 = OpLoad %type_uint32 %65\n" 3084 "%67 = OpCopyObject %type_uint32 %66\n" 3085 "%68 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %67\n" 3086 "%71 = OpAtomicIAdd %type_uint32 %68 %70 %34 %69\n" 3087 3088 "%73 = OpRayQueryProceedKHR %72 %var_ray_query\n" 3089 "OpSelectionMerge %75 None\n" 3090 "OpBranchConditional %73 %74 %75\n" 3091 "%74 = OpLabel\n" 3092 3093 "%77 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n" 3094 "%78 = OpIEqual %72 %77 %34\n" 3095 "OpSelectionMerge %80 None\n" 3096 "OpBranchConditional %78 %79 %80\n" 3097 "%79 = OpLabel\n" 3098 "%81 = OpAccessChain %35 %33 %34\n" 3099 "%82 = OpLoad %type_uint32 %81\n" 3100 "%84 = OpAccessChain %35 %83 %34\n" 3101 "%85 = OpLoad %type_uint32 %84\n" 3102 "%86 = OpIAdd %type_uint32 %82 %85\n" 3103 "%87 = OpCopyObject %type_uint32 %86\n" 3104 "%88 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %87\n" 3105 "%90 = OpAtomicIAdd %type_uint32 %88 %70 %34 %89\n" 3106 "OpBranch %80\n" 3107 "%80 = OpLabel\n" 3108 "OpBranch %75\n" 3109 "%75 = OpLabel\n" 3110 3111 // rayQueryInitializeEXT using pointer to AS 3112 "%91 = OpLoad %type_uint32 %24\n" 3113 "%as_index = OpCopyObject %type_uint32 %91\n" 3114 3115 // <changed_section> 3116 "%as_device_addres_ptr = OpAccessChain %type_uint64_ssbo_ptr %var_as_pointers_ssbo %c_int32_0 %as_index\n" 3117 "%as_device_addres = OpLoad %v2uint %as_device_addres_ptr\n" 3118 "%as_to_use = OpConvertUToAccelerationStructureKHR %type_as %as_device_addres\n" 3119 // </changed_section> 3120 3121 "%95 = OpLoad %12 %14\n" 3122 "%96 = OpLoad %6 %8\n" 3123 "%97 = OpLoad %12 %19\n" 3124 "%98 = OpLoad %6 %10\n" 3125 "OpRayQueryInitializeKHR %var_ray_query %as_to_use %55 %56 %95 %96 %97 %98\n" 3126 3127 "%99 = OpAccessChain %35 %33 %34\n" 3128 "%100 = OpLoad %type_uint32 %99\n" 3129 "%101 = OpAccessChain %35 %83 %34\n" 3130 "%102 = OpLoad %type_uint32 %101\n" 3131 "%103 = OpIMul %type_uint32 %102 %69\n" 3132 "%104 = OpIAdd %type_uint32 %100 %103\n" 3133 "%105 = OpCopyObject %type_uint32 %104\n" 3134 "%106 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %105\n" 3135 "%108 = OpAtomicIAdd %type_uint32 %106 %70 %34 %107\n" 3136 3137 "%109 = OpRayQueryProceedKHR %72 %var_ray_query\n" 3138 "OpSelectionMerge %111 None\n" 3139 "OpBranchConditional %109 %110 %111\n" 3140 "%110 = OpLabel\n" 3141 3142 "%112 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n" 3143 "%113 = OpIEqual %72 %112 %34\n" 3144 "OpSelectionMerge %115 None\n" 3145 "OpBranchConditional %113 %114 %115\n" 3146 "%114 = OpLabel\n" 3147 "%116 = OpAccessChain %35 %33 %34\n" 3148 "%117 = OpLoad %type_uint32 %116\n" 3149 "%118 = OpAccessChain %35 %83 %34\n" 3150 "%119 = OpLoad %type_uint32 %118\n" 3151 "%120 = OpIMul %type_uint32 %119 %89\n" 3152 "%121 = OpIAdd %type_uint32 %117 %120\n" 3153 "%122 = OpCopyObject %type_uint32 %121\n" 3154 "%123 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %122\n" 3155 "%125 = OpAtomicIAdd %type_uint32 %123 %70 %34 %124\n" 3156 "OpBranch %115\n" 3157 "%115 = OpLabel\n" 3158 "OpBranch %111\n" 3159 "%111 = OpLabel\n" 3160 "OpReturn\n" 3161 "OpFunctionEnd\n"; 3162 3163 programCollection.spirvAsmSources.add("comp") << compSource << spvBuildOptions; 3164} 3165 3166TestInstance* RayQueryASDynamicIndexingTestCase::createInstance(Context& context) const 3167{ 3168 return new RayQueryASDynamicIndexingTestInstance(context); 3169} 3170 3171 3172RayQueryASDynamicIndexingTestInstance::RayQueryASDynamicIndexingTestInstance(Context& context) 3173 : vkt::TestInstance(context) 3174{ 3175} 3176 3177tcu::TestStatus RayQueryASDynamicIndexingTestInstance::iterate(void) 3178{ 3179 const DeviceInterface& vkd = m_context.getDeviceInterface(); 3180 const VkDevice device = m_context.getDevice(); 3181 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 3182 const VkQueue queue = m_context.getUniversalQueue(); 3183 Allocator& allocator = m_context.getDefaultAllocator(); 3184 const deUint32 tlasCount = 500; // changing this will require also changing shaders 3185 const deUint32 activeTlasCount = 32; // number of tlas out of <tlasCount> that will be active 3186 3187 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder() 3188 .addArrayBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, VK_SHADER_STAGE_COMPUTE_BIT) 3189 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // pointers to all acceleration structures 3190 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with indices of all acceleration structures 3191 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with result values 3192 .build(vkd, device); 3193 3194 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder() 3195 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount) 3196 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 3197 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 3198 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 3199 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 3200 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout); 3201 3202 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); 3203 Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u); 3204 const VkComputePipelineCreateInfo pipelineCreateInfo 3205 { 3206 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType 3207 DE_NULL, // const void* pNext 3208 0u, // VkPipelineCreateFlags flags 3209 { // VkPipelineShaderStageCreateInfo stage 3210 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 3211 DE_NULL, 3212 (VkPipelineShaderStageCreateFlags)0, 3213 VK_SHADER_STAGE_COMPUTE_BIT, 3214 *shaderModule, 3215 "main", 3216 DE_NULL 3217 }, 3218 *pipelineLayout, // VkPipelineLayout layout 3219 DE_NULL, // VkPipeline basePipelineHandle 3220 0, // deInt32 basePipelineIndex 3221 }; 3222 3223 Move<VkPipeline> pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo); 3224 3225 const VkDeviceSize pointerBufferSize = tlasCount * sizeof(VkDeviceAddress); 3226 const VkBufferCreateInfo pointerBufferCreateInfo = makeBufferCreateInfo(pointerBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 3227 de::MovePtr<BufferWithMemory> pointerBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, pointerBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress)); 3228 3229 const VkDeviceSize indicesBufferSize = activeTlasCount * sizeof(deUint32); 3230 const VkBufferCreateInfo indicesBufferCreateInfo = makeBufferCreateInfo(indicesBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 3231 de::MovePtr<BufferWithMemory> indicesBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, indicesBufferCreateInfo, MemoryRequirement::HostVisible)); 3232 3233 const VkDeviceSize resultBufferSize = activeTlasCount * sizeof(deUint32) * 4; 3234 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(resultBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); 3235 de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible)); 3236 3237 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex); 3238 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 3239 3240 de::SharedPtr<BottomLevelAccelerationStructure> blas = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release()); 3241 std::vector<de::MovePtr<TopLevelAccelerationStructure>> tlasVect(tlasCount); 3242 std::vector<VkDeviceAddress> tlasPtrVect(tlasCount); 3243 std::vector<VkAccelerationStructureKHR> tlasVkVect; 3244 3245 // randomly scatter AS indices across the range (number of them should be equal to the max subgroup size) 3246 deRandom rnd; 3247 deRandom_init(&rnd, 123); 3248 std::set<deUint32> asIndicesSet; 3249 while (asIndicesSet.size() < activeTlasCount) 3250 asIndicesSet.insert(deRandom_getUint32(&rnd) % tlasCount); 3251 3252 // fill indices buffer 3253 deUint32 helperIndex = 0; 3254 auto& indicesBufferAlloc = indicesBuffer->getAllocation(); 3255 deUint32* indicesBufferPtr = reinterpret_cast<deUint32*>(indicesBufferAlloc.getHostPtr()); 3256 std::for_each(asIndicesSet.begin(), asIndicesSet.end(), 3257 [&helperIndex, indicesBufferPtr](const deUint32& index) 3258 { 3259 indicesBufferPtr[helperIndex++] = index; 3260 }); 3261 vk::flushAlloc(vkd, device, indicesBufferAlloc); 3262 3263 // clear result buffer 3264 auto& resultBufferAlloc = resultBuffer->getAllocation(); 3265 void* resultBufferPtr = resultBufferAlloc.getHostPtr(); 3266 deMemset(resultBufferPtr, 0, static_cast<size_t>(resultBufferSize)); 3267 vk::flushAlloc(vkd, device, resultBufferAlloc); 3268 3269 beginCommandBuffer(vkd, *cmdBuffer, 0u); 3270 { 3271 // build bottom level acceleration structure 3272 blas->setGeometryData( 3273 { 3274 { 0.0, 0.0, 0.0 }, 3275 { 1.0, 0.0, 0.0 }, 3276 { 0.0, 1.0, 0.0 }, 3277 }, 3278 true, 3279 0u 3280 ); 3281 3282 blas->createAndBuild(vkd, device, *cmdBuffer, allocator); 3283 3284 // build top level acceleration structures 3285 for (deUint32 tlasIndex = 0; tlasIndex < tlasCount; ++tlasIndex) 3286 { 3287 auto& tlas = tlasVect[tlasIndex]; 3288 tlas = makeTopLevelAccelerationStructure(); 3289 tlas->setInstanceCount(1); 3290 tlas->addInstance(blas); 3291 if (!asIndicesSet.count(tlasIndex)) 3292 { 3293 // tlas that are not in asIndicesSet should be empty but it is hard to do 3294 // that with current cts utils so we are marking them as inactive instead 3295 tlas->setInactiveInstances(true); 3296 } 3297 tlas->createAndBuild(vkd, device, *cmdBuffer, allocator); 3298 3299 // get acceleration structure device address 3300 const VkAccelerationStructureDeviceAddressInfoKHR addressInfo = 3301 { 3302 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType sType 3303 DE_NULL, // const void* pNext 3304 *tlas->getPtr() // VkAccelerationStructureKHR accelerationStructure 3305 }; 3306 VkDeviceAddress vkda = vkd.getAccelerationStructureDeviceAddressKHR(device, &addressInfo); 3307 tlasPtrVect[tlasIndex] = vkda; 3308 } 3309 3310 // fill pointer buffer 3311 vkd.cmdUpdateBuffer(*cmdBuffer, **pointerBuffer, 0, pointerBufferSize, tlasPtrVect.data()); 3312 3313 // wait for data transfers 3314 const VkMemoryBarrier uploadBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT); 3315 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &uploadBarrier, 1u); 3316 3317 // wait for as build 3318 const VkMemoryBarrier asBuildBarrier = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR); 3319 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &asBuildBarrier, 1u); 3320 3321 tlasVkVect.reserve(tlasCount); 3322 for (auto& tlas : tlasVect) 3323 tlasVkVect.push_back(*tlas->getPtr()); 3324 3325 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = 3326 { 3327 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; 3328 DE_NULL, // const void* pNext; 3329 tlasCount, // deUint32 accelerationStructureCount; 3330 tlasVkVect.data(), // const VkAccelerationStructureKHR* pAccelerationStructures; 3331 }; 3332 3333 const vk::VkDescriptorBufferInfo pointerBufferInfo = makeDescriptorBufferInfo(**pointerBuffer, 0u, VK_WHOLE_SIZE); 3334 const vk::VkDescriptorBufferInfo indicesBufferInfo = makeDescriptorBufferInfo(**indicesBuffer, 0u, VK_WHOLE_SIZE); 3335 const vk::VkDescriptorBufferInfo resultInfo = makeDescriptorBufferInfo(**resultBuffer, 0u, VK_WHOLE_SIZE); 3336 3337 DescriptorSetUpdateBuilder() 3338 .writeArray (*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, &accelerationStructureWriteDescriptorSet) 3339 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &pointerBufferInfo) 3340 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indicesBufferInfo) 3341 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo) 3342 .update(vkd, device); 3343 3344 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL); 3345 3346 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); 3347 3348 vkd.cmdDispatch(*cmdBuffer, activeTlasCount, 1, 1); 3349 3350 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); 3351 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier); 3352 } 3353 endCommandBuffer(vkd, *cmdBuffer); 3354 3355 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); 3356 3357 invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), resultBufferSize); 3358 3359 // verify result buffer 3360 deUint32 failures = 0; 3361 const deUint32* resultPtr = reinterpret_cast<deUint32*>(resultBuffer->getAllocation().getHostPtr()); 3362 for (deUint32 index = 0; index < activeTlasCount; ++index) 3363 { 3364 failures += (resultPtr[0 * activeTlasCount + index] != 2) + 3365 (resultPtr[1 * activeTlasCount + index] != 3) + 3366 (resultPtr[2 * activeTlasCount + index] != 5) + 3367 (resultPtr[3 * activeTlasCount + index] != 7); 3368 } 3369 3370 if (failures) 3371 return tcu::TestStatus::fail(de::toString(failures) + " failures, " + de::toString(4 * activeTlasCount - failures) + " are ok"); 3372 return tcu::TestStatus::pass("Pass"); 3373} 3374 3375} // anonymous 3376 3377/********************/ 3378 3379void addBasicBuildingTests(tcu::TestCaseGroup* group) 3380{ 3381 struct ShaderSourceTypeData 3382 { 3383 ShaderSourceType shaderSourceType; 3384 ShaderSourcePipeline shaderSourcePipeline; 3385 const char* name; 3386 } shaderSourceTypes[] = 3387 { 3388 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", }, 3389 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", }, 3390 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", }, 3391 }; 3392 3393 struct 3394 { 3395 vk::VkAccelerationStructureBuildTypeKHR buildType; 3396 const char* name; 3397 } buildTypes[] = 3398 { 3399 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 3400 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 3401 }; 3402 3403 struct 3404 { 3405 BottomTestType testType; 3406 bool usesAOP; 3407 const char* name; 3408 } bottomTestTypes[] = 3409 { 3410 { BottomTestType::TRIANGLES, false, "triangles" }, 3411 { BottomTestType::TRIANGLES, true, "triangles_aop" }, 3412 { BottomTestType::AABBS, false, "aabbs" }, 3413 { BottomTestType::AABBS, true, "aabbs_aop" }, 3414 }; 3415 3416 struct 3417 { 3418 TopTestType testType; 3419 bool usesAOP; 3420 const char* name; 3421 } topTestTypes[] = 3422 { 3423 { TopTestType::IDENTICAL_INSTANCES, false, "identical_instances" }, 3424 { TopTestType::IDENTICAL_INSTANCES, true, "identical_instances_aop" }, 3425 { TopTestType::DIFFERENT_INSTANCES, false, "different_instances" }, 3426 { TopTestType::DIFFERENT_INSTANCES, true, "different_instances_aop" }, 3427 }; 3428 3429 struct BuildFlagsData 3430 { 3431 VkBuildAccelerationStructureFlagsKHR flags; 3432 const char* name; 3433 }; 3434 3435 BuildFlagsData optimizationTypes[] = 3436 { 3437 { VkBuildAccelerationStructureFlagsKHR(0u), "0" }, 3438 { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, "fasttrace" }, 3439 { VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, "fastbuild" }, 3440 }; 3441 3442 BuildFlagsData updateTypes[] = 3443 { 3444 { VkBuildAccelerationStructureFlagsKHR(0u), "0" }, 3445 { VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, "update" }, 3446 }; 3447 3448 BuildFlagsData compactionTypes[] = 3449 { 3450 { VkBuildAccelerationStructureFlagsKHR(0u), "0" }, 3451 { VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, "compaction" }, 3452 }; 3453 3454 BuildFlagsData lowMemoryTypes[] = 3455 { 3456 { VkBuildAccelerationStructureFlagsKHR(0u), "0" }, 3457 { VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, "lowmemory" }, 3458 }; 3459 3460 struct 3461 { 3462 bool padVertices; 3463 const char* name; 3464 } paddingType[] = 3465 { 3466 { false, "nopadding" }, 3467 { true, "padded" }, 3468 }; 3469 3470 struct 3471 { 3472 bool topGeneric; 3473 bool bottomGeneric; 3474 const char* suffix; 3475 } createGenericParams[] = 3476 { 3477 { false, false, "" }, 3478 { false, true, "_bottomgeneric" }, 3479 { true, false, "_topgeneric" }, 3480 { true, true, "_bothgeneric" }, 3481 }; 3482 3483 // In order not to create thousands of new test variants for unbound buffer memory on acceleration structure creation, we will 3484 // set these options on some of the tests. 3485 de::ModCounter32 unboundedCreationBottomCounter (3u); 3486 de::ModCounter32 unboundedCreationTopCounter (7u); 3487 3488 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx) 3489 { 3490 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name)); 3491 3492 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx) 3493 { 3494 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name)); 3495 3496 for (size_t bottomNdx = 0; bottomNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++bottomNdx) 3497 { 3498 de::MovePtr<tcu::TestCaseGroup> bottomGroup(new tcu::TestCaseGroup(group->getTestContext(), bottomTestTypes[bottomNdx].name)); 3499 3500 for (size_t topNdx = 0; topNdx < DE_LENGTH_OF_ARRAY(topTestTypes); ++topNdx) 3501 { 3502 de::MovePtr<tcu::TestCaseGroup> topGroup(new tcu::TestCaseGroup(group->getTestContext(), topTestTypes[topNdx].name)); 3503 3504 for (int paddingTypeIdx = 0; paddingTypeIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingTypeIdx) 3505 { 3506 de::MovePtr<tcu::TestCaseGroup> paddingTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingTypeIdx].name)); 3507 3508 for (size_t optimizationNdx = 0; optimizationNdx < DE_LENGTH_OF_ARRAY(optimizationTypes); ++optimizationNdx) 3509 { 3510 for (size_t updateNdx = 0; updateNdx < DE_LENGTH_OF_ARRAY(updateTypes); ++updateNdx) 3511 { 3512 for (size_t compactionNdx = 0; compactionNdx < DE_LENGTH_OF_ARRAY(compactionTypes); ++compactionNdx) 3513 { 3514 for (size_t lowMemoryNdx = 0; lowMemoryNdx < DE_LENGTH_OF_ARRAY(lowMemoryTypes); ++lowMemoryNdx) 3515 { 3516 for (int createGenericIdx = 0; createGenericIdx < DE_LENGTH_OF_ARRAY(createGenericParams); ++createGenericIdx) 3517 { 3518 std::string testName = 3519 std::string(optimizationTypes[optimizationNdx].name) + "_" + 3520 std::string(updateTypes[updateNdx].name) + "_" + 3521 std::string(compactionTypes[compactionNdx].name) + "_" + 3522 std::string(lowMemoryTypes[lowMemoryNdx].name) + 3523 std::string(createGenericParams[createGenericIdx].suffix); 3524 3525 const bool unboundedCreationBottom = (static_cast<uint32_t>(unboundedCreationBottomCounter++) == 0u); 3526 const bool unboundedCreationTop = (static_cast<uint32_t>(unboundedCreationTopCounter++) == 0u); 3527 3528 TestParams testParams 3529 { 3530 shaderSourceTypes[shaderSourceNdx].shaderSourceType, 3531 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline, 3532 buildTypes[buildTypeNdx].buildType, 3533 VK_FORMAT_R32G32B32_SFLOAT, 3534 paddingType[paddingTypeIdx].padVertices, 3535 VK_INDEX_TYPE_NONE_KHR, 3536 bottomTestTypes[bottomNdx].testType, 3537 InstanceCullFlags::NONE, 3538 bottomTestTypes[bottomNdx].usesAOP, 3539 createGenericParams[createGenericIdx].bottomGeneric, 3540 unboundedCreationBottom, 3541 topTestTypes[topNdx].testType, 3542 topTestTypes[topNdx].usesAOP, 3543 createGenericParams[createGenericIdx].topGeneric, 3544 unboundedCreationTop, 3545 optimizationTypes[optimizationNdx].flags | updateTypes[updateNdx].flags | compactionTypes[compactionNdx].flags | lowMemoryTypes[lowMemoryNdx].flags, 3546 OT_NONE, 3547 OP_NONE, 3548 TEST_WIDTH, 3549 TEST_HEIGHT, 3550 0u, 3551 EmptyAccelerationStructureCase::NOT_EMPTY, 3552 }; 3553 paddingTypeGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), testName.c_str(), testParams)); 3554 } 3555 } 3556 } 3557 } 3558 } 3559 topGroup->addChild(paddingTypeGroup.release()); 3560 } 3561 bottomGroup->addChild(topGroup.release()); 3562 } 3563 buildGroup->addChild(bottomGroup.release()); 3564 } 3565 sourceTypeGroup->addChild(buildGroup.release()); 3566 } 3567 group->addChild(sourceTypeGroup.release()); 3568 } 3569} 3570 3571void addVertexIndexFormatsTests(tcu::TestCaseGroup* group) 3572{ 3573 struct ShaderSourceTypeData 3574 { 3575 ShaderSourceType shaderSourceType; 3576 ShaderSourcePipeline shaderSourcePipeline; 3577 const char* name; 3578 } shaderSourceTypes[] = 3579 { 3580 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" }, 3581 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" }, 3582 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" }, 3583 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", }, 3584 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", }, 3585 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", }, 3586 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", }, 3587 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", }, 3588 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", }, 3589 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", }, 3590 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", }, 3591 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", }, 3592 }; 3593 3594 struct 3595 { 3596 vk::VkAccelerationStructureBuildTypeKHR buildType; 3597 const char* name; 3598 } buildTypes[] = 3599 { 3600 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 3601 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 3602 }; 3603 3604 const VkFormat vertexFormats[] = 3605 { 3606 // Mandatory formats. 3607 VK_FORMAT_R32G32_SFLOAT, 3608 VK_FORMAT_R32G32B32_SFLOAT, 3609 VK_FORMAT_R16G16_SFLOAT, 3610 VK_FORMAT_R16G16B16A16_SFLOAT, 3611 VK_FORMAT_R16G16_SNORM, 3612 VK_FORMAT_R16G16B16A16_SNORM, 3613 3614 // Additional formats. 3615 VK_FORMAT_R8G8_SNORM, 3616 VK_FORMAT_R8G8B8_SNORM, 3617 VK_FORMAT_R8G8B8A8_SNORM, 3618 VK_FORMAT_R16G16B16_SNORM, 3619 VK_FORMAT_R16G16B16_SFLOAT, 3620 VK_FORMAT_R32G32B32A32_SFLOAT, 3621 VK_FORMAT_R64G64_SFLOAT, 3622 VK_FORMAT_R64G64B64_SFLOAT, 3623 VK_FORMAT_R64G64B64A64_SFLOAT, 3624 }; 3625 3626 struct 3627 { 3628 VkIndexType indexType; 3629 const char* name; 3630 } indexFormats[] = 3631 { 3632 { VK_INDEX_TYPE_NONE_KHR , "index_none" }, 3633 { VK_INDEX_TYPE_UINT16 , "index_uint16" }, 3634 { VK_INDEX_TYPE_UINT32 , "index_uint32" }, 3635 }; 3636 3637 struct 3638 { 3639 bool padVertices; 3640 const char* name; 3641 } paddingType[] = 3642 { 3643 { false, "nopadding" }, 3644 { true, "padded" }, 3645 }; 3646 3647 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx) 3648 { 3649 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name)); 3650 3651 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx) 3652 { 3653 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name)); 3654 3655 for (size_t vertexFormatNdx = 0; vertexFormatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); ++vertexFormatNdx) 3656 { 3657 const auto format = vertexFormats[vertexFormatNdx]; 3658 const auto formatName = getFormatSimpleName(format); 3659 3660 de::MovePtr<tcu::TestCaseGroup> vertexFormatGroup(new tcu::TestCaseGroup(group->getTestContext(), formatName.c_str())); 3661 3662 for (int paddingIdx = 0; paddingIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingIdx) 3663 { 3664 de::MovePtr<tcu::TestCaseGroup> paddingGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingIdx].name)); 3665 3666 for (size_t indexFormatNdx = 0; indexFormatNdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatNdx) 3667 { 3668 TestParams testParams 3669 { 3670 shaderSourceTypes[shaderSourceNdx].shaderSourceType, 3671 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline, 3672 buildTypes[buildTypeNdx].buildType, 3673 format, 3674 paddingType[paddingIdx].padVertices, 3675 indexFormats[indexFormatNdx].indexType, 3676 BottomTestType::TRIANGLES, 3677 InstanceCullFlags::NONE, 3678 false, 3679 false, 3680 false, 3681 TopTestType::IDENTICAL_INSTANCES, 3682 false, 3683 false, 3684 false, 3685 VkBuildAccelerationStructureFlagsKHR(0u), 3686 OT_NONE, 3687 OP_NONE, 3688 TEST_WIDTH, 3689 TEST_HEIGHT, 3690 0u, 3691 EmptyAccelerationStructureCase::NOT_EMPTY, 3692 }; 3693 paddingGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), indexFormats[indexFormatNdx].name, testParams)); 3694 } 3695 vertexFormatGroup->addChild(paddingGroup.release()); 3696 } 3697 buildGroup->addChild(vertexFormatGroup.release()); 3698 } 3699 sourceTypeGroup->addChild(buildGroup.release()); 3700 } 3701 group->addChild(sourceTypeGroup.release()); 3702 } 3703} 3704 3705void addOperationTestsImpl (tcu::TestCaseGroup* group, const deUint32 workerThreads) 3706{ 3707 struct ShaderSourceTypeData 3708 { 3709 ShaderSourceType shaderSourceType; 3710 ShaderSourcePipeline shaderSourcePipeline; 3711 const char* name; 3712 } shaderSourceTypes[] = 3713 { 3714 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" }, 3715 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" }, 3716 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" }, 3717 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", }, 3718 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", }, 3719 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", }, 3720 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", }, 3721 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", }, 3722 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", }, 3723 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", }, 3724 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", }, 3725 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", }, 3726 }; 3727 3728 struct 3729 { 3730 OperationType operationType; 3731 const char* name; 3732 } operationTypes[] = 3733 { 3734 { OP_COPY, "copy" }, 3735 { OP_COMPACT, "compaction" }, 3736 { OP_SERIALIZE, "serialization" }, 3737 }; 3738 3739 struct 3740 { 3741 vk::VkAccelerationStructureBuildTypeKHR buildType; 3742 const char* name; 3743 } buildTypes[] = 3744 { 3745 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 3746 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 3747 }; 3748 3749 struct 3750 { 3751 OperationTarget operationTarget; 3752 const char* name; 3753 } operationTargets[] = 3754 { 3755 { OT_TOP_ACCELERATION, "top_acceleration_structure" }, 3756 { OT_BOTTOM_ACCELERATION, "bottom_acceleration_structure" }, 3757 }; 3758 3759 struct 3760 { 3761 BottomTestType testType; 3762 const char* name; 3763 } bottomTestTypes[] = 3764 { 3765 { BottomTestType::TRIANGLES, "triangles" }, 3766 { BottomTestType::AABBS, "aabbs" }, 3767 }; 3768 3769 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx) 3770 { 3771 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name)); 3772 3773 for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx) 3774 { 3775 if (workerThreads > 0) 3776 if (operationTypes[operationTypeNdx].operationType != OP_COPY && operationTypes[operationTypeNdx].operationType != OP_SERIALIZE) 3777 continue; 3778 3779 de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name)); 3780 3781 for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx) 3782 { 3783 if (workerThreads > 0 && buildTypes[buildTypeNdx].buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR) 3784 continue; 3785 3786 de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name)); 3787 3788 for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets); ++operationTargetNdx) 3789 { 3790 de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name)); 3791 3792 for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx) 3793 { 3794 TopTestType topTest = (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ? TopTestType::DIFFERENT_INSTANCES : TopTestType::IDENTICAL_INSTANCES; 3795 3796 TestParams testParams 3797 { 3798 shaderSourceTypes[shaderSourceNdx].shaderSourceType, 3799 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline, 3800 buildTypes[buildTypeNdx].buildType, 3801 VK_FORMAT_R32G32B32_SFLOAT, 3802 false, 3803 VK_INDEX_TYPE_NONE_KHR, 3804 bottomTestTypes[testTypeNdx].testType, 3805 InstanceCullFlags::NONE, 3806 false, 3807 false, 3808 false, 3809 topTest, 3810 false, 3811 false, 3812 false, 3813 VkBuildAccelerationStructureFlagsKHR(0u), 3814 operationTargets[operationTargetNdx].operationTarget, 3815 operationTypes[operationTypeNdx].operationType, 3816 TEST_WIDTH, 3817 TEST_HEIGHT, 3818 workerThreads, 3819 EmptyAccelerationStructureCase::NOT_EMPTY, 3820 }; 3821 operationTargetGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, testParams)); 3822 } 3823 buildGroup->addChild(operationTargetGroup.release()); 3824 } 3825 operationTypeGroup->addChild(buildGroup.release()); 3826 } 3827 sourceTypeGroup->addChild(operationTypeGroup.release()); 3828 } 3829 group->addChild(sourceTypeGroup.release()); 3830 } 3831} 3832 3833void addOperationTests (tcu::TestCaseGroup* group) 3834{ 3835 addOperationTestsImpl(group, 0); 3836} 3837 3838void addHostThreadingOperationTests (tcu::TestCaseGroup* group) 3839{ 3840 const deUint32 threads[] = { 1, 2, 3, 4, 8, std::numeric_limits<deUint32>::max() }; 3841 3842 for (size_t threadsNdx = 0; threadsNdx < DE_LENGTH_OF_ARRAY(threads); ++threadsNdx) 3843 { 3844 const std::string groupName = threads[threadsNdx] != std::numeric_limits<deUint32>::max() 3845 ? de::toString(threads[threadsNdx]) 3846 : "max"; 3847 3848 de::MovePtr<tcu::TestCaseGroup> threadGroup(new tcu::TestCaseGroup(group->getTestContext(), groupName.c_str())); 3849 3850 addOperationTestsImpl(threadGroup.get(), threads[threadsNdx]); 3851 3852 group->addChild(threadGroup.release()); 3853 } 3854} 3855 3856void addFuncArgTests (tcu::TestCaseGroup* group) 3857{ 3858 const struct 3859 { 3860 vk::VkAccelerationStructureBuildTypeKHR buildType; 3861 const char* name; 3862 } buildTypes[] = 3863 { 3864 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 3865 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 3866 }; 3867 3868 auto& ctx = group->getTestContext(); 3869 3870 for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx) 3871 { 3872 TestParams testParams 3873 { 3874 SST_COMPUTE_SHADER, 3875 SSP_COMPUTE_PIPELINE, 3876 buildTypes[buildTypeNdx].buildType, 3877 VK_FORMAT_R32G32B32_SFLOAT, 3878 false, 3879 VK_INDEX_TYPE_NONE_KHR, 3880 BottomTestType::TRIANGLES, 3881 InstanceCullFlags::NONE, 3882 false, 3883 false, 3884 false, 3885 TopTestType::IDENTICAL_INSTANCES, 3886 false, 3887 false, 3888 false, 3889 VkBuildAccelerationStructureFlagsKHR(0u), 3890 OT_NONE, 3891 OP_NONE, 3892 TEST_WIDTH, 3893 TEST_HEIGHT, 3894 0u, 3895 EmptyAccelerationStructureCase::NOT_EMPTY, 3896 }; 3897 3898 group->addChild(new RayQueryASFuncArgTestCase(ctx, buildTypes[buildTypeNdx].name, testParams)); 3899 } 3900} 3901 3902void addInstanceTriangleCullingTests (tcu::TestCaseGroup* group) 3903{ 3904 const struct 3905 { 3906 ShaderSourceType shaderSourceType; 3907 ShaderSourcePipeline shaderSourcePipeline; 3908 std::string name; 3909 } shaderSourceTypes[] = 3910 { 3911 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" }, 3912 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" }, 3913 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" }, 3914 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", }, 3915 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", }, 3916 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", }, 3917 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", }, 3918 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", }, 3919 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", }, 3920 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", }, 3921 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", }, 3922 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", }, 3923 }; 3924 3925 const struct 3926 { 3927 InstanceCullFlags cullFlags; 3928 std::string name; 3929 } cullFlags[] = 3930 { 3931 { InstanceCullFlags::NONE, "noflags" }, 3932 { InstanceCullFlags::COUNTERCLOCKWISE, "ccw" }, 3933 { InstanceCullFlags::CULL_DISABLE, "nocull" }, 3934 { InstanceCullFlags::ALL, "ccw_nocull" }, 3935 }; 3936 3937 const struct 3938 { 3939 TopTestType topType; 3940 std::string name; 3941 } topType[] = 3942 { 3943 { TopTestType::DIFFERENT_INSTANCES, "transformed" }, // Each instance has its own transformation matrix. 3944 { TopTestType::IDENTICAL_INSTANCES, "notransform" }, // "Identical" instances, different geometries. 3945 }; 3946 3947 const struct 3948 { 3949 vk::VkAccelerationStructureBuildTypeKHR buildType; 3950 std::string name; 3951 } buildTypes[] = 3952 { 3953 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 3954 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 3955 }; 3956 3957 const struct 3958 { 3959 VkIndexType indexType; 3960 std::string name; 3961 } indexFormats[] = 3962 { 3963 { VK_INDEX_TYPE_NONE_KHR , "index_none" }, 3964 { VK_INDEX_TYPE_UINT16 , "index_uint16" }, 3965 { VK_INDEX_TYPE_UINT32 , "index_uint32" }, 3966 }; 3967 3968 auto& ctx = group->getTestContext(); 3969 3970 for (int shaderSourceIdx = 0; shaderSourceIdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceIdx) 3971 { 3972 de::MovePtr<tcu::TestCaseGroup> shaderSourceGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceIdx].name.c_str())); 3973 3974 for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx) 3975 { 3976 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str())); 3977 3978 for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx) 3979 { 3980 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str())); 3981 3982 for (int topTypeIdx = 0; topTypeIdx < DE_LENGTH_OF_ARRAY(topType); ++topTypeIdx) 3983 { 3984 for (int cullFlagsIdx = 0; cullFlagsIdx < DE_LENGTH_OF_ARRAY(cullFlags); ++cullFlagsIdx) 3985 { 3986 const std::string testName = topType[topTypeIdx].name + "_" + cullFlags[cullFlagsIdx].name; 3987 3988 TestParams testParams 3989 { 3990 shaderSourceTypes[shaderSourceIdx].shaderSourceType, 3991 shaderSourceTypes[shaderSourceIdx].shaderSourcePipeline, 3992 buildTypes[buildTypeIdx].buildType, 3993 VK_FORMAT_R32G32B32_SFLOAT, 3994 false, 3995 indexFormats[indexFormatIdx].indexType, 3996 BottomTestType::TRIANGLES, 3997 cullFlags[cullFlagsIdx].cullFlags, 3998 false, 3999 false, 4000 false, 4001 topType[topTypeIdx].topType, 4002 false, 4003 false, 4004 false, 4005 VkBuildAccelerationStructureFlagsKHR(0u), 4006 OT_NONE, 4007 OP_NONE, 4008 TEST_WIDTH, 4009 TEST_HEIGHT, 4010 0u, 4011 EmptyAccelerationStructureCase::NOT_EMPTY, 4012 }; 4013 indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, testName.c_str(), testParams)); 4014 } 4015 } 4016 buildTypeGroup->addChild(indexTypeGroup.release()); 4017 } 4018 shaderSourceGroup->addChild(buildTypeGroup.release()); 4019 } 4020 group->addChild(shaderSourceGroup.release()); 4021 } 4022} 4023 4024void addInstanceUpdateTests (tcu::TestCaseGroup* group) 4025{ 4026 const struct 4027 { 4028 vk::VkAccelerationStructureBuildTypeKHR buildType; 4029 std::string name; 4030 } buildTypes[] = 4031 { 4032 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 4033 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 4034 }; 4035 4036 struct 4037 { 4038 OperationType operationType; 4039 const char* name; 4040 } operationTypes[] = 4041 { 4042 { OP_UPDATE, "update" }, 4043 { OP_UPDATE_IN_PLACE, "update_in_place" }, 4044 }; 4045 4046 auto& ctx = group->getTestContext(); 4047 4048 for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx) 4049 { 4050 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeNdx].name.c_str())); 4051 4052 for (int operationTypesIdx = 0; operationTypesIdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypesIdx) 4053 { 4054 TestParams testParams 4055 { 4056 SST_COMPUTE_SHADER, 4057 SSP_COMPUTE_PIPELINE, 4058 buildTypes[buildTypeNdx].buildType, 4059 VK_FORMAT_R32G32B32_SFLOAT, 4060 false, 4061 VK_INDEX_TYPE_NONE_KHR, 4062 BottomTestType::TRIANGLES, 4063 InstanceCullFlags::NONE, 4064 false, 4065 false, 4066 false, 4067 TopTestType::IDENTICAL_INSTANCES, 4068 false, 4069 false, 4070 false, 4071 VkBuildAccelerationStructureFlagsKHR(0u), 4072 OT_NONE, 4073 OP_NONE, 4074 TEST_WIDTH, 4075 TEST_HEIGHT, 4076 0u, 4077 EmptyAccelerationStructureCase::NOT_EMPTY, 4078 }; 4079 4080 buildTypeGroup->addChild(new RayQueryASFuncArgTestCase(ctx, operationTypes[operationTypesIdx].name, testParams)); 4081 } 4082 group->addChild(buildTypeGroup.release()); 4083 } 4084} 4085 4086void addDynamicIndexingTests(tcu::TestCaseGroup* group) 4087{ 4088 auto& ctx = group->getTestContext(); 4089 group->addChild(new RayQueryASDynamicIndexingTestCase(ctx, "dynamic_indexing")); 4090} 4091 4092void addEmptyAccelerationStructureTests (tcu::TestCaseGroup* group) 4093{ 4094 const struct 4095 { 4096 ShaderSourceType shaderSourceType; 4097 ShaderSourcePipeline shaderSourcePipeline; 4098 std::string name; 4099 } shaderSourceTypes[] = 4100 { 4101 { SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader" }, 4102 { SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader" }, 4103 { SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader" }, 4104 { SST_GEOMETRY_SHADER, SSP_GRAPHICS_PIPELINE, "geometry_shader", }, 4105 { SST_FRAGMENT_SHADER, SSP_GRAPHICS_PIPELINE, "fragment_shader", }, 4106 { SST_COMPUTE_SHADER, SSP_COMPUTE_PIPELINE, "compute_shader", }, 4107 { SST_RAY_GENERATION_SHADER, SSP_RAY_TRACING_PIPELINE, "rgen_shader", }, 4108 { SST_INTERSECTION_SHADER, SSP_RAY_TRACING_PIPELINE, "isect_shader", }, 4109 { SST_ANY_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "ahit_shader", }, 4110 { SST_CLOSEST_HIT_SHADER, SSP_RAY_TRACING_PIPELINE, "chit_shader", }, 4111 { SST_MISS_SHADER, SSP_RAY_TRACING_PIPELINE, "miss_shader", }, 4112 { SST_CALLABLE_SHADER, SSP_RAY_TRACING_PIPELINE, "call_shader", }, 4113 }; 4114 4115 const struct 4116 { 4117 vk::VkAccelerationStructureBuildTypeKHR buildType; 4118 std::string name; 4119 } buildTypes[] = 4120 { 4121 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built" }, 4122 { VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built" }, 4123 }; 4124 4125 const struct 4126 { 4127 VkIndexType indexType; 4128 std::string name; 4129 } indexFormats[] = 4130 { 4131 { VK_INDEX_TYPE_NONE_KHR , "index_none" }, 4132 { VK_INDEX_TYPE_UINT16 , "index_uint16" }, 4133 { VK_INDEX_TYPE_UINT32 , "index_uint32" }, 4134 }; 4135 4136 const struct 4137 { 4138 EmptyAccelerationStructureCase emptyASCase; 4139 std::string name; 4140 } emptyCases[] = 4141 { 4142 { EmptyAccelerationStructureCase::INACTIVE_TRIANGLES, "inactive_triangles" }, 4143 { EmptyAccelerationStructureCase::INACTIVE_INSTANCES, "inactive_instances" }, 4144 { EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM, "no_geometries_bottom" }, 4145 { EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP, "no_primitives_top" }, 4146 { EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM, "no_primitives_bottom" }, 4147 }; 4148 4149 auto& ctx = group->getTestContext(); 4150 4151 for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx) 4152 { 4153 de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceNdx].name.c_str())); 4154 4155 for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx) 4156 { 4157 de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str())); 4158 4159 for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx) 4160 { 4161 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str())); 4162 4163 for (int emptyCaseIdx = 0; emptyCaseIdx < DE_LENGTH_OF_ARRAY(emptyCases); ++emptyCaseIdx) 4164 { 4165 TestParams testParams 4166 { 4167 shaderSourceTypes[shaderSourceNdx].shaderSourceType, 4168 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline, 4169 buildTypes[buildTypeIdx].buildType, 4170 VK_FORMAT_R32G32B32_SFLOAT, 4171 false, 4172 indexFormats[indexFormatIdx].indexType, 4173 BottomTestType::TRIANGLES, 4174 InstanceCullFlags::NONE, 4175 false, 4176 false, 4177 false, 4178 TopTestType::IDENTICAL_INSTANCES, 4179 false, 4180 false, 4181 false, 4182 VkBuildAccelerationStructureFlagsKHR(0u), 4183 OT_NONE, 4184 OP_NONE, 4185 TEST_WIDTH, 4186 TEST_HEIGHT, 4187 0u, 4188 emptyCases[emptyCaseIdx].emptyASCase, 4189 }; 4190 indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, emptyCases[emptyCaseIdx].name.c_str(), testParams)); 4191 } 4192 buildTypeGroup->addChild(indexTypeGroup.release()); 4193 } 4194 sourceTypeGroup->addChild(buildTypeGroup.release()); 4195 } 4196 group->addChild(sourceTypeGroup.release()); 4197 } 4198} 4199 4200tcu::TestCaseGroup* createAccelerationStructuresTests(tcu::TestContext& testCtx) 4201{ 4202 // Acceleration structure tests using rayQuery feature 4203 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "acceleration_structures")); 4204 4205 // Test building AS with different build types, build flags and geometries/instances using arrays or arrays of pointers 4206 addTestGroup(group.get(), "flags", addBasicBuildingTests); 4207 // Test building AS with different vertex and index formats 4208 addTestGroup(group.get(), "format", addVertexIndexFormatsTests); 4209 // Test copying, compaction and serialization of AS 4210 addTestGroup(group.get(), "operations", addOperationTests); 4211 // Test host threading operations 4212 addTestGroup(group.get(), "host_threading", addHostThreadingOperationTests); 4213 // Test using AS as function argument using both pointers and bare values 4214 addTestGroup(group.get(), "function_argument", addFuncArgTests); 4215 // Test building AS with counterclockwise triangles and/or disabling face culling 4216 addTestGroup(group.get(), "instance_triangle_culling", addInstanceTriangleCullingTests); 4217 // Test updating instance index using both in-place and separate src/dst acceleration structures 4218 addTestGroup(group.get(), "instance_update", addInstanceUpdateTests); 4219 // Exercise dynamic indexing of acceleration structures 4220 addTestGroup(group.get(), "dynamic_indexing", addDynamicIndexingTests); 4221 // Test building empty acceleration structures using different methods 4222 addTestGroup(group.get(), "empty", addEmptyAccelerationStructureTests); 4223 4224 return group.release(); 4225} 4226 4227} // RayQuery 4228 4229} // vkt 4230