• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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