1// Copyright 2018-2021 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. 65 66ifdef::VK_VERSION_1_1[] 67The invocations created by shader call instructions are grouped into 68subgroups by the implementation. 69Those subgroups may: be unrelated to the subgroup of the parent invocation. 70endif::VK_VERSION_1_1[] 71 72 73[[ray-tracing-recursion-depth]] 74_Pipeline trace ray instructions_ can: be used recursively; invoked shaders 75can: themselves execute pipeline trace ray instructions, to a maximum depth 76defined by the 77ifdef::VK_NV_ray_tracing[] 78<<limits-maxRecursionDepth, pname:maxRecursionDepth>> or 79endif::VK_NV_ray_tracing[] 80<<limits-maxRayRecursionDepth, pname:maxRayRecursionDepth>> limit. 81 82Shaders directly invoked from the API always have a recursion depth of 0; 83each shader executed by a pipeline trace ray instruction has a recursion 84depth one higher than the recursion depth of the shader which invoked it. 85Applications must: not invoke a shader with a recursion depth greater than 86the value of 87ifdef::VK_NV_ray_tracing[] 88pname:maxRecursionDepth or 89endif::VK_NV_ray_tracing[] 90pname:maxPipelineRayRecursionDepth specified in the pipeline. 91 92There is no explicit recursion limit for other shader call instructions 93which may recurse (e.g. code:OpExecuteCallableKHR) but there is an upper 94bound determined by the <<ray-tracing-pipeline-stack, stack size>>. 95 96[[ray-tracing-repack]] 97An _invocation repack instruction_ is a ray tracing shader call instruction 98where the implementation may: change the set of invocations that are 99executing. 100When a repack instruction is encountered, the invocation is suspended and a 101new invocation begins and executes the instruction. 102After executing the repack instruction (which may: result in other ray 103tracing shader stages executing) the new invocation ends and the original 104invocation is resumed, but it may: be resumed in a different subgroup or at 105a different code:SubgroupLocalInvocationId within the same subgroup. 106When a subset of invocations in a subgroup execute the invocation repack 107instruction, those that do not execute it remain in the same subgroup at the 108same code:SubgroupLocalInvocationId. 109 110The code:OpTraceRayKHR, 111ifdef::VK_NV_ray_tracing_motion_blur[] 112code:OpTraceRayMotionNV, 113endif::VK_NV_ray_tracing_motion_blur[] 114code:OpReportIntersectionKHR, and code:OpExecuteCallableKHR instructions are 115invocation repack instructions. 116 117ifdef::VK_VERSION_1_1[] 118ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 119The invocations that are executing before an invocation repack instruction, 120after the instruction, or are created by the instruction, are 121<<shader-call-related,shader-call-related>>. 122endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 123 124If the implementation changes the composition of subgroups, the values of 125code:SubgroupSize, code:SubgroupLocalInvocationId, 126ifdef::VK_NV_shader_sm_builtins[] 127code:SMIDNV, code:WarpIDNV, 128endif::VK_NV_shader_sm_builtins[] 129and builtin variables that are derived from them (code:SubgroupEqMask, 130code:SubgroupGeMask, code:SubgroupGtMask, code:SubgroupLeMask, 131code:SubgroupLtMask) must: be changed accordingly by the invocation repack 132instruction. 133The application must: use <<builtin-volatile-semantics,code:Volatile 134semantics>> on these code:BuiltIn variables when used in the ray generation, 135closest hit, miss, intersection, and callable shaders. 136Similarly, the application must: use code:Volatile semantics on any 137code:RayTmaxKHR decorated code:Builtin used in an intersection shader. 138 139[NOTE] 140.Note 141==== 142<<shaders-group-operations,Subgroup operations>> are permitted in the 143programmable ray tracing shader stages. 144However, shader call instructions place a bound on where results of subgroup 145instructions or subgroup-scoped instructions that execute the dynamic 146instance of that instruction are potentially valid. 147For example, care must: be taken when using the result of a ballot operation 148that was computed before an invocation repack instruction, after that repack 149instruction. 150The ballot may: be incorrect as the set of invocations could have changed. 151 152ifdef::VK_EXT_subgroup_size_control[] 153While the code:SubgroupSize built-in is required to be declared 154code:Volatile, its value will never change unless 155ename:VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT is 156set on pipeline creation, as without that bit set, its value is required to 157match that of slink:VkPhysicalDeviceSubgroupProperties::pname:subgroupSize. 158endif::VK_EXT_subgroup_size_control[] 159 160ifdef::VK_KHR_shader_clock[] 161For clock operations, the value of a code:Subgroup scoped 162code:OpReadClockKHR read before the dynamic instance of a repack instruction 163should: not be compared to the result of that clock instruction after the 164repack instruction. 165endif::VK_KHR_shader_clock[] 166==== 167endif::VK_VERSION_1_1[] 168 169ifdef::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 170When a ray tracing shader executes a dynamic instance of an invocation 171repack instruction which results in another ray tracing shader being 172invoked, their instructions are related by 173<<shader-call-order,shader-call-order>>. 174 175For ray tracing invocations that are 176<<shader-call-related,shader-call-related>>: 177 178 * <<memory-model-memory-operation,memory operations>> on 179 code:StorageBuffer, code:Image, and code:ShaderRecordBufferKHR storage 180 classes can: be synchronized using the 181ifdef::VK_KHR_ray_tracing_pipeline[code:ShaderCallKHR] 182ifndef::VK_KHR_ray_tracing_pipeline[code:Device or code:QueueFamily] 183 scope. 184 185 * the code:CallableDataKHR, code:IncomingCallableDataKHR, 186 code:RayPayloadKHR, code:HitAttributeKHR, and code:IncomingRayPayloadKHR 187 storage classes are <<memory-model-shader-io,system-synchronized>> and 188 no application availability and visibility operations are required. 189 190 * memory operations within a single invocation before and after the 191 invocation repack instruction are ordered by 192 <<memory-model-program-order,program-order>> and do not require explicit 193 synchronzation. 194endif::VK_VERSION_1_2,VK_KHR_vulkan_memory_model[] 195 196 197[[ray-tracing-commands]] 198== Ray Tracing Commands 199 200_Ray tracing commands_ provoke work in the ray tracing pipeline. 201Ray tracing commands are recorded into a command buffer and when executed by 202a queue will produce work that executes according to the currently bound ray 203tracing pipeline. 204A ray tracing pipeline must: be bound to a command buffer before any ray 205tracing commands are recorded in that command buffer. 206 207ifdef::VK_NV_ray_tracing[] 208 209[open,refpage='vkCmdTraceRaysNV',desc='Initialize a ray tracing dispatch',type='protos'] 210-- 211:refpage: vkCmdTraceRaysNV 212 213To dispatch ray tracing use: 214 215include::{generated}/api/protos/vkCmdTraceRaysNV.txt[] 216 217 * pname:commandBuffer is the command buffer into which the command will be 218 recorded. 219 * pname:raygenShaderBindingTableBuffer is the buffer object that holds the 220 shader binding table data for the ray generation shader stage. 221 * pname:raygenShaderBindingOffset is the offset in bytes (relative to 222 pname:raygenShaderBindingTableBuffer) of the ray generation shader being 223 used for the trace. 224 * pname:missShaderBindingTableBuffer is the buffer object that holds the 225 shader binding table data for the miss shader stage. 226 * pname:missShaderBindingOffset is the offset in bytes (relative to 227 pname:missShaderBindingTableBuffer) of the miss shader being used for 228 the trace. 229 * pname:missShaderBindingStride is the size in bytes of each shader 230 binding table record in pname:missShaderBindingTableBuffer. 231 * pname:hitShaderBindingTableBuffer is the buffer object that holds the 232 shader binding table data for the hit shader stages. 233 * pname:hitShaderBindingOffset is the offset in bytes (relative to 234 pname:hitShaderBindingTableBuffer) of the hit shader group being used 235 for the trace. 236 * pname:hitShaderBindingStride is the size in bytes of each shader binding 237 table record in pname:hitShaderBindingTableBuffer. 238 * pname:callableShaderBindingTableBuffer is the buffer object that holds 239 the shader binding table data for the callable shader stage. 240 * pname:callableShaderBindingOffset is the offset in bytes (relative to 241 pname:callableShaderBindingTableBuffer) of the callable shader being 242 used for the trace. 243 * pname:callableShaderBindingStride is the size in bytes of each shader 244 binding table record in pname:callableShaderBindingTableBuffer. 245 * pname:width is the width of the ray trace query dimensions. 246 * pname:height is height of the ray trace query dimensions. 247 * pname:depth is depth of the ray trace query dimensions. 248 249When the command is executed, a ray generation group of [eq]#pname:width 250{times} pname:height {times} pname:depth# rays is assembled. 251 252.Valid Usage 253**** 254include::{chapters}/commonvalidity/trace_rays_common.txt[] 255 * [[VUID-vkCmdTraceRaysNV-commandBuffer-04624]] 256 pname:commandBuffer must: not be a protected command buffer 257 * [[VUID-vkCmdTraceRaysNV-maxRecursionDepth-03625]] 258 This command must: not cause a pipeline trace ray instruction to be 259 executed from a shader invocation with a <<ray-tracing-recursion-depth, 260 recursion depth>> greater than the value of pname:maxRecursionDepth used 261 to create the bound ray tracing pipeline 262 * [[VUID-vkCmdTraceRaysNV-raygenShaderBindingTableBuffer-04042]] 263 If pname:raygenShaderBindingTableBuffer is non-sparse then it must: be 264 bound completely and contiguously to a single sname:VkDeviceMemory 265 object 266 * [[VUID-vkCmdTraceRaysNV-raygenShaderBindingOffset-02455]] 267 pname:raygenShaderBindingOffset must: be less than the size of 268 pname:raygenShaderBindingTableBuffer 269 * [[VUID-vkCmdTraceRaysNV-raygenShaderBindingOffset-02456]] 270 pname:raygenShaderBindingOffset must: be a multiple of 271 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 272 * [[VUID-vkCmdTraceRaysNV-missShaderBindingTableBuffer-04043]] 273 If pname:missShaderBindingTableBuffer is non-sparse then it must: be 274 bound completely and contiguously to a single sname:VkDeviceMemory 275 object 276 * [[VUID-vkCmdTraceRaysNV-missShaderBindingOffset-02457]] 277 pname:missShaderBindingOffset must: be less than the size of 278 pname:missShaderBindingTableBuffer 279 * [[VUID-vkCmdTraceRaysNV-missShaderBindingOffset-02458]] 280 pname:missShaderBindingOffset must: be a multiple of 281 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 282 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingTableBuffer-04044]] 283 If pname:hitShaderBindingTableBuffer is non-sparse then it must: be 284 bound completely and contiguously to a single sname:VkDeviceMemory 285 object 286 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingOffset-02459]] 287 pname:hitShaderBindingOffset must: be less than the size of 288 pname:hitShaderBindingTableBuffer 289 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingOffset-02460]] 290 pname:hitShaderBindingOffset must: be a multiple of 291 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 292 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingTableBuffer-04045]] 293 If pname:callableShaderBindingTableBuffer is non-sparse then it must: be 294 bound completely and contiguously to a single sname:VkDeviceMemory 295 object 296 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingOffset-02461]] 297 pname:callableShaderBindingOffset must: be less than the size of 298 pname:callableShaderBindingTableBuffer 299 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingOffset-02462]] 300 pname:callableShaderBindingOffset must: be a multiple of 301 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupBaseAlignment 302 * [[VUID-vkCmdTraceRaysNV-missShaderBindingStride-02463]] 303 pname:missShaderBindingStride must: be a multiple of 304 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupHandleSize 305 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingStride-02464]] 306 pname:hitShaderBindingStride must: be a multiple of 307 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupHandleSize 308 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingStride-02465]] 309 pname:callableShaderBindingStride must: be a multiple of 310 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:shaderGroupHandleSize 311 * [[VUID-vkCmdTraceRaysNV-missShaderBindingStride-02466]] 312 pname:missShaderBindingStride must: be less than or equal to 313 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxShaderGroupStride 314 * [[VUID-vkCmdTraceRaysNV-hitShaderBindingStride-02467]] 315 pname:hitShaderBindingStride must: be less than or equal to 316 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxShaderGroupStride 317 * [[VUID-vkCmdTraceRaysNV-callableShaderBindingStride-02468]] 318 pname:callableShaderBindingStride must: be less than or equal to 319 sname:VkPhysicalDeviceRayTracingPropertiesNV::pname:maxShaderGroupStride 320 * [[VUID-vkCmdTraceRaysNV-width-02469]] 321 pname:width must: be less than or equal to 322 sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0] 323 * [[VUID-vkCmdTraceRaysNV-height-02470]] 324 pname:height must: be less than or equal to 325 sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1] 326 * [[VUID-vkCmdTraceRaysNV-depth-02471]] 327 pname:depth must: be less than or equal to 328 sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2] 329**** 330 331include::{generated}/validity/protos/vkCmdTraceRaysNV.txt[] 332-- 333 334endif::VK_NV_ray_tracing[] 335 336ifdef::VK_KHR_ray_tracing_pipeline[] 337[open,refpage='vkCmdTraceRaysKHR',desc='Initialize a ray tracing dispatch',type='protos'] 338-- 339:refpage: vkCmdTraceRaysKHR 340 341To dispatch ray tracing use: 342 343include::{generated}/api/protos/vkCmdTraceRaysKHR.txt[] 344 345 * pname:commandBuffer is the command buffer into which the command will be 346 recorded. 347 * pname:pRaygenShaderBindingTable is a 348 slink:VkStridedDeviceAddressRegionKHR that holds the shader binding 349 table data for the ray generation shader stage. 350 * pname:pMissShaderBindingTable is a slink:VkStridedDeviceAddressRegionKHR 351 that holds the shader binding table data for the miss shader stage. 352 * pname:pHitShaderBindingTable is a slink:VkStridedDeviceAddressRegionKHR 353 that holds the shader binding table data for the hit shader stage. 354 * pname:pCallableShaderBindingTable is a 355 slink:VkStridedDeviceAddressRegionKHR that holds the shader binding 356 table data for the callable shader stage. 357 * pname:width is the width of the ray trace query dimensions. 358 * pname:height is height of the ray trace query dimensions. 359 * pname:depth is depth of the ray trace query dimensions. 360 361When the command is executed, a ray generation group of [eq]#pname:width 362{times} pname:height {times} pname:depth# rays is assembled. 363 364.Valid Usage 365**** 366include::{chapters}/commonvalidity/trace_rays_common.txt[] 367include::{chapters}/commonvalidity/trace_rays_common_khr.txt[] 368 * [[VUID-vkCmdTraceRaysKHR-commandBuffer-04625]] 369 pname:commandBuffer must: not be a protected command buffer 370 * [[VUID-vkCmdTraceRaysKHR-width-03626]] 371 pname:width must: be less than or equal to 372 [eq]#sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0] 373 {times} sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[0]# 374 * [[VUID-vkCmdTraceRaysKHR-height-03627]] 375 pname:height must: be less than or equal to 376 [eq]#sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1] 377 {times} sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[1]# 378 * [[VUID-vkCmdTraceRaysKHR-depth-03628]] 379 pname:depth must: be less than or equal to 380 [eq]#sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2] 381 {times} sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[2]# 382 * [[VUID-vkCmdTraceRaysKHR-width-03629]] 383 [eq]#pname:width {times} pname:height {times} pname:depth# must: be less 384 than or equal to 385 sname:VkPhysicalDeviceRayTracingPipelinePropertiesKHR::pname:maxRayDispatchInvocationCount 386**** 387 388include::{generated}/validity/protos/vkCmdTraceRaysKHR.txt[] 389-- 390 391[open,refpage='VkStridedDeviceAddressRegionKHR',desc='Structure specifying a region of device addresses with a stride',type='structs'] 392-- 393:refpage: VkStridedDeviceAddressRegionKHR 394 395The sname:VkStridedDeviceAddressRegionKHR structure is defined as: 396 397include::{generated}/api/structs/VkStridedDeviceAddressRegionKHR.txt[] 398 399 * pname:deviceAddress is the device address (as returned by the 400 flink:vkGetBufferDeviceAddress command) at which the region starts, or 401 zero if the region is unused. 402 * pname:stride is the byte stride between consecutive elements. 403 * pname:size is the size in bytes of the region starting at 404 pname:deviceAddress. 405 406.Valid Usage 407**** 408 * [[VUID-VkStridedDeviceAddressRegionKHR-size-04631]] 409 If pname:size is not zero, all addresses between pname:deviceAddress and 410 [eq]#pname:deviceAddress {plus} pname:size - 1# must: be in the buffer 411 device address range of the same buffer 412 * [[VUID-VkStridedDeviceAddressRegionKHR-size-04632]] 413 If pname:size is not zero, pname:stride must: be less than or equal to 414 the size of the buffer from which pname:deviceAddress was queried 415**** 416 417include::{generated}/validity/structs/VkStridedDeviceAddressRegionKHR.txt[] 418-- 419 420ifdef::VK_HUAWEI_invocation_mask[] 421 422[open,refpage='vkCmdBindInvocationMaskHUAWEI',desc='Bind an invocation mask image on a command buffer',type='protos'] 423-- 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.txt[] 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,invocation mask image>> 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.txt[] 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.txt[] 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.txt[] 503include::{chapters}/commonvalidity/trace_rays_common_khr.txt[] 504 * [[VUID-vkCmdTraceRaysIndirectKHR-indirectDeviceAddress-03632]] 505 If the buffer from which pname:indirectDeviceAddress was queried is 506 non-sparse then it must: be bound completely and contiguously to a 507 single sname:VkDeviceMemory object 508 * [[VUID-vkCmdTraceRaysIndirectKHR-indirectDeviceAddress-03633]] 509 The buffer from which pname:indirectDeviceAddress was queried must: have 510 been created with the ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set 511 * [[VUID-vkCmdTraceRaysIndirectKHR-indirectDeviceAddress-03634]] 512 pname:indirectDeviceAddress must: be a multiple of `4` 513 * [[VUID-vkCmdTraceRaysIndirectKHR-commandBuffer-03635]] 514 pname:commandBuffer must: not be a protected command buffer 515 * [[VUID-vkCmdTraceRaysIndirectKHR-indirectDeviceAddress-03636]] 516 All device addresses between pname:indirectDeviceAddress and 517 [eq]#pname:indirectDeviceAddress {plus} 518 code:sizeof(sname:VkTraceRaysIndirectCommandKHR) - 1# must: be in the 519 buffer device address range of the same buffer 520 * [[VUID-vkCmdTraceRaysIndirectKHR-rayTracingPipelineTraceRaysIndirect-03637]] 521 The <<features-rayTracingPipelineTraceRaysIndirect, 522 sname:VkPhysicalDeviceRayTracingPipelineFeaturesKHR::pname:rayTracingPipelineTraceRaysIndirect>> 523 feature must: be enabled 524ifdef::VK_NV_ray_tracing_motion_blur[] 525 * [[VUID-vkCmdTraceRaysIndirectKHR-rayTracingMotionBlurPipelineTraceRaysIndirect-04951]] 526 If the bound ray tracing pipeline was created with 527 ename:VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV 528 sname:VkPhysicalDeviceRayTracingMotionBlurFeaturesNV::pname:rayTracingMotionBlurPipelineTraceRaysIndirect 529 feature must: be enabled 530endif::VK_NV_ray_tracing_motion_blur[] 531**** 532 533include::{generated}/validity/protos/vkCmdTraceRaysIndirectKHR.txt[] 534-- 535 536[open,refpage='VkTraceRaysIndirectCommandKHR',desc='Structure specifying the parameters of an indirect ray tracing command',type='structs'] 537-- 538:refpage: VkTraceRaysIndirectCommandKHR 539 540The sname:VkTraceRaysIndirectCommandKHR structure is defined as: 541 542include::{generated}/api/structs/VkTraceRaysIndirectCommandKHR.txt[] 543 544 * pname:width is the width of the ray trace query dimensions. 545 * pname:height is height of the ray trace query dimensions. 546 * pname:depth is depth of the ray trace query dimensions. 547 548The members of sname:VkTraceRaysIndirectCommandKHR have the same meaning as 549the similarly named parameters of flink:vkCmdTraceRaysKHR. 550 551.Valid Usage 552**** 553 * [[VUID-VkTraceRaysIndirectCommandKHR-width-03638]] 554 pname:width must: be less than or equal to 555 [eq]#sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0] 556 {times} sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[0]# 557 * [[VUID-VkTraceRaysIndirectCommandKHR-height-03639]] 558 pname:height must: be less than or equal to 559 [eq]#sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1] 560 {times} sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[1]# 561 * [[VUID-VkTraceRaysIndirectCommandKHR-depth-03640]] 562 pname:depth must: be less than or equal to 563 [eq]#sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2] 564 {times} sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupSize[2]# 565 * [[VUID-VkTraceRaysIndirectCommandKHR-width-03641]] 566 [eq]#pname:width {times} pname:height {times} pname:depth# must: be less 567 than or equal to 568 sname:VkPhysicalDeviceRayTracingPipelinePropertiesKHR::pname:maxRayDispatchInvocationCount 569**** 570 571include::{generated}/validity/structs/VkTraceRaysIndirectCommandKHR.txt[] 572-- 573endif::VK_KHR_ray_tracing_pipeline[] 574 575 576[[shader-binding-table]] 577== Shader Binding Table 578 579A _shader binding table_ is a resource which establishes the relationship 580between the ray tracing pipeline and the acceleration structures that were 581built for the ray tracing pipeline. 582It indicates the shaders that operate on each geometry in an acceleration 583structure. 584In addition, it contains the resources accessed by each shader, including 585indices of textures, buffer device addresses, and constants. 586The application allocates and manages _shader binding tables_ as 587slink:VkBuffer objects. 588 589Each entry in the shader binding table consists of 590pname:shaderGroupHandleSize bytes of data, either as queried by 591flink:vkGetRayTracingShaderGroupHandlesKHR to refer to those specified 592shaders, or all zeros to refer to a zero shader group. 593A zero shader group behaves as though it is a shader group consisting 594entirely of ename:VK_SHADER_UNUSED_KHR. 595The remainder of the data specified by the stride is application-visible 596data that can be referenced by a code:ShaderRecordBufferKHR block in the 597shader. 598 599The shader binding tables to use in a ray tracing pipeline are passed to the 600ifdef::VK_NV_ray_tracing[] 601flink:vkCmdTraceRaysNV, 602endif::VK_NV_ray_tracing[] 603flink:vkCmdTraceRaysKHR, or flink:vkCmdTraceRaysIndirectKHR commands. 604Shader binding tables are read-only in shaders that are executing on the ray 605tracing pipeline. 606 607Shader variables identified with the code:ShaderRecordBufferKHR storage 608class are used to access the provided shader binding table. 609Such variables must: be: 610 611 * typed as code:OpTypeStruct, or an array of this type, 612 * identified with a code:Block decoration, and 613 * laid out explicitly using the code:Offset, code:ArrayStride, and 614 code:MatrixStride decorations as specified in 615 <<interfaces-resources-layout,Offset and Stride Assignment>>. 616 617The code:Offset decoration for any member of a code:Block-decorated variable 618in the code:ShaderRecordBufferKHR storage class must: not cause the space 619required for that variable to extend outside the range [eq]#[0, 620pname:maxStorageBufferRange)#. 621 622Accesses to the shader binding table from ray tracing pipelines must: be 623<<synchronization-dependencies,synchronized>> with the 624ename:VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR 625<<synchronization-pipeline-stages, pipeline stage>> and an 626<<synchronization-access-types, access type>> of 627ename:VK_ACCESS_SHADER_READ_BIT. 628 629[NOTE] 630.Note 631==== 632Because different shader record buffers can be associated with the same 633shader, a shader variable with code:ShaderRecordBufferKHR storage class will 634not be dynamically uniform if different invocations of the same shader can 635reference different data in the shader record buffer, such as if the same 636shader occurs twice in the shader binding table with a different shader 637record buffer. 638In this case, indexing resources based on values in the 639code:ShaderRecordBufferKHR storage class, the index should be decorated as 640code:NonUniform. 641==== 642 643[[shader-binding-table-indexing-rules]] 644=== Indexing Rules 645 646In order to execute the correct shaders and access the correct resources 647during a ray tracing dispatch, the implementation must: be able to locate 648shader binding table entries at various stages of execution. 649This is accomplished by defining a set of indexing rules that compute shader 650binding table record positions relative to the buffer's base address in 651memory. 652The application must: organize the contents of the shader binding table's 653memory in a way that application of the indexing rules will lead to correct 654records. 655 656 657==== Ray Generation Shaders 658 659Only one ray generation shader is executed per ray tracing dispatch. 660 661ifdef::VK_KHR_ray_tracing_pipeline[] 662For flink:vkCmdTraceRaysKHR, the location of the ray generation shader is 663specified by the pname:pRaygenShaderBindingTable->deviceAddress parameter 664-- there is no indexing. 665All data accessed must: be less than pname:pRaygenShaderBindingTable->size 666bytes from pname:deviceAddress. 667pname:pRaygenShaderBindingTable->stride is unused, and must: be equal to 668pname:pRaygenShaderBindingTable->size. 669endif::VK_KHR_ray_tracing_pipeline[] 670 671ifdef::VK_NV_ray_tracing[] 672For flink:vkCmdTraceRaysNV, the location of the ray generation shader is 673specified by the pname:raygenShaderBindingTableBuffer and 674pname:raygenShaderBindingOffset parameters -- there is no indexing. 675endif::VK_NV_ray_tracing[] 676 677 678[[shader-binding-table-hit-shader-indexing]] 679==== Hit Shaders 680 681The base for the computation of intersection, any-hit, and closest hit 682shader locations is the code:instanceShaderBindingTableRecordOffset value 683stored with each instance of a top-level acceleration structure 684(slink:VkAccelerationStructureInstanceKHR). 685This value determines the beginning of the shader binding table records for 686a given instance. 687 688In the following rule, code:geometryIndex refers to the 689<<acceleration-structure-geometry-index, geometry index>> of the intersected 690geometry within the instance. 691 692The code:sbtRecordOffset and code:sbtRecordStride values are passed in as 693parameters to 694ifdef::VK_NV_ray_tracing[code:traceNV()] 695ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 696ifdef::VK_KHR_ray_tracing_pipeline[code:traceRayEXT()] 697calls made in the shaders. 698See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language 699Specification for more details. 700In SPIR-V, these correspond to the code:SBTOffset and code:SBTStride 701parameters to the 702ifdef::VK_NV_ray_tracing[code:OpTraceRayNV] 703ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 704ifdef::VK_KHR_ray_tracing_pipeline[code:OpTraceRayKHR] 705ifdef::VK_NV_ray_tracing_motion_blur[ or code:OpTraceRayMotionNV] 706instruction. 707 708The result of this computation is then added to 709ifdef::VK_KHR_ray_tracing_pipeline[] 710pname:pHitShaderBindingTable->deviceAddress, a device address passed to 711flink:vkCmdTraceRaysKHR 712endif::VK_KHR_ray_tracing_pipeline[] 713ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[, or ] 714ifdef::VK_NV_ray_tracing[] 715pname:hitShaderBindingOffset, a base offset passed to flink:vkCmdTraceRaysNV 716endif::VK_NV_ray_tracing[] 717. 718 719ifdef::VK_KHR_ray_tracing_pipeline[] 720For flink:vkCmdTraceRaysKHR, the complete rule to compute a hit shader 721binding table record address in the pname:pHitShaderBindingTable is: 722 723 {empty}:: [eq]#pname:pHitShaderBindingTable->deviceAddress {plus} 724 pname:pHitShaderBindingTable->stride {times} ( 725 code:instanceShaderBindingTableRecordOffset {plus} 726 code:geometryIndex {times} code:sbtRecordStride {plus} 727 code:sbtRecordOffset )# 728 729All data accessed must: be less than pname:pHitShaderBindingTable->size 730bytes from the base address. 731endif::VK_KHR_ray_tracing_pipeline[] 732 733ifdef::VK_NV_ray_tracing[] 734For flink:vkCmdTraceRaysNV, the offset and stride come from direct 735parameters, so the full rule to compute a hit shader binding table record 736address in the pname:hitShaderBindingTableBuffer is: 737 738 {empty}:: [eq]#pname:hitShaderBindingOffset {plus} 739 pname:hitShaderBindingStride {times} ( 740 code:instanceShaderBindingTableRecordOffset {plus} 741 code:geometryIndex {times} code:sbtRecordStride {plus} 742 code:sbtRecordOffset )# 743 744endif::VK_NV_ray_tracing[] 745 746 747==== Miss Shaders 748 749A miss shader is executed whenever a ray query fails to find an intersection 750for the given scene geometry. 751Multiple miss shaders may: be executed throughout a ray tracing dispatch. 752 753The base for the computation of miss shader locations is 754ifdef::VK_KHR_ray_tracing_pipeline[] 755pname:pMissShaderBindingTable->deviceAddress, a device address passed into 756flink:vkCmdTraceRaysKHR 757endif::VK_KHR_ray_tracing_pipeline[] 758ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[, or ] 759ifdef::VK_NV_ray_tracing[] 760pname:missShaderBindingOffset, a base offset passed into 761flink:vkCmdTraceRaysNV 762endif::VK_NV_ray_tracing[] 763. 764 765The code:missIndex value is passed in as a parameter to 766ifdef::VK_NV_ray_tracing[code:traceNV()] 767ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 768ifdef::VK_KHR_ray_tracing_pipeline[code:traceRayEXT()] 769calls made in the shaders. 770See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language 771Specification for more details. 772In SPIR-V, this corresponds to the code:MissIndex parameter to the 773ifdef::VK_NV_ray_tracing[code:OpTraceRayNV] 774ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 775ifdef::VK_KHR_ray_tracing_pipeline[code:OpTraceRayKHR] 776ifdef::VK_NV_ray_tracing_motion_blur[ or code:OpTraceRayMotionNV] 777instruction. 778 779ifdef::VK_KHR_ray_tracing_pipeline[] 780For flink:vkCmdTraceRaysKHR, the complete rule to compute a miss shader 781binding table record address in the pname:pMissShaderBindingTable is: 782 783 {empty}:: [eq]#pname:pMissShaderBindingTable->deviceAddress {plus} 784 pname:pMissShaderBindingTable->stride {times} code:missIndex# 785 786All data accessed must: be less than pname:pMissShaderBindingTable->size 787bytes from the base address. 788endif::VK_KHR_ray_tracing_pipeline[] 789 790ifdef::VK_NV_ray_tracing[] 791For flink:vkCmdTraceRaysNV, the offset and stride come from direct 792parameters, so the full rule to compute a miss shader binding table record 793address in the pname:missShaderBindingTableBuffer is: 794 795 {empty}:: [eq]#pname:missShaderBindingOffset {plus} 796 pname:missShaderBindingStride {times} code:missIndex# 797 798endif::VK_NV_ray_tracing[] 799 800 801==== Callable Shaders 802 803A callable shader is executed when requested by a ray tracing shader. 804Multiple callable shaders may: be executed throughout a ray tracing 805dispatch. 806 807The base for the computation of callable shader locations is 808ifdef::VK_KHR_ray_tracing_pipeline[] 809pname:pCallableShaderBindingTable->deviceAddress, a device address passed 810into flink:vkCmdTraceRaysKHR 811endif::VK_KHR_ray_tracing_pipeline[] 812ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[, or ] 813ifdef::VK_NV_ray_tracing[] 814pname:callableShaderBindingOffset, a base offset passed into 815flink:vkCmdTraceRaysNV 816endif::VK_NV_ray_tracing[] 817. 818 819The code:sbtRecordIndex value is passed in as a parameter to 820ifdef::VK_NV_ray_tracing[code:executeCallableNV()] 821ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 822ifdef::VK_KHR_ray_tracing_pipeline[code:executeCallableEXT()] 823calls made in the shaders. 824See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language 825Specification for more details. 826In SPIR-V, this corresponds to the code:SBTIndex parameter to the 827ifdef::VK_NV_ray_tracing[code:OpExecuteCallableNV] 828ifdef::VK_NV_ray_tracing+VK_KHR_ray_tracing_pipeline[ or ] 829ifdef::VK_KHR_ray_tracing_pipeline[code:OpExecuteCallableKHR] 830instruction. 831 832ifdef::VK_KHR_ray_tracing_pipeline[] 833For flink:vkCmdTraceRaysKHR, the complete rule to compute a callable shader 834binding table record address in the pname:pCallableShaderBindingTable is: 835 836 {empty}:: [eq]#pname:pCallableShaderBindingTable->deviceAddress {plus} 837 pname:pCallableShaderBindingTable->stride {times} 838 code:sbtRecordIndex# 839 840All data accessed must: be less than pname:pCallableShaderBindingTable->size 841bytes from the base address. 842endif::VK_KHR_ray_tracing_pipeline[] 843 844ifdef::VK_NV_ray_tracing[] 845For flink:vkCmdTraceRaysNV, the offset and stride come from direct 846parameters, so the full rule to compute a callable shader binding table 847record address in the pname:callableShaderBindingTableBuffer is: 848 849 {empty}:: [eq]#pname:callableShaderBindingOffset {plus} 850 pname:callableShaderBindingStride {times} code:sbtRecordIndex# 851 852endif::VK_NV_ray_tracing[] 853 854 855[[ray-tracing-pipeline-stack]] 856== Ray Tracing Pipeline Stack 857 858Ray tracing pipelines have a potentially large set of shaders which may: be 859invoked in various call chain combinations to perform ray tracing. 860To store parameters for a given shader execution, an implementation may: use 861a stack of data in memory. 862This stack must: be sized to the sum of the stack sizes of all shaders in 863any call chain executed by the application. 864 865If the stack size is not set explicitly, the stack size for a pipeline is: 866 867 {empty}:: [eq]#rayGenStackMax {plus} min(1, 868 pname:maxPipelineRayRecursionDepth) {times} 869 max(closestHitStackMax, missStackMax, intersectionStackMax 870 {plus} anyHitStackMax) {plus} max(0, 871 pname:maxPipelineRayRecursionDepth-1) {times} 872 max(closestHitStackMax, missStackMax) {plus} 2 {times} 873 callableStackMax# 874 875where [eq]#rayGenStackMax#, [eq]#closestHitStackMax#, [eq]#missStackMax#, 876[eq]#anyHitStackMax#, [eq]#intersectionStackMax#, and [eq]#callableStackMax# 877are the maximum stack values queried by the respective shader stages for any 878shaders in any shader groups defined by the pipeline. 879 880This stack size is potentially significant, so an application may: want to 881provide a more accurate stack size after pipeline compilation. 882The value that the application provides is the maximum value of the sum of 883all shaders in a call chain across all possible call chains, taking into 884account any application specific knowledge about the properties of the call 885chains. 886 887[NOTE] 888.Note 889==== 890For example, if an application has two types of closest hit and miss shaders 891that it can use but the first level of rays will only use the first kind 892(possibly reflection) and the second level will only use the second kind 893(occlusion or shadow ray, for example) then the application can compute the 894stack size by something similar to: 895 896 {empty}:: [eq]#code:rayGenStack {plus} max(code:closestHit1Stack, 897 code:miss1Stack) {plus} max(code:closestHit2Stack, 898 code:miss2Stack)# 899 900This is guaranteed to be no larger than the default stack size computation 901which assumes that both call levels may be the larger of the two. 902==== 903