32. Ray Tracing

Unlike draw commands which use rasterization, ray tracing is a rendering method which generates an image by tracing the path of rays which have a single origin and using shaders to determine the final colour of an image plane.

Ray tracing uses a separate rendering pipeline from both the graphics and compute pipelines (see Ray tracing Pipeline). It has a unique set of programmable and fixed function stages.

image/svg+xmlRay Generation traceNV() Acceleration Structure Traversal Hit? Miss Closest Hit Intersection Any Hit yesno
Figure 33. Ray tracing Pipeline
Caption

Interaction between the different shader stages in the ray tracing pipeline

32.1. Ray Tracing Commands

Ray tracing commands provoke work in the raytacing pipeline. Ray tracing commands are recorded into a command buffer and when executed by a queue will produce work which executes according to the currently bound ray tracing pipeline. A ray tracing pipeline must be bound to a command buffer before any ray tracing commands are recorded in that command buffer.

Each ray tracing call operates on a set of shader stages that are specific to the ray tracing pipeline as well as a set of VkAccelerationStructureNV objects which describe the scene geometry in an implementation-specific way. The relationship between the ray tracing pipeline object and the acceleration structures is passed into the raytacing command in a VkBuffer object known as a shader binding table.

During execution, control alternates between scheduling and other operations. The scheduling functionality is implementation-specific and is responsible for workload execution. The shader stages are programmable. Traversal, which refers to the process of traversing acceleration structures to find potential intersections of rays with geometry, is fixed function.

The programmable portions of the pipeline are exposed in a single-ray programming model. Each GPU thread handles one ray at a time. Memory operations can be synchronized using standard memory barriers. However, communication and synchronization between threads is not allowed. In particular, the use of compute pipeline synchronization functions is not supported in the ray tracing pipeline.

To dispatch a ray tracing call use:

void vkCmdTraceRaysNV(
    VkCommandBuffer                             commandBuffer,
    VkBuffer                                    raygenShaderBindingTableBuffer,
    VkDeviceSize                                raygenShaderBindingOffset,
    VkBuffer                                    missShaderBindingTableBuffer,
    VkDeviceSize                                missShaderBindingOffset,
    VkDeviceSize                                missShaderBindingStride,
    VkBuffer                                    hitShaderBindingTableBuffer,
    VkDeviceSize                                hitShaderBindingOffset,
    VkDeviceSize                                hitShaderBindingStride,
    VkBuffer                                    callableShaderBindingTableBuffer,
    VkDeviceSize                                callableShaderBindingOffset,
    VkDeviceSize                                callableShaderBindingStride,
    uint32_t                                    width,
    uint32_t                                    height,
    uint32_t                                    depth);
  • commandBuffer is the command buffer into which the command will be recorded.

  • raygenShaderBindingTableBuffer is the buffer object that holds the shader binding table data for the ray generation shader stage.

  • raygenShaderBindingOffset is the offset in bytes (relative to raygenShaderBindingTableBuffer) of the ray generation shader being used for the trace.

  • missShaderBindingTableBuffer is the buffer object that holds the shader binding table data for the miss shader stage.

  • missShaderBindingOffset is the offset in bytes (relative to missShaderBindingTableBuffer) of the miss shader being used for the trace.

  • missShaderBindingStride is the size in bytes of each shader binding table record in missShaderBindingTableBuffer

  • hitShaderBindingTableBuffer is the buffer object that holds the shader binding table data for the hit shader stages.

  • hitShaderBindingOffset is the offset in bytes (relative to hitShaderBindingTableBuffer) of the hit shader group being used for the trace.

  • hitShaderBindingStride is the size in bytes of each shader binding table record in hitShaderBindingTableBuffer

  • callableShaderBindingTableBuffer is the buffer object that holds the shader binding table data for the callable shader stage.

  • callableShaderBindingOffset is the offset in bytes (relative to callableShaderBindingTableBuffer) of the callable shader being used for the trace.

  • callableShaderBindingStride is the size in bytes of each shader binding table record in callableShaderBindingTableBuffer

  • width is the width of the ray trace query dimensions.

  • height is height of the ray trace query dimensions.

  • depth is depth of the ray trace query dimensions.

