1// Copyright 2018-2022 The Khronos Group Inc. 2// 3// SPDX-License-Identifier: CC-BY-4.0 4 5[[ray-tracing]] 6= Ray Tracing 7 8Ray tracing uses a separate rendering pipeline from both the graphics and 9compute pipelines (see <<pipelines-ray-tracing,Ray Tracing Pipeline>>). 10 11[[fig-raypipe]] 12image::{images}/ray_tracing_execution.svg[align="center",title="Ray tracing pipeline execution",opts="{imageopts}"] 13 14.Caption 15**** 16Interaction between the different shader stages in the ray tracing pipeline 17**** 18 19Within the ray tracing pipeline, code:OpTraceRayKHR 20ifdef::VK_NV_ray_tracing_motion_blur[] 21or code:OpTraceRayMotionNV 22endif::VK_NV_ray_tracing_motion_blur[] 23can: be called to perform a <<ray-traversal,ray traversal>> that invokes the 24various ray tracing shader stages during its execution. 25The relationship between the ray tracing pipeline object and the geometries 26present in the acceleration structure traversed is passed into the ray 27tracing command in a slink:VkBuffer object known as a _shader binding 28table_. 29code:OpExecuteCallableKHR can also be used in ray tracing pipelines to 30invoke a <<shaders-callable,callable shader>>. 31 32During execution, control alternates between scheduling and other 33operations. 34The scheduling functionality is implementation-specific and is responsible 35for workload execution. 36The shader stages are programmable. 37<<ray-traversal, _Traversal_>>, which refers to the process of traversing 38acceleration structures to find potential intersections of rays with 39geometry, is fixed function. 40 41The programmable portions of the pipeline are exposed in a single-ray 42programming model, with each invocation handling one ray at a time. 43Memory operations can: be synchronized using standard memory barriers. 44The code:Workgroup scope and variables with a storage class of 45code:Workgroup must: not be used in the ray tracing pipeline. 46 47 48[[ray-tracing-shader-call]] 49== Shader Call Instructions 50 51A _shader call_ is an instruction which may: cause execution to continue 52elsewhere by creating one or more invocations that execute a different 53shader stage. 54 55The shader call instructions are: 56 57 * code:OpTraceRayKHR which may: invoke intersection, any-hit, closest hit, 58 or miss shaders, 59ifdef::VK_NV_ray_tracing_motion_blur[] 60 * code:OpTraceRayMotionNV which may: invoke intersection, any-hit, closest 61 hit, or miss shaders, 62endif::VK_NV_ray_tracing_motion_blur[] 63 * code:OpReportIntersectionKHR which may: invoke any-hit shaders, and 64 * code:OpExecuteCallableKHR which will invoke a callable shader. 65ifdef::VK_NV_ray_tracing_invocation_reorder[] 66 * code:OpHitObjectTraceRayNV, code:OpHitObjectTraceRayMotionNV, and 67 code:OpHitObjectExecuteShaderNV which may: invoke intersection, any-hit, 68 closest hit, miss, or callable shaders. 69endif::VK_NV_ray_tracing_invocation_reorder[] 70 71ifdef::VK_VERSION_1_1[] 72The invocations created by shader call instructions are grouped into 73subgroups by the implementation. 74Those subgroups may: be unrelated to the subgroup of the parent invocation. 75endif::VK_VERSION_1_1[] 76 77 78[[ray-tracing-recursion-depth]] 79_Pipeline trace ray instructions_ can: be used recursively; invoked shaders 80can: themselves execute pipeline trace ray instructions, to a maximum depth 81defined by the 82ifdef::VK_NV_ray_tracing[] 83<<limits-maxRecursionDepth, pname:maxRecursionDepth>> or 84endif::VK_NV_ray_tracing[] 85<<limits-maxRayRecursionDepth, pname:maxRayRecursionDepth>> limit. 86 87Shaders directly invoked from the API always have a recursion depth of 0; 88each shader executed by a pipeline trace ray instruction has a recursion 89depth one higher than the recursion depth of the shader which invoked it. 90Applications must: not invoke a shader with a recursion depth greater than 91the value of 92ifdef::VK_NV_ray_tracing[] 93pname:maxRecursionDepth or 94endif::VK_NV_ray_tracing[] 95pname:maxPipelineRayRecursionDepth specified in the pipeline. 96 97There is no explicit recursion limit for other shader call instructions 98which may recurse (e.g. code:OpExecuteCallableKHR) but there is an upper 99bound determined by the <<ray-tracing-pipeline-stack, stack size>>. 100 101[[ray-tracing-repack]] 102An _invocation repack instruction_ is a ray tracing shader call instruction 103where the implementation may: change the set of invocations that are 104executing. 105When a repack instruction is encountered, the invocation is suspended and a 106new invocation begins and executes the instruction. 107After executing the repack instruction (which may: result in other ray 108tracing shader stages executing) the new invocation ends and the original 109invocation is resumed, but it may: be resumed in a different subgroup or at 110a different code:SubgroupLocalInvocationId within the same subgroup. 111When a subset of invocations in a subgroup execute the invocation repack 112instruction, those that do not execute it remain in the same subgroup at the 113same code:SubgroupLocalInvocationId. 114 115The code:OpTraceRayKHR, 116ifdef::VK_NV_ray_tracing_motion_blur[] 117code:OpTraceRayMotionNV, 118endif::VK_NV_ray_tracing_motion_blur[] 119ifdef::VK_NV_ray_tracing_invocation_reorder[] 120code:OpReorderThreadWithHintNV, code:OpReorderThreadWithHitObjectNV, 121endif::VK_NV_ray_tracing_invocation_reorder[] 122code:OpReportIntersectionKHR, and code:OpExecuteCallableKHR instructions are 123invocation repack instructions. 124 125ifdef::VK_VERSION_1_1[] 126ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 127The invocations that are executing before an invocation repack instruction, 128after the instruction, or are created by the instruction, are 129<<shader-call-related,shader-call-related>>. 130endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 131 132If the implementation changes the composition of subgroups, the values of 133code:SubgroupSize, code:SubgroupLocalInvocationId, 134ifdef::VK_NV_shader_sm_builtins[] 135code:SMIDNV, code:WarpIDNV, 136endif::VK_NV_shader_sm_builtins[] 137and builtin variables that are derived from them (code:SubgroupEqMask, 138code:SubgroupGeMask, code:SubgroupGtMask, code:SubgroupLeMask, 139code:SubgroupLtMask) must: be changed accordingly by the invocation repack 140instruction. 141The application must: use <<builtin-volatile-semantics,code:Volatile 142semantics>> on these code:BuiltIn variables when used in the ray generation, 143closest hit, miss, intersection, and callable shaders. 144Similarly, the application must: use code:Volatile semantics on any 145code:RayTmaxKHR decorated code:Builtin used in an intersection shader. 146 147[NOTE] 148.Note 149==== 150<<shaders-group-operations,Subgroup operations>> are permitted in the 151programmable ray tracing shader stages. 152However, shader call instructions place a bound on where results of subgroup 153instructions or subgroup-scoped instructions that execute the dynamic 154instance of that instruction are potentially valid. 155For example, care must: be taken when using the result of a ballot operation 156that was computed before an invocation repack instruction, after that repack 157instruction. 158The ballot may: be incorrect as the set of invocations could have changed. 159 160ifdef::VK_VERSION_1_3,VK_EXT_subgroup_size_control[] 161While the code:SubgroupSize built-in is required to be declared 162code:Volatile, its value will never change unless 163ename:VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT is set 164on pipeline creation, as without that bit set, its value is required to 165match that of slink:VkPhysicalDeviceSubgroupProperties::pname:subgroupSize. 166endif::VK_VERSION_1_3,VK_EXT_subgroup_size_control[] 167 168ifdef::VK_KHR_shader_clock[] 169For clock operations, the value of a code:Subgroup scoped 170code:OpReadClockKHR read before the dynamic instance of a repack instruction 171should: not be compared to the result of that clock instruction after the 172repack instruction. 173endif::VK_KHR_shader_clock[] 174==== 175endif::VK_VERSION_1_1[] 176 177ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 178When a ray tracing shader executes a dynamic instance of an invocation 179repack instruction which results in another ray tracing shader being 180invoked, their instructions are related by 181<<shader-call-order,shader-call-order>>. 182 183For ray tracing invocations that are 184<<shader-call-related,shader-call-related>>: 185 186 * <<memory-model-memory-operation,memory operations>> on 187 code:StorageBuffer, code:Image, and code:ShaderRecordBufferKHR storage 188 classes can: be synchronized using the 189ifdef::VK_KHR_ray_tracing_pipeline[code:ShaderCallKHR] 190ifndef::VK_KHR_ray_tracing_pipeline[code:Device or code:QueueFamily] 191 scope. 192 193 * the code:CallableDataKHR, code:IncomingCallableDataKHR, 194 code:RayPayloadKHR, code:HitAttributeKHR, and code:IncomingRayPayloadKHR 195 storage classes are <<memory-model-shader-io,system-synchronized>> and 196 no application availability and visibility operations are required. 197 198 * memory operations within a single invocation before and after the 199 invocation repack instruction are ordered by 200 <<memory-model-program-order,program-order>> and do not require explicit 201 synchronzation. 202endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 203 204 205[[ray-tracing-commands]] 206== Ray Tracing Commands 207 208_Ray tracing commands_ provoke work in the ray tracing pipeline. 209Ray tracing commands are recorded into a command buffer and when executed by 210a queue will produce work that executes according to the currently bound ray 211tracing pipeline. 212A ray tracing pipeline must: be bound to a command buffer before any ray 213tracing commands are recorded in that command buffer. 214 215ifdef::VK_NV_ray_tracing[] 216 217[open,refpage='vkCmdTraceRaysNV',desc='Initialize a ray tracing dispatch',type='protos'] 218-- 219:refpage: vkCmdTraceRaysNV 220 221To dispatch ray tracing use: 222 223include::{generated}/api/protos/vkCmdTraceRaysNV.adoc[] 224 225 * pname:commandBuffer is the command buffer into which the command will be 226 recorded. 227 * pname:raygenShaderBindingTableBuffer is the buffer object that holds the 228 shader binding table data for the ray generation shader stage. 229 * pname:raygenShaderBindingOffset is the offset in bytes (relative to 230 pname:raygenShaderBindingTableBuffer) of the ray generation shader being 231 used for the trace. 232 * pname:missShaderBindingTableBuffer is the buffer object that holds the 233 shader binding table data for the miss shader stage. 234 * pname:missShaderBindingOffset is the offset in bytes (relative to 235 pname:missShaderBindingTableBuffer) of the miss shader being used for 236 the trace. 237 * pname:missShaderBindingStride is the size in bytes of each shader 238 binding table record in pname:missShaderBindingTableBuffer. 239 * pname:hitShaderBindingTableBuffer is the buffer object that holds the 240 shader binding table data for the hit shader stages. 241 * pname:hitShaderBindingOffset is the offset in bytes (relative to 242 pname:hitShaderBindingTableBuffer) of the hit shader group being used 243 for the trace. 244 * pname:hitShaderBindingStride is the size in bytes of each shader binding 245 table record in pname:hitShaderBindingTableBuffer. 246 * pname:callableShaderBindingTableBuffer is the buffer object that holds 247 the shader binding table data for the callable shader stage. 248 * pname:callableShaderBindingOffset is the offset in bytes (relative to 249 pname:callableShaderBindingTableBuffer) of the callable shader being 250 used for the trace. 251 * pname:callableShaderBindingStride is the size in bytes of each shader 252 binding table record in pname:callableShaderBindingTableBuffer. 253 * pname:width is the width of the ray trace query dimensions. 254 * pname:height is height of the ray trace query dimensions. 255 * pname:depth is depth of the ray trace query dimensions. 256 257When the command is executed, a ray generation group of [eq]#pname:width 258{times} pname:height {times} pname:depth# rays is assembled. 259 260.Valid Usage 261**** 262include::{chapters}/commonvalidity/trace_rays_common.adoc[] 263 * [[VUID-vkCmdTraceRaysNV-commandBuffer-04624]] 264 pname:commandBuffer must: not be a protected command buffer 265 * [[VUID-vkCmdTraceRaysNV-maxRecursionDepth-03625]] 266 This command must: not cause a pipeline trace ray instruction to be 267 executed from a shader invocation with a <<ray-tracing-recursion-depth, 268 recursion depth>> greater than the value of pname:maxRecursionDepth used 269 to create the bound ray tracing pipeline 270 * [[VUID-vkCmdTraceRaysNV-raygenShaderBindingTableBuffer-04042]] 271 If pname:raygenShaderBindingTableBuffer is non-sparse then it must: be 272 bound completely and contiguously to a single sname:VkDeviceMemory 273 object 274 * [[VUID-vkCmdTraceRaysNV-raygenShaderBindingOffset-02455]] 275 pname:raygenShaderBindingOffset must: be less than the size of 276 pname:raygenShaderBindingTableBuffer 277 * [[VUID-vkCmdTraceRaysNV-raygenShaderBindingOffset-02456]] 278 pname:raygenShaderBindingOffset must: be a multiple of 279 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 280 * [[VUID-vkCmdTraceRaysNV-missShaderBindingTableBuffer-04043]] 281 If pname:missShaderBindingTableBuffer is non-sparse then it must: be 282 bound completely and contiguously to a single sname:VkDeviceMemory 283 object 284 * [[VUID-vkCmdTraceRaysNV-missShaderBindingOffset-02457]] 285 pname:missShaderBindingOffset must: be less than the size of 286 pname:missShaderBindingTableBuffer 287 * [[VUID-vkCmdTraceRaysNV-missShaderBindingOffset-02458]] 288 pname:missShaderBindingOffset must: be a multiple of 289 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 290 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingTableBuffer-04044]] 291 If pname:hitShaderBindingTableBuffer is non-sparse then it must: be 292 bound completely and contiguously to a single sname:VkDeviceMemory 293 object 294 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingOffset-02459]] 295 pname:hitShaderBindingOffset must: be less than the size of 296 pname:hitShaderBindingTableBuffer 297 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingOffset-02460]] 298 pname:hitShaderBindingOffset must: be a multiple of 299 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 300 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingTableBuffer-04045]] 301 If pname:callableShaderBindingTableBuffer is non-sparse then it must: be 302 bound completely and contiguously to a single sname:VkDeviceMemory 303 object 304 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingOffset-02461]] 305 pname:callableShaderBindingOffset must: be less than the size of 306 pname:callableShaderBindingTableBuffer 307 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingOffset-02462]] 308 pname:callableShaderBindingOffset must: be a multiple of 309 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 310 * [[VUID-vkCmdTraceRaysNV-missShaderBindingStride-02463]] 311 pname:missShaderBindingStride must: be a multiple of 312 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupHandleSize 313 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingStride-02464]] 314 pname:hitShaderBindingStride must: be a multiple of 315 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupHandleSize 316 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingStride-02465]] 317 pname:callableShaderBindingStride must: be a multiple of 318 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupHandleSize 319 * [[VUID-vkCmdTraceRaysNV-missShaderBindingStride-02466]] 320 pname:missShaderBindingStride must: be less than or equal to 321 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxShaderGroupStride 322 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingStride-02467]] 323 pname:hitShaderBindingStride must: be less than or equal to 324 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxShaderGroupStride 325 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingStride-02468]] 326 pname:callableShaderBindingStride must: be less than or equal to 327 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxShaderGroupStride 328 * [[VUID-vkCmdTraceRaysNV-width-02469]] 329 pname:width must: be less than or equal to 330 sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0] 331 * [[VUID-vkCmdTraceRaysNV-height-02470]] 332 pname:height must: be less than or equal to 333 sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1] 334 * [[VUID-vkCmdTraceRaysNV-depth-02471]] 335 pname:depth must: be less than or equal to 336 sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2] 337**** 338 339include::{generated}/validity/protos/vkCmdTraceRaysNV.adoc[] 340-- 341 342endif::VK_NV_ray_tracing[] 343 344ifdef::VK_KHR_ray_tracing_pipeline[] 345[open,refpage='vkCmdTraceRaysKHR',desc='Initialize a ray tracing dispatch',type='protos'] 346-- 347:refpage: vkCmdTraceRaysKHR 348 349To dispatch ray tracing use: 350 351include::{generated}/api/protos/vkCmdTraceRaysKHR.adoc[] 352 353 * pname:commandBuffer is the command buffer into which the command will be 354 recorded. 355 * pname:pRaygenShaderBindingTable is a 356 slink:VkStridedDeviceAddressRegionKHR that holds the shader binding 357 table data for the ray generation shader stage. 358 * pname:pMissShaderBindingTable is a slink:VkStridedDeviceAddressRegionKHR 359 that holds the shader binding table data for the miss shader stage. 360 * pname:pHitShaderBindingTable is a slink:VkStridedDeviceAddressRegionKHR 361 that holds the shader binding table data for the hit shader stage. 362 * pname:pCallableShaderBindingTable is a 363 slink:VkStridedDeviceAddressRegionKHR that holds the shader binding 364 table data for the callable shader stage. 365 * pname:width is the width of the ray trace query dimensions. 366 * pname:height is height of the ray trace query dimensions. 367 * pname:depth is depth of the ray trace query dimensions. 368 369When the command is executed, a ray generation group of [eq]#pname:width 370{times} pname:height {times} pname:depth# rays is assembled. 371 372.Valid Usage 373**** 374include::{chapters}/commonvalidity/trace_rays_common.adoc[] 375include::{chapters}/commonvalidity/trace_rays_common_khr.adoc[] 376include::{chapters}/commonvalidity/trace_rays_binding_table_raygen_stride.adoc[] 377 378:rayGenShaderBindingTableAddress: pname:pRayGenShaderBindingTable->deviceAddress 379:rayGenShaderBindingTableStride: pname:pRayGenShaderBindingTable->stride 380:missShaderBindingTableAddress: pname:pMissShaderBindingTable->deviceAddress 381:missShaderBindingTableStride: pname:pMissShaderBindingTable->stride 382:hitShaderBindingTableAddress: pname:pHitShaderBindingTable->deviceAddress 383:hitShaderBindingTableStride: pname:pHitShaderBindingTable->stride 384:callableShaderBindingTableAddress: pname:pCallableShaderBindingTable->deviceAddress 385:callableShaderBindingTableStride: pname:pCallableShaderBindingTable->stride 386include::{chapters}/commonvalidity/trace_rays_binding_table.adoc[] 387include::{chapters}/commonvalidity/trace_rays_limits_common.adoc[] 388**** 389 390include::{generated}/validity/protos/vkCmdTraceRaysKHR.adoc[] 391-- 392 393[open,refpage='VkStridedDeviceAddressRegionKHR',desc='Structure specifying a region of device addresses with a stride',type='structs'] 394-- 395:refpage: VkStridedDeviceAddressRegionKHR 396 397The sname:VkStridedDeviceAddressRegionKHR structure is defined as: 398 399include::{generated}/api/structs/VkStridedDeviceAddressRegionKHR.adoc[] 400 401 * pname:deviceAddress is the device address (as returned by the 402 flink:vkGetBufferDeviceAddress command) at which the region starts, or 403 zero if the region is unused. 404 * pname:stride is the byte stride between consecutive elements. 405 * pname:size is the size in bytes of the region starting at 406 pname:deviceAddress. 407 408.Valid Usage 409**** 410 * [[VUID-VkStridedDeviceAddressRegionKHR-size-04631]] 411 If pname:size is not zero, all addresses between pname:deviceAddress and 412 [eq]#pname:deviceAddress {plus} pname:size - 1# must: be in the buffer 413 device address range of the same buffer 414 * [[VUID-VkStridedDeviceAddressRegionKHR-size-04632]] 415 If pname:size is not zero, pname:stride must: be less than or equal to 416 the size of the buffer from which pname:deviceAddress was queried 417**** 418 419include::{generated}/validity/structs/VkStridedDeviceAddressRegionKHR.adoc[] 420-- 421 422ifdef::VK_HUAWEI_invocation_mask[] 423[open,refpage='vkCmdBindInvocationMaskHUAWEI',desc='Bind an invocation mask image on a command buffer',type='protos'] 424-- 425When invocation mask image usage is enabled in the bound ray tracing 426pipeline, the pipeline uses an invocation mask image specified by the 427command: 428 429include::{generated}/api/protos/vkCmdBindInvocationMaskHUAWEI.adoc[] 430 431 * pname:commandBuffer is the command buffer into which the command will be 432 recorded 433 * pname:imageView is an image view handle specifying the invocation mask 434 image pname:imageView may: be set to dlink:VK_NULL_HANDLE, which is 435 equivalent to specifying a view of an image filled with ones value. 436 * pname:imageLayout is the layout that the image subresources accessible 437 from pname:imageView will be in when the invocation mask image is 438 accessed 439 440.Valid Usage 441**** 442 * [[VUID-vkCmdBindInvocationMaskHUAWEI-None-04976]] 443 The <<features-invocationMask, pname:invocationMask>> feature must: be 444 enabled 445 * [[VUID-vkCmdBindInvocationMaskHUAWEI-imageView-04977]] 446 If pname:imageView is not dlink:VK_NULL_HANDLE, it must: be a valid 447 slink:VkImageView handle of type ename:VK_IMAGE_VIEW_TYPE_2D 448 * [[VUID-vkCmdBindInvocationMaskHUAWEI-imageView-04978]] 449 If pname:imageView is not dlink:VK_NULL_HANDLE, it must: have a format 450 of ename:VK_FORMAT_R8_UINT 451 * [[VUID-vkCmdBindInvocationMaskHUAWEI-imageView-04979]] 452 If pname:imageView is not dlink:VK_NULL_HANDLE, it must: have been 453 created with ename:VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI set 454 * [[VUID-vkCmdBindInvocationMaskHUAWEI-imageView-04980]] 455 If pname:imageView is not dlink:VK_NULL_HANDLE, pname:imageLayout must: 456 be ename:VK_IMAGE_LAYOUT_GENERAL 457 * [[VUID-vkCmdBindInvocationMaskHUAWEI-width-04981]] 458 Thread mask image resolution must match the pname:width and pname:height 459 in flink:vkCmdTraceRaysKHR 460 * [[VUID-vkCmdBindInvocationMaskHUAWEI-None-04982]] 461 Each element in the invocation mask image must: have the value `0` or 462 `1`. 463 The value 1 means the invocation is active 464 * [[VUID-vkCmdBindInvocationMaskHUAWEI-width-04983]] 465 pname:width in flink:vkCmdTraceRaysKHR should be 1 466**** 467 468include::{generated}/validity/protos/vkCmdBindInvocationMaskHUAWEI.adoc[] 469-- 470endif::VK_HUAWEI_invocation_mask[] 471 472[open,refpage='vkCmdTraceRaysIndirectKHR',desc='Initialize an indirect ray tracing dispatch',type='protos'] 473-- 474:refpage: vkCmdTraceRaysIndirectKHR 475 476To dispatch ray tracing, with some parameters sourced on the device, use: 477 478include::{generated}/api/protos/vkCmdTraceRaysIndirectKHR.adoc[] 479 480 * pname:commandBuffer is the command buffer into which the command will be 481 recorded. 482 * pname:pRaygenShaderBindingTable is a 483 slink:VkStridedDeviceAddressRegionKHR that holds the shader binding 484 table data for the ray generation shader stage. 485 * pname:pMissShaderBindingTable is a slink:VkStridedDeviceAddressRegionKHR 486 that holds the shader binding table data for the miss shader stage. 487 * pname:pHitShaderBindingTable is a slink:VkStridedDeviceAddressRegionKHR 488 that holds the shader binding table data for the hit shader stage. 489 * pname:pCallableShaderBindingTable is a 490 slink:VkStridedDeviceAddressRegionKHR that holds the shader binding 491 table data for the callable shader stage. 492 * pname:indirectDeviceAddress is a buffer device address which is a 493 pointer to a slink:VkTraceRaysIndirectCommandKHR structure containing 494 the trace ray parameters. 495 496fname:vkCmdTraceRaysIndirectKHR behaves similarly to flink:vkCmdTraceRaysKHR 497except that the ray trace query dimensions are read by the device from 498pname:indirectDeviceAddress during execution. 499 500.Valid Usage 501**** 502include::{chapters}/commonvalidity/trace_rays_common.adoc[] 503include::{chapters}/commonvalidity/trace_rays_common_khr.adoc[] 504include::{chapters}/commonvalidity/trace_rays_binding_table_raygen_stride.adoc[] 505 506:rayGenShaderBindingTableAddress: pname:pRayGenShaderBindingTable->deviceAddress 507:rayGenShaderBindingTableStride: pname:pRayGenShaderBindingTable->stride 508:missShaderBindingTableAddress: pname:pMissShaderBindingTable->deviceAddress 509:missShaderBindingTableStride: pname:pMissShaderBindingTable->stride 510:hitShaderBindingTableAddress: pname:pHitShaderBindingTable->deviceAddress 511:hitShaderBindingTableStride: pname:pHitShaderBindingTable->stride 512:callableShaderBindingTableAddress: pname:pCallableShaderBindingTable->deviceAddress 513:callableShaderBindingTableStride: pname:pCallableShaderBindingTable->stride 514include::{chapters}/commonvalidity/trace_rays_binding_table.adoc[] 515 516:cmdstruct: VkTraceRaysIndirectCommandKHR 517:feature: rayTracingPipelineTraceRaysIndirect 518include::{chapters}/commonvalidity/trace_rays_indirect_common.adoc[] 519**** 520 521include::{generated}/validity/protos/vkCmdTraceRaysIndirectKHR.adoc[] 522-- 523 524[open,refpage='VkTraceRaysIndirectCommandKHR',desc='Structure specifying the parameters of an indirect ray tracing command',type='structs'] 525-- 526:refpage: VkTraceRaysIndirectCommandKHR 527 528The sname:VkTraceRaysIndirectCommandKHR structure is defined as: 529 530include::{generated}/api/structs/VkTraceRaysIndirectCommandKHR.adoc[] 531 532 * pname:width is the width of the ray trace query dimensions. 533 * pname:height is height of the ray trace query dimensions. 534 * pname:depth is depth of the ray trace query dimensions. 535 536The members of sname:VkTraceRaysIndirectCommandKHR have the same meaning as 537the similarly named parameters of flink:vkCmdTraceRaysKHR. 538 539.Valid Usage 540**** 541include::{chapters}/commonvalidity/trace_rays_limits_common.adoc[] 542**** 543 544include::{generated}/validity/structs/VkTraceRaysIndirectCommandKHR.adoc[] 545-- 546 547ifdef::VK_KHR_ray_tracing_maintenance1[] 548[open,refpage='vkCmdTraceRaysIndirect2KHR',desc='Initialize an indirect ray tracing dispatch with indirect shader binding tables',type='protos'] 549-- 550:refpage: vkCmdTraceRaysIndirect2KHR 551 552To dispatch ray tracing, with some parameters sourced on the device, use: 553 554include::{generated}/api/protos/vkCmdTraceRaysIndirect2KHR.adoc[] 555 556 * pname:commandBuffer is the command buffer into which the command will be 557 recorded. 558 * pname:indirectDeviceAddress is a buffer device address which is a 559 pointer to a slink:VkTraceRaysIndirectCommand2KHR structure containing 560 the trace ray parameters. 561 562fname:vkCmdTraceRaysIndirect2KHR behaves similarly to 563flink:vkCmdTraceRaysIndirectKHR except that shader binding table parameters 564as well as dispatch dimensions are read by the device from 565pname:indirectDeviceAddress during execution. 566 567.Valid Usage 568**** 569include::{chapters}/commonvalidity/trace_rays_common.adoc[] 570include::{chapters}/commonvalidity/trace_rays_common_khr.adoc[] 571 572:cmdstruct: VkTraceRaysIndirectCommand2KHR 573:feature: rayTracingPipelineTraceRaysIndirect2 574include::{chapters}/commonvalidity/trace_rays_indirect_common.adoc[] 575**** 576 577include::{generated}/validity/protos/vkCmdTraceRaysIndirect2KHR.adoc[] 578-- 579 580[open,refpage='VkTraceRaysIndirectCommand2KHR',desc='Structure specifying the parameters of an indirect trace ray command with indirect shader binding tables',type='structs'] 581-- 582:refpage: VkTraceRaysIndirectCommand2KHR 583 584The sname:VkTraceRaysIndirectCommand2KHR structure is defined as: 585 586include::{generated}/api/structs/VkTraceRaysIndirectCommand2KHR.adoc[] 587 588 * pname:raygenShaderRecordAddress is a basetype:VkDeviceAddress of the ray 589 generation shader binding table record used by this command. 590 * pname:raygenShaderRecordSize is a basetype:VkDeviceSize number of bytes 591 corresponding to the ray generation shader binding table record at base 592 address pname:raygenShaderRecordAddress. 593 * pname:missShaderBindingTableAddress is a basetype:VkDeviceAddress of the 594 first record in the miss shader binding table used by this command. 595 * pname:missShaderBindingTableSize is a basetype:VkDeviceSize number of 596 bytes corresponding to the total size of the miss shader binding table 597 at pname:missShaderBindingTableAddress that may be accessed by this 598 command. 599 * pname:missShaderBindingTableStride is a basetype:VkDeviceSize number of 600 bytes between records of the miss shader binding table. 601 * pname:hitShaderBindingTableAddress is a basetype:VkDeviceAddress of the 602 first record in the hit shader binding table used by this command. 603 * pname:hitShaderBindingTableSize is a basetype:VkDeviceSize number of 604 bytes corresponding to the total size of the hit shader binding table at 605 pname:hitShaderBindingTableAddress that may be accessed by this command. 606 * pname:hitShaderBindingTableStride is a basetype:VkDeviceSize number of 607 bytes between records of the hit shader binding table. 608 * pname:callableShaderBindingTableAddress is a basetype:VkDeviceAddress of 609 the first record in the callable shader binding table used by this 610 command. 611 * pname:callableShaderBindingTableSize is a basetype:VkDeviceSize number 612 of bytes corresponding to the total size of the callable shader binding 613 table at pname:callableShaderBindingTableAddress that may be accessed by 614 this command. 615 * pname:callableShaderBindingTableStride is a basetype:VkDeviceSize number 616 of bytes between records of the callable shader binding table. 617 * pname:width is the width of the ray trace query dimensions. 618 * pname:height is height of the ray trace query dimensions. 619 * pname:depth is depth of the ray trace query dimensions. 620 621The members of sname:VkTraceRaysIndirectCommand2KHR have the same meaning as 622the similarly named parameters of flink:vkCmdTraceRaysKHR. 623 624Indirect shader binding table buffer parameters must satisfy the same memory 625alignment and binding requirements as their counterparts in 626flink:vkCmdTraceRaysIndirectKHR and flink:vkCmdTraceRaysKHR. 627 628.Valid Usage 629**** 630:rayGenShaderBindingTableAddress: pname:raygenShaderRecordAddress 631:rayGenShaderBindingTableSize: pname:raygenShaderRecordSize 632:missShaderBindingTableAddress: pname:missShaderBindingTableAddress 633:missShaderBindingTableStride: pname:missShaderBindingTableStride 634:hitShaderBindingTableAddress: pname:hitShaderBindingTableAddress 635:hitShaderBindingTableStride: pname:hitShaderBindingTableStride 636:callableShaderBindingTableAddress: pname:callableShaderBindingTableAddress 637:callableShaderBindingTableStride: pname:callableShaderBindingTableStride 638include::{chapters}/commonvalidity/trace_rays_binding_table.adoc[] 639include::{chapters}/commonvalidity/trace_rays_limits_common.adoc[] 640**** 641 642include::{generated}/validity/structs/VkTraceRaysIndirectCommand2KHR.adoc[] 643-- 644endif::VK_KHR_ray_tracing_maintenance1[] 645 646endif::VK_KHR_ray_tracing_pipeline[] 647 648 649[[shader-binding-table]] 650== Shader Binding Table 651 652A _shader binding table_ is a resource which establishes the relationship 653between the ray tracing pipeline and the acceleration structures that were 654built for the ray tracing pipeline. 655It indicates the shaders that operate on each geometry in an acceleration 656structure. 657In addition, it contains the resources accessed by each shader, including 658indices of textures, buffer device addresses, and constants. 659The application allocates and manages _shader binding tables_ as 660slink:VkBuffer objects. 661 662Each entry in the shader binding table consists of 663pname:shaderGroupHandleSize bytes of data, either as queried by 664flink:vkGetRayTracingShaderGroupHandlesKHR to refer to those specified 665shaders, or all zeros to refer to a zero shader group. 666A zero shader group behaves as though it is a shader group consisting 667entirely of ename:VK_SHADER_UNUSED_KHR. 668The remainder of the data specified by the stride is application-visible 669data that can be referenced by a code:ShaderRecordBufferKHR block in the 670shader. 671 672The shader binding tables to use in a ray tracing pipeline are passed to the 673ifdef::VK_NV_ray_tracing[] 674flink:vkCmdTraceRaysNV, 675endif::VK_NV_ray_tracing[] 676flink:vkCmdTraceRaysKHR, or flink:vkCmdTraceRaysIndirectKHR commands. 677Shader binding tables are read-only in shaders that are executing on the ray 678tracing pipeline. 679 680Shader variables identified with the code:ShaderRecordBufferKHR storage 681class are used to access the provided shader binding table. 682Such variables must: be: 683 684 * typed as code:OpTypeStruct, or an array of this type, 685 * identified with a code:Block decoration, and 686 * laid out explicitly using the code:Offset, code:ArrayStride, and 687 code:MatrixStride decorations as specified in 688 <<interfaces-resources-layout,Offset and Stride Assignment>>. 689 690The code:Offset decoration for any member of a code:Block-decorated variable 691in the code:ShaderRecordBufferKHR storage class must: not cause the space 692required for that variable to extend outside the range [eq]#[0, 693pname:maxStorageBufferRange)#. 694 695Accesses to the shader binding table from ray tracing pipelines must: be 696<<synchronization-dependencies,synchronized>> with the 697ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR 698<<synchronization-pipeline-stages, pipeline stage>> and an 699<<synchronization-access-types, access type>> of 700ename:VK_ACCESS_SHADER_READ_BIT. 701 702[NOTE] 703.Note 704==== 705Because different shader record buffers can be associated with the same 706shader, a shader variable with code:ShaderRecordBufferKHR storage class will 707not be dynamically uniform if different invocations of the same shader can 708reference different data in the shader record buffer, such as if the same 709shader occurs twice in the shader binding table with a different shader 710record buffer. 711In this case, indexing resources based on values in the 712code:ShaderRecordBufferKHR storage class, the index should be decorated as 713code:NonUniform. 714==== 715 716 717[[shader-binding-table-indexing-rules]] 718=== Indexing Rules 719 720In order to execute the correct shaders and access the correct resources 721during a ray tracing dispatch, the implementation must: be able to locate 722shader binding table entries at various stages of execution. 723This is accomplished by defining a set of indexing rules that compute shader 724binding table record positions relative to the buffer's base address in 725memory. 726The application must: organize the contents of the shader binding table's 727memory in a way that application of the indexing rules will lead to correct 728records. 729 730 731==== Ray Generation Shaders 732 733Only one ray generation shader is executed per ray tracing dispatch. 734 735ifdef::VK_KHR_ray_tracing_pipeline[] 736For flink:vkCmdTraceRaysKHR, the location of the ray generation shader is 737specified by the pname:pRaygenShaderBindingTable->deviceAddress parameter 738-- there is no indexing. 739All data accessed must: be less than pname:pRaygenShaderBindingTable->size 740bytes from pname:deviceAddress. 741pname:pRaygenShaderBindingTable->stride is unused, and must: be equal to 742pname:pRaygenShaderBindingTable->size. 743endif::VK_KHR_ray_tracing_pipeline[] 744 745ifdef::VK_NV_ray_tracing[] 746For flink:vkCmdTraceRaysNV, the location of the ray generation shader is 747specified by the pname:raygenShaderBindingTableBuffer and 748pname:raygenShaderBindingOffset parameters -- there is no indexing. 749endif::VK_NV_ray_tracing[] 750 751 752[[shader-binding-table-hit-shader-indexing]] 753==== Hit Shaders 754 755The base for the computation of intersection, any-hit, and closest hit 756shader locations is the code:instanceShaderBindingTableRecordOffset value 757stored with each instance of a top-level acceleration structure 758(slink:VkAccelerationStructureInstanceKHR). 759This value determines the beginning of the shader binding table records for 760a given instance. 761 762In the following rule, code:geometryIndex refers to the 763<<acceleration-structure-geometry-index, geometry index>> of the intersected 764geometry within the instance. 765 766The code:sbtRecordOffset and code:sbtRecordStride values are passed in as 767parameters to 768ifdef::VK_NV_ray_tracing[code:traceNV()] 769ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 770ifdef::VK_KHR_ray_tracing_pipeline[code:traceRayEXT()] 771calls made in the shaders. 772See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language 773Specification for more details. 774In SPIR-V, these correspond to the code:SBTOffset and code:SBTStride 775parameters to the 776ifdef::VK_NV_ray_tracing[code:OpTraceRayNV] 777ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 778ifdef::VK_KHR_ray_tracing_pipeline[code:OpTraceRayKHR] 779ifdef::VK_NV_ray_tracing_motion_blur[ or code:OpTraceRayMotionNV] 780instruction. 781 782The result of this computation is then added to 783ifdef::VK_KHR_ray_tracing_pipeline[] 784pname:pHitShaderBindingTable->deviceAddress, a device address passed to 785flink:vkCmdTraceRaysKHR 786endif::VK_KHR_ray_tracing_pipeline[] 787ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[, or ] 788ifdef::VK_NV_ray_tracing[] 789pname:hitShaderBindingOffset, a base offset passed to flink:vkCmdTraceRaysNV 790endif::VK_NV_ray_tracing[] 791. 792 793ifdef::VK_KHR_ray_tracing_pipeline[] 794For flink:vkCmdTraceRaysKHR, the complete rule to compute a hit shader 795binding table record address in the pname:pHitShaderBindingTable is: 796 797 {empty}:: [eq]#pname:pHitShaderBindingTable->deviceAddress {plus} 798 pname:pHitShaderBindingTable->stride {times} ( 799 code:instanceShaderBindingTableRecordOffset {plus} 800 code:geometryIndex {times} code:sbtRecordStride {plus} 801 code:sbtRecordOffset )# 802 803All data accessed must: be less than pname:pHitShaderBindingTable->size 804bytes from the base address. 805endif::VK_KHR_ray_tracing_pipeline[] 806 807ifdef::VK_NV_ray_tracing[] 808For flink:vkCmdTraceRaysNV, the offset and stride come from direct 809parameters, so the full rule to compute a hit shader binding table record 810address in the pname:hitShaderBindingTableBuffer is: 811 812 {empty}:: [eq]#pname:hitShaderBindingOffset {plus} 813 pname:hitShaderBindingStride {times} ( 814 code:instanceShaderBindingTableRecordOffset {plus} 815 code:geometryIndex {times} code:sbtRecordStride {plus} 816 code:sbtRecordOffset )# 817 818endif::VK_NV_ray_tracing[] 819 820 821==== Miss Shaders 822 823A miss shader is executed whenever a ray query fails to find an intersection 824for the given scene geometry. 825Multiple miss shaders may: be executed throughout a ray tracing dispatch. 826 827The base for the computation of miss shader locations is 828ifdef::VK_KHR_ray_tracing_pipeline[] 829pname:pMissShaderBindingTable->deviceAddress, a device address passed into 830flink:vkCmdTraceRaysKHR 831endif::VK_KHR_ray_tracing_pipeline[] 832ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[, or ] 833ifdef::VK_NV_ray_tracing[] 834pname:missShaderBindingOffset, a base offset passed into 835flink:vkCmdTraceRaysNV 836endif::VK_NV_ray_tracing[] 837. 838 839The code:missIndex value is passed in as a parameter to 840ifdef::VK_NV_ray_tracing[code:traceNV()] 841ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 842ifdef::VK_KHR_ray_tracing_pipeline[code:traceRayEXT()] 843calls made in the shaders. 844See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language 845Specification for more details. 846In SPIR-V, this corresponds to the code:MissIndex parameter to the 847ifdef::VK_NV_ray_tracing[code:OpTraceRayNV] 848ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 849ifdef::VK_KHR_ray_tracing_pipeline[code:OpTraceRayKHR] 850ifdef::VK_NV_ray_tracing_motion_blur[ or code:OpTraceRayMotionNV] 851instruction. 852 853ifdef::VK_KHR_ray_tracing_pipeline[] 854For flink:vkCmdTraceRaysKHR, the complete rule to compute a miss shader 855binding table record address in the pname:pMissShaderBindingTable is: 856 857 {empty}:: [eq]#pname:pMissShaderBindingTable->deviceAddress {plus} 858 pname:pMissShaderBindingTable->stride {times} code:missIndex# 859 860All data accessed must: be less than pname:pMissShaderBindingTable->size 861bytes from the base address. 862endif::VK_KHR_ray_tracing_pipeline[] 863 864ifdef::VK_NV_ray_tracing[] 865For flink:vkCmdTraceRaysNV, the offset and stride come from direct 866parameters, so the full rule to compute a miss shader binding table record 867address in the pname:missShaderBindingTableBuffer is: 868 869 {empty}:: [eq]#pname:missShaderBindingOffset {plus} 870 pname:missShaderBindingStride {times} code:missIndex# 871 872endif::VK_NV_ray_tracing[] 873 874 875==== Callable Shaders 876 877A callable shader is executed when requested by a ray tracing shader. 878Multiple callable shaders may: be executed throughout a ray tracing 879dispatch. 880 881The base for the computation of callable shader locations is 882ifdef::VK_KHR_ray_tracing_pipeline[] 883pname:pCallableShaderBindingTable->deviceAddress, a device address passed 884into flink:vkCmdTraceRaysKHR 885endif::VK_KHR_ray_tracing_pipeline[] 886ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[, or ] 887ifdef::VK_NV_ray_tracing[] 888pname:callableShaderBindingOffset, a base offset passed into 889flink:vkCmdTraceRaysNV 890endif::VK_NV_ray_tracing[] 891. 892 893The code:sbtRecordIndex value is passed in as a parameter to 894ifdef::VK_NV_ray_tracing[code:executeCallableNV()] 895ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 896ifdef::VK_KHR_ray_tracing_pipeline[code:executeCallableEXT()] 897calls made in the shaders. 898See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language 899Specification for more details. 900In SPIR-V, this corresponds to the code:SBTIndex parameter to the 901ifdef::VK_NV_ray_tracing[code:OpExecuteCallableNV] 902ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 903ifdef::VK_KHR_ray_tracing_pipeline[code:OpExecuteCallableKHR] 904instruction. 905 906ifdef::VK_KHR_ray_tracing_pipeline[] 907For flink:vkCmdTraceRaysKHR, the complete rule to compute a callable shader 908binding table record address in the pname:pCallableShaderBindingTable is: 909 910 {empty}:: [eq]#pname:pCallableShaderBindingTable->deviceAddress {plus} 911 pname:pCallableShaderBindingTable->stride {times} 912 code:sbtRecordIndex# 913 914All data accessed must: be less than pname:pCallableShaderBindingTable->size 915bytes from the base address. 916endif::VK_KHR_ray_tracing_pipeline[] 917 918ifdef::VK_NV_ray_tracing[] 919For flink:vkCmdTraceRaysNV, the offset and stride come from direct 920parameters, so the full rule to compute a callable shader binding table 921record address in the pname:callableShaderBindingTableBuffer is: 922 923 {empty}:: [eq]#pname:callableShaderBindingOffset {plus} 924 pname:callableShaderBindingStride {times} code:sbtRecordIndex# 925 926endif::VK_NV_ray_tracing[] 927 928 929[[ray-tracing-pipeline-stack]] 930== Ray Tracing Pipeline Stack 931 932Ray tracing pipelines have a potentially large set of shaders which may: be 933invoked in various call chain combinations to perform ray tracing. 934To store parameters for a given shader execution, an implementation may: use 935a stack of data in memory. 936This stack must: be sized to the sum of the stack sizes of all shaders in 937any call chain executed by the application. 938 939If the stack size is not set explicitly, the stack size for a pipeline is: 940 941 {empty}:: [eq]#rayGenStackMax {plus} min(1, 942 pname:maxPipelineRayRecursionDepth) {times} 943 max(closestHitStackMax, missStackMax, intersectionStackMax 944 {plus} anyHitStackMax) {plus} max(0, 945 pname:maxPipelineRayRecursionDepth-1) {times} 946 max(closestHitStackMax, missStackMax) {plus} 2 {times} 947 callableStackMax# 948 949where [eq]#rayGenStackMax#, [eq]#closestHitStackMax#, [eq]#missStackMax#, 950[eq]#anyHitStackMax#, [eq]#intersectionStackMax#, and [eq]#callableStackMax# 951are the maximum stack values queried by the respective shader stages for any 952shaders in any shader groups defined by the pipeline. 953 954This stack size is potentially significant, so an application may: want to 955provide a more accurate stack size after pipeline compilation. 956The value that the application provides is the maximum value of the sum of 957all shaders in a call chain across all possible call chains, taking into 958account any application specific knowledge about the properties of the call 959chains. 960 961[NOTE] 962.Note 963==== 964For example, if an application has two types of closest hit and miss shaders 965that it can use but the first level of rays will only use the first kind 966(possibly reflection) and the second level will only use the second kind 967(occlusion or shadow ray, for example) then the application can compute the 968stack size by something similar to: 969 970 {empty}:: [eq]#code:rayGenStack {plus} max(code:closestHit1Stack, 971 code:miss1Stack) {plus} max(code:closestHit2Stack, 972 code:miss2Stack)# 973 974This is guaranteed to be no larger than the default stack size computation 975which assumes that both call levels may be the larger of the two. 976==== 977 978 979[[ray-tracing-capture-replay]] 980== Ray Tracing Capture Replay 981 982In a similar way to 983<<features-bufferDeviceAddressCaptureReplay,bufferDeviceAddressCaptureReplay>>, 984the <<features-rayTracingPipelineShaderGroupHandleCaptureReplay, 985pname:rayTracingPipelineShaderGroupHandleCaptureReplay>> feature allows the 986querying of opaque data which can: be used in a future replay. 987 988During the capture phase, capture/replay tools are expected to query opaque 989data for shader group handle replay using 990flink:vkGetRayTracingCaptureReplayShaderGroupHandlesKHR. 991 992Providing the opaque data during replay, using 993slink:VkRayTracingShaderGroupCreateInfoKHR::pname:pShaderGroupCaptureReplayHandle 994at pipeline creation time, causes the implementation to generate identical 995shader group handles to those in the capture phase, allowing capture/replay 996tools to re-use previously recorded shader binding table buffer contents or 997to obtain the same handles by calling 998flink:vkGetRayTracingCaptureReplayShaderGroupHandlesKHR again. 999 1000 1001 1002