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