When the command is executed, a ray generation group of width × height × depth rays is assembled.

Valid Usage
  • raygenShaderBindingOffset must be less than the size of raygenShaderBindingTableBuffer

  • raygenShaderBindingOffset must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupBaseAlignment.

  • missShaderBindingOffset must be less than the size of missShaderBindingTableBuffer

  • missShaderBindingOffset must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupBaseAlignment.

  • hitShaderBindingOffset must be less than the size of hitShaderBindingTableBuffer

  • hitShaderBindingOffset must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupBaseAlignment.

  • callableShaderBindingOffset must be less than the size of callableShaderBindingTableBuffer

  • callableShaderBindingOffset must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupBaseAlignment.

  • missShaderBindingStride must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupHandleSize

  • hitShaderBindingStride must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupHandleSize

  • callableShaderBindingStride must be a multiple of VkPhysicalDeviceRayTracingPropertiesNV::shaderGroupHandleSize

  • missShaderBindingStride must be a less than or equal to VkPhysicalDeviceRayTracingPropertiesNV::maxShaderGroupStride

  • hitShaderBindingStride must be a less than or equal to VkPhysicalDeviceRayTracingPropertiesNV::maxShaderGroupStride

  • callableShaderBindingStride must be a less than or equal to VkPhysicalDeviceRayTracingPropertiesNV::maxShaderGroupStride

  • width must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[0]

  • height must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[1]

  • depth must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[2]

  • For each set n that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the bound VkPipeline object, specified via vkCmdBindPipeline

  • A valid ray tracing pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_RAY_TRACING_NV

  • For each push constant that is statically used by the VkPipeline bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, a push constant value must have been set for VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, with a VkPipelineLayout that is compatible for push constants with the one used to create the current VkPipeline, as described in Pipeline Layout Compatibility

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage

  • If any VkSampler object that is accessed from a shader by the VkPipeline bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the bound descriptor set

  • If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV accesses a storage buffer, it must not access values outside of the range of that buffer specified in the bound descriptor set

  • If a VkImageView is sampled with with VK_FILTER_LINEAR as a result of this command, then the image view’s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

  • If a VkImageView is sampled with with VK_FILTER_CUBIC_IMG as a result of this command, then the image view’s format features must contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG.

  • Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY

  • If commandBuffer is an unprotected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV reads from or writes to any image or buffer, that image or buffer must not be a protected image or protected buffer.

  • If commandBuffer is a protected command buffer, and any pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV writes to any image or buffer, that image or buffer must not be an unprotected image or unprotected buffer.

  • If commandBuffer is a protected command buffer, and any pipeline stage other than the ray tracing pipeline stage in the VkPipeline object bound to VK_PIPELINE_BIND_POINT_RAY_TRACING_NV reads from any image or buffer, the image or buffer must not be a protected image or protected buffer.

  • Any VkImage created with a VkImageCreateInfo::flags containing VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV sampled as a result of this command must only be sampled using a VkSamplerAddressMode of VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE.

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • raygenShaderBindingTableBuffer must be a valid VkBuffer handle

  • If missShaderBindingTableBuffer is not VK_NULL_HANDLE, missShaderBindingTableBuffer must be a valid VkBuffer handle

  • If hitShaderBindingTableBuffer is not VK_NULL_HANDLE, hitShaderBindingTableBuffer must be a valid VkBuffer handle

  • If callableShaderBindingTableBuffer is not VK_NULL_HANDLE, callableShaderBindingTableBuffer must be a valid VkBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support compute operations

  • Each of callableShaderBindingTableBuffer, commandBuffer, hitShaderBindingTableBuffer, missShaderBindingTableBuffer, and raygenShaderBindingTableBuffer that are valid handles must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Compute

32.2. Shader Binding Table

A shader binding table is a resource which establishes the relationship between the ray tracing pipeline and the acceleration structures that were built for the ray tracing query. It indicates the shaders that operate on each geometry in an acceleration structure. In addition, it contains the resources accessed by each shader, including indices of textures and constants. The application allocates and manages shader binding tables as VkBuffer objects.

