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