Each entry in the shader binding table consists of shaderHeaderSize bytes of data as queried by vkGetRayTracingShaderHandlesNV to refer to the shader that it invokes. The remainder of the data specified by the stride is application-visible data that can be referenced by a shaderRecordNV block in the shader.

The shader binding tables to use in a ray tracing query are passed to vkCmdTraceRaysNV. Shader binding tables are read-only in shaders that are executing on the ray tracing pipeline.

32.2.1. Indexing Rules

In order to execute the correct shaders and access the correct resources during a ray tracing dispatch, the implementation must be able to locate shader binding table entries at various stages of execution. This is accomplished by defining a set of indexing rules that compute shader binding table record positions relative to the buffer’s base address in memory. The application must organize the contents of the shader binding table’s memory in a way that application of the indexing rules will lead to correct records.

Ray Generation Shaders

Only one ray generation shader is executed per ray tracing dispatch. Its location is passed into vkCmdTraceRaysNV using the raygenShaderBindingTableBuffer and raygenShaderBindingTableOffset parameters - there is no indexing.

Hit Shaders

The base for the computation of intersection, any hit and closest hit shader locations is the instanceShaderBindingTableRecordOffset value stored with each instance of a top-level acceleration structure. This value determines the beginning of the shader binding table records for a given instance. Each geometry in the instance must have at least one hit program record.

In the following rule, geometryIndex refers to the location of the geometry within the instance.

The sbtRecordStride and sbtRecordOffset values are passed in as parameters to traceNV() calls made in the shaders. See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language Specification for more details.

The result of this computation is then added to hitProgramShaderBindingTableBaseIndex, a base index passed to vkCmdTraceRaysNV.

The complete rule to compute a hit shader binding table record index is:

instanceShaderBindingTableRecordOffset + hitProgramShaderBindingTableBaseIndex + geometryIndex × sbtRecordStride + sbtRecordOffset

Miss Shaders

A Miss shader is executed whenever a ray query fails to find an intersection for the given scene geometry. Multiple miss shaders can be executed throughout a ray tracing dispatch.

The base for the computation of miss shader locations is missProgramShaderBindingTableBaseIndex, a base index passed into vkCmdTraceRaysNV.

The sbtRecordOffset value is passed in as parameters to traceNV() calls made in the shaders. See Section 8.19 (Ray Tracing Functions) of the OpenGL Shading Language Specification for more details.

The complete rule to compute a miss shader binding table record address is:

missIndex × missShaderBindingStride + sbtRecordOffset

32.3. Acceleration Structures

Acceleration structures are data structures used by the implementation to efficiently manage the scene geometry as it is traversed during a ray tracing query. The application is responsible for managing acceleration structure objects (see Acceleration Structures, including allocation, destruction, executing builds or updates, and synchronizing resources used uring ray tracing queries.

There are two types of acceleration structures, top level acceleration structures and bottom level acceleration structures.

image/svg+xml Top-Level Acceleration Structure Bottom-LevelAccelerationStructure Bottom-LevelAccelerationStructure Transformand shadinginformation Transformand shadinginformation Transformand shadinginformation
Figure 34. Acceleration Structure
Caption

The diagram shows the relationship between top and bottom level acceleration structures.

32.3.1. Instances

Instances are found in top level acceleration structures and contain data that refer to a single bottom-level acceleration structure, a transform matrix, and shading information. Multiple instances may point to a single bottom level acceleration structure.

An instance is defined in a VkBuffer by a structure consisting of 64 bytes of data.

  • transform is 12 floats representing a 4x3 transform matrix in row-major order

  • instanceCustomIndex The low 24 bits of a 32-bit integer after the transform. This value appears in the builtin gl_InstanceCustomIndexNV

  • mask The high 8 bits of the same integer as instanceCustomIndex. This is the visibility mask. The instance can only be hit if rayMask & instance.mask != 0

  • instanceOffset The low 24 bits of the next 32-bit integer. The value contributed by this instance to the hit shader binding table index computation as instanceShaderBindingTableRecordOffset.

  • flags The high 8 bits of the same integer as instanceOffset. VkGeometryInstanceFlagBitsNV values that apply to this instance.

  • accelerationStructure. The 8 byte value returned by vkGetAccelerationStructureHandleNV for the bottom level acceleration structure referred to by this instance.

Note

The C language spec doesn’t define the ordering of bit-fields, but in practice, this struct produces the layout described above:

struct VkGeometryInstanceNV {
    float          transform[12];
    uint32_t       instanceCustomIndex : 24;
    uint32_t       mask : 8;
    uint32_t       instanceOffset : 24;
    uint32_t       flags : 8;
    uint64_t       accelerationStructureHandle;
};

Possible values of flags in the instance modifying the behavior of that instance are:,

typedef enum VkGeometryInstanceFlagBitsNV {
    VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = 0x00000001,
    VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002,
    VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = 0x00000004,
    VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = 0x00000008,
} VkGeometryInstanceFlagBitsNV;
  • VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV disables face culling for this instance.

  • VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV indicates that the front face of the triangle for culling purposes should be the face that’s counter clockwise in object space relative to the ray origin. Because the facing is determined in object space, an instance transform matrix does not changing winding, but a geometry transform does.

  • VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV causes this instance to act as though VK_GEOMETRY_OPAQUE_BIT_NV were specified on all geometries referenced by this instance. This behavior can be overridden by the ray flag gl_RayFlagsNoOpaqueNV.

  • VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV causes this instance to act as though VK_GEOMETRY_OPAQUE_BIT_NV were not specified on all geometries referenced by this instance. This behavior can be overridden by the ray flag gl_RayFlagsOpaqueNV.

VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV and VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV must not be used in the same flag.

32.3.2. Geometry

Geometries refer to a triangle or axis-aligned bounding box.

32.3.3. Top Level Acceleration Structures

Opaque acceleration structure for an array of instances. The descriptor referencing this is the starting point for tracing

32.3.4. Bottom Level Acceleration Structures

Opaque acceleration structure for an array of geometries.

32.3.5. Building Acceleration Structures

To build an acceleration structure call:

void vkCmdBuildAccelerationStructureNV(
    VkCommandBuffer                             commandBuffer,
    const VkAccelerationStructureInfoNV*        pInfo,
    VkBuffer                                    instanceData,
    VkDeviceSize                                instanceOffset,
    VkBool32                                    update,
    VkAccelerationStructureNV                   dst,
    VkAccelerationStructureNV                   src,
    VkBuffer                                    scratch,
    VkDeviceSize                                scratchOffset);
  • commandBuffer is the command buffer into which the command will be recorded

  • info contains the shared information for the acceleration structure’s structure

  • instanceData is the buffer containing instance data that will be used to build the acceleration structure as described in Accelerator structure instances. This parameter must be NULL for bottom level acceleration structures.

  • instanceOffset is the offset in bytes (relative to the start of instanceData) at which the instance data is located.

  • update specifies whether to update the dst acceleration structure with the data in src.

  • dst points to the target acceleration structure for the build.

  • src points to an existing acceleration structure that can be used to update the dst acceleration structure.

  • scratch is the VkBuffer that will be used as scratch memory for the build.

  • scratchOffset is the offset in bytes relative to the start of scratch that will be used as scratch memory.

Valid Usage
  • geometryCount must be less than or equal to VkPhysicalDeviceRayTracingPropertiesNV::maxGeometryCount

  • dst must have been created with compatible VkAccelerationStructureInfoNV where VkAccelerationStructureInfoNV:::type and VkAccelerationStructureInfoNV::flags are identical, VkAccelerationStructureInfoNV::instanceCount and VkAccelerationStructureInfoNV::geometryCount for dst are greater than or equal to the build size and each geometry in VkAccelerationStructureInfoNV::pGeometries for dst has greater than or equal to the number of vertices, indices, and AABBs.

  • If update is true, src must not be VK_NULL_HANDLE

  • If update is true, src must have been built last with VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV set in VkAccelerationStructureInfoNV::flags

  • If update is false, The size member of the VkMemoryRequirements structure returned from a call to vkGetAccelerationStructureMemoryRequirementsNV with VkAccelerationStructureMemoryRequirementsInfoNV::accelerationStructure set to dst and VkAccelerationStructureMemoryRequirementsInfoNV::type set to VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV must be less than or equal to the size of scratch minus scratchOffset

  • If update is true, The size member of the VkMemoryRequirements structure returned from a call to vkGetAccelerationStructureMemoryRequirementsNV with VkAccelerationStructureMemoryRequirementsInfoNV::accelerationStructure set to dst and VkAccelerationStructureMemoryRequirementsInfoNV::type set to VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV must be less than or equal to the size of scratch minus scratchOffset

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pInfo must be a valid pointer to a valid VkAccelerationStructureInfoNV structure

  • If instanceData is not VK_NULL_HANDLE, instanceData must be a valid VkBuffer handle

  • dst must be a valid VkAccelerationStructureNV handle

  • If src is not VK_NULL_HANDLE, src must be a valid VkAccelerationStructureNV handle

  • scratch must be a valid VkBuffer handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support compute operations

  • Each of commandBuffer, dst, instanceData, scratch, and src that are valid handles must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Compute

32.3.6. Copying Acceleration Structures

An additional command exists for copying acceleration structures without updating their contents. The acceleration structure object may be compacted in order to improve performance. Before copying, an application must query the size of the resulting acceleration structure.

To query acceleration structure size parameters call:

void vkCmdWriteAccelerationStructuresPropertiesNV(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    accelerationStructureCount,
    const VkAccelerationStructureNV*            pAccelerationStructures,
    VkQueryType                                 queryType,
    VkQueryPool                                 queryPool,
    uint32_t                                    firstQuery);
  • commandBuffer is the command buffer into which the command will be recorded.

  • accelerationStructureCount is the count of acceleration structures for which to query the property.

  • accelerationStructures points to an array of existing acceleration structures which have been built.

  • queryType is a VkQueryType value specifying the type of queries managed by the pool.

  • queryPool is the query pool that will manage the results of the query.

  • firstQuery is the first query index within the query pool that will contain the accelerationStructureCount number of results

Valid Usage
  • queryType must be VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV

  • queryPool must have been created with a queryType matching queryType

  • The queries identified by queryPool and firstQuery must be unavailable

  • All acceleration structures in accelerationStructures must have been built with VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV if queryType is VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • pAccelerationStructures must be a valid pointer to an array of accelerationStructureCount valid VkAccelerationStructureNV handles

  • queryType must be a valid VkQueryType value

  • queryPool must be a valid VkQueryPool handle

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support compute operations

  • accelerationStructureCount must be greater than 0

  • Each of commandBuffer, queryPool, and the elements of pAccelerationStructures must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Compute

To copy an acceleration structure call:

void vkCmdCopyAccelerationStructureNV(
    VkCommandBuffer                             commandBuffer,
    VkAccelerationStructureNV                   dst,
    VkAccelerationStructureNV                   src,
    VkCopyAccelerationStructureModeNV           mode);
  • commandBuffer is the command buffer into which the command will be recorded.

  • dst points to the target acceleration structure for the copy

  • src points to the source acceleration structure for the copy

  • mode is a VkCopyAccelerationStructureModeNV value that specifies additional operations to perform during the copy.

Valid Usage
  • mode must be VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV or VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV

  • src must have been built with VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV if mode is VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV

Valid Usage (Implicit)
  • commandBuffer must be a valid VkCommandBuffer handle

  • dst must be a valid VkAccelerationStructureNV handle

  • src must be a valid VkAccelerationStructureNV handle

  • mode must be a valid VkCopyAccelerationStructureModeNV value

  • commandBuffer must be in the recording state

  • The VkCommandPool that commandBuffer was allocated from must support compute operations

  • Each of commandBuffer, dst, and src must have been created, allocated, or retrieved from the same VkDevice

Host Synchronization
  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Compute

Possible values of vkCmdCopyAccelerationStructureNV::mode, specifying additional operations to perform during the copy, are:

typedef enum VkCopyAccelerationStructureModeNV {
    VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0,
    VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1,
} VkCopyAccelerationStructureModeNV;
  • VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV creates a direct copy of the acceleration structure specified in src into the one specified by dst. The dst acceleration structure must have been created with the same parameters as src.

  • VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV creates a more compact version of an acceleration structure src into dst. The acceleration structure dst must have been created with a compactedSize corresponding to the one returned by vkCmdWriteAccelerationStructuresPropertiesNV after the build of the acceleration structure specified by src.