Shader Execution Reordering (SER)
Slang provides support for Shader Execution Reordering (SER) across multiple backends:
- D3D12: Via NVAPI or native DXR 1.3 (SM 6.9)
- Vulkan/SPIR-V: Via GL_NV_shader_invocation_reorder (NV) or GL_EXT_shader_invocation_reorder (cross-vendor EXT)
- CUDA: Via OptiX
Platform Notes
Vulkan (NV Extension)
With GL_NV_shader_invocation_reorder, HitObject variables have special allocation semantics with limitations around flow control and assignment.
Vulkan (EXT Extension)
The cross-vendor GL_EXT_shader_invocation_reorder extension provides broader compatibility. Note that MakeHit and MakeMotionHit are NV-only and not available with the EXT extension.
D3D12 (DXR 1.3)
Native DXR 1.3 support (SM 6.9) provides HitObject without requiring NVAPI.
Links
API Reference
The HitObject API provides cross-platform SER functionality. The API is based on the NvAPI/DXR 1.3 interface.
Free Functions
Fused Functions (Vulkan EXT only)
struct HitObject
Description
Immutable data type representing a ray hit or a miss. Can be used to invoke hit or miss shading, or as a key in ReorderThread. Created by one of several methods described below. HitObject and its related functions are available in raytracing shader types only.
Methods
- TraceRay
- TraceMotionRay
- MakeMiss
- MakeHit
- MakeMotionHit
- MakeMotionMiss
- MakeNop
- FromRayQuery
- Invoke
- IsMiss
- IsHit
- IsNop
- GetRayDesc
- GetRayFlags
- GetRayTMin
- GetRayTCurrent
- GetWorldRayOrigin
- GetWorldRayDirection
- GetShaderTableIndex
- SetShaderTableIndex
- GetInstanceIndex
- GetInstanceID
- GetGeometryIndex
- GetPrimitiveIndex
- GetHitKind
- GetAttributes
- GetTriangleVertexPositions
- GetWorldToObject
- GetObjectToWorld
- GetCurrentTime
- GetObjectRayOrigin
- GetObjectRayDirection
- GetShaderRecordBufferHandle
- GetClusterID
- GetSpherePositionAndRadius
- GetLssPositionsAndRadii
- IsSphereHit
- IsLssHit
- LoadLocalRootTableConstant
HitObject.TraceRay
Description
Executes ray traversal (including anyhit and intersection shaders) like TraceRay, but returns the resulting hit information as a HitObject and does not trigger closesthit or miss shaders.
Signature
static HitObject HitObject.TraceRay<payload_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint RayFlags,
uint InstanceInclusionMask,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
uint MissShaderIndex,
RayDesc Ray,
inout payload_t Payload);
HitObject.TraceMotionRay
Description
Executes motion ray traversal (including anyhit and intersection shaders) like TraceRay, but returns the resulting hit information as a HitObject and does not trigger closesthit or miss shaders.
Note: Requires motion blur support. Available on Vulkan (NV/EXT) and CUDA.
Signature
static HitObject HitObject.TraceMotionRay<payload_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint RayFlags,
uint InstanceInclusionMask,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
uint MissShaderIndex,
RayDesc Ray,
float CurrentTime,
inout payload_t Payload);
HitObject.MakeHit
Description
Creates a HitObject representing a hit based on values explicitly passed as arguments, without tracing a ray. The primitive specified by AccelerationStructure, InstanceIndex, GeometryIndex, and PrimitiveIndex must exist. The shader table index is computed using the formula used with TraceRay. The computed index must reference a valid hit group record in the shader table. The Attributes parameter must either be an attribute struct, such as BuiltInTriangleIntersectionAttributes, or another HitObject to copy the attributes from.
Note: This function is NV-only and not available with the cross-vendor EXT extension.
Signature
static HitObject HitObject.MakeHit<attr_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint InstanceIndex,
uint GeometryIndex,
uint PrimitiveIndex,
uint HitKind,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
RayDesc Ray,
attr_t attributes);
static HitObject HitObject.MakeHit<attr_t>(
uint HitGroupRecordIndex,
RaytracingAccelerationStructure AccelerationStructure,
uint InstanceIndex,
uint GeometryIndex,
uint PrimitiveIndex,
uint HitKind,
RayDesc Ray,
attr_t attributes);
HitObject.MakeMotionHit
Description
See MakeHit but handles Motion.
Note: This function is NV-only and not available with the cross-vendor EXT extension.
Signature
static HitObject HitObject.MakeMotionHit<attr_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint InstanceIndex,
uint GeometryIndex,
uint PrimitiveIndex,
uint HitKind,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
RayDesc Ray,
float CurrentTime,
attr_t attributes);
static HitObject HitObject.MakeMotionHit<attr_t>(
uint HitGroupRecordIndex,
RaytracingAccelerationStructure AccelerationStructure,
uint InstanceIndex,
uint GeometryIndex,
uint PrimitiveIndex,
uint HitKind,
RayDesc Ray,
float CurrentTime,
attr_t attributes);
HitObject.MakeMiss
Description
Creates a HitObject representing a miss based on values explicitly passed as arguments, without tracing a ray. The provided shader table index must reference a valid miss record in the shader table.
Signature
static HitObject HitObject.MakeMiss(
uint MissShaderIndex,
RayDesc Ray);
HitObject.MakeMotionMiss
Description
See MakeMiss but handles Motion. Available on Vulkan (NV and EXT extensions).
Signature
static HitObject HitObject.MakeMotionMiss(
uint MissShaderIndex,
RayDesc Ray,
float CurrentTime);
HitObject.MakeNop
Description
Creates a HitObject representing “NOP” (no operation) which is neither a hit nor a miss. Invoking a NOP hit object using HitObject::Invoke has no effect. Reordering by hit objects using ReorderThread will group NOP hit objects together. This can be useful in some reordering scenarios where future control flow for some threads is known to process neither a hit nor a miss.
Signature
static HitObject HitObject.MakeNop();
HitObject.FromRayQuery
Description
Creates a HitObject from a committed RayQuery hit. The RayQuery must have a committed hit (either triangle or procedural). If the RayQuery has no committed hit, the resulting HitObject will represent a miss or NOP depending on the query state.
Note: DXR 1.3 only. Also available on Vulkan EXT via hitObjectRecordFromQueryEXT.
Signature
static HitObject HitObject.FromRayQuery<RayQuery_t>(
RayQuery_t Query);
static HitObject HitObject.FromRayQuery<RayQuery_t, attr_t>(
RayQuery_t Query,
uint CommittedCustomHitKind,
attr_t CommittedCustomAttribs);
HitObject.Invoke
Description
Invokes closesthit or miss shading for the specified hit object. In case of a NOP HitObject, no shader is invoked.
Signature
static void HitObject.Invoke<payload_t>(
RaytracingAccelerationStructure AccelerationStructure,
HitObject HitOrMiss,
inout payload_t Payload);
// DXR 1.3 overload (without AccelerationStructure)
static void HitObject.Invoke<payload_t>(
HitObject HitOrMiss,
inout payload_t Payload);
HitObject.IsMiss
Description
Returns true if the HitObject encodes a miss, otherwise returns false.
Signature
bool HitObject.IsMiss();
HitObject.IsHit
Description
Returns true if the HitObject encodes a hit, otherwise returns false.
Signature
bool HitObject.IsHit();
HitObject.IsNop
Description
Returns true if the HitObject encodes a nop, otherwise returns false.
Signature
bool HitObject.IsNop();
HitObject.GetRayDesc
Description
Queries ray properties from HitObject. Valid if the hit object represents a hit or a miss.
Signature
RayDesc HitObject.GetRayDesc();
HitObject.GetRayFlags
Description
Returns the ray flags used when tracing the ray. Valid if the hit object represents a hit or a miss.
Note: DXR 1.3 and Vulkan EXT.
Signature
uint HitObject.GetRayFlags();
HitObject.GetRayTMin
Description
Returns the minimum T value of the ray. Valid if the hit object represents a hit or a miss.
Note: DXR 1.3 and Vulkan EXT.
Signature
float HitObject.GetRayTMin();
HitObject.GetRayTCurrent
Description
Returns the current T value (hit distance) of the ray. Valid if the hit object represents a hit or a miss.
Note: DXR 1.3 and Vulkan EXT (called GetRayTMax in GLSL/SPIR-V).
Signature
float HitObject.GetRayTCurrent();
HitObject.GetWorldRayOrigin
Description
Returns the ray origin in world space. Valid if the hit object represents a hit or a miss.
Note: DXR 1.3 and Vulkan EXT.
Signature
float3 HitObject.GetWorldRayOrigin();
HitObject.GetWorldRayDirection
Description
Returns the ray direction in world space. Valid if the hit object represents a hit or a miss.
Note: DXR 1.3 and Vulkan EXT.
Signature
float3 HitObject.GetWorldRayDirection();
HitObject.GetShaderTableIndex
Description
Queries shader table index from HitObject. Valid if the hit object represents a hit or a miss.
Signature
uint HitObject.GetShaderTableIndex();
HitObject.GetInstanceIndex
Description
Returns the instance index of a hit. Valid if the hit object represents a hit.
Signature
uint HitObject.GetInstanceIndex();
HitObject.GetInstanceID
Description
Returns the instance ID of a hit. Valid if the hit object represents a hit.
Signature
uint HitObject.GetInstanceID();
HitObject.GetGeometryIndex
Description
Returns the geometry index of a hit. Valid if the hit object represents a hit.
Signature
uint HitObject.GetGeometryIndex();
HitObject.GetPrimitiveIndex
Description
Returns the primitive index of a hit. Valid if the hit object represents a hit.
Signature
uint HitObject.GetPrimitiveIndex();
HitObject.GetHitKind
Description
Returns the hit kind. Valid if the hit object represents a hit.
Signature
uint HitObject.GetHitKind();
HitObject.GetAttributes
Description
Returns the attributes of a hit. Valid if the hit object represents a hit or a miss.
Signature
attr_t HitObject.GetAttributes<attr_t>();
HitObject.GetTriangleVertexPositions
Description
Returns the world-space vertex positions of the triangle that was hit. Valid if the hit object represents a triangle hit.
Note: Vulkan EXT only. Requires SPV_KHR_ray_tracing_position_fetch capability.
Signature
void HitObject.GetTriangleVertexPositions(out float3 positions[3]);
HitObject.LoadLocalRootTableConstant
Description
Loads a root constant from the local root table referenced by the hit object. Valid if the hit object represents a hit or a miss. RootConstantOffsetInBytes must be a multiple of 4.
Note: D3D12/HLSL only.
Signature
uint HitObject.LoadLocalRootTableConstant(uint RootConstantOffsetInBytes);
HitObject.SetShaderTableIndex
Description
Sets the shader table index of the hit object. Used to modify which shader gets invoked during HitObject.Invoke. EXT extension only (not available with NV extension).
Signature
void HitObject.SetShaderTableIndex(uint RecordIndex);
HitObject.GetWorldToObject
Description
Returns the world-to-object transformation matrix. Valid if the hit object represents a hit.
Signature
float4x3 HitObject.GetWorldToObject();
// DXR 1.3 layout variants
float3x4 HitObject.GetWorldToObject3x4();
float4x3 HitObject.GetWorldToObject4x3();
HitObject.GetObjectToWorld
Description
Returns the object-to-world transformation matrix. Valid if the hit object represents a hit.
Signature
float4x3 HitObject.GetObjectToWorld();
// DXR 1.3 layout variants
float3x4 HitObject.GetObjectToWorld3x4();
float4x3 HitObject.GetObjectToWorld4x3();
HitObject.GetCurrentTime
Description
Returns the current time for motion blur. Valid if the hit object represents a motion hit or miss.
Note: Requires motion blur support. Available on Vulkan (NV/EXT).
Signature
float HitObject.GetCurrentTime();
HitObject.GetObjectRayOrigin
Description
Returns the ray origin in object space. Valid if the hit object represents a hit.
Signature
float3 HitObject.GetObjectRayOrigin();
HitObject.GetObjectRayDirection
Description
Returns the ray direction in object space. Valid if the hit object represents a hit.
Signature
float3 HitObject.GetObjectRayDirection();
HitObject.GetShaderRecordBufferHandle
Description
Returns the shader record buffer handle. Valid if the hit object represents a hit or a miss.
Signature
uint2 HitObject.GetShaderRecordBufferHandle();
HitObject.GetClusterID
Description
Returns the cluster ID for cluster acceleration structures. Valid if the hit object represents a hit.
Note: NV-only (requires GL_NV_cluster_acceleration_structure).
Signature
int HitObject.GetClusterID();
HitObject.GetSpherePositionAndRadius
Description
Returns the position and radius of a sphere primitive. Valid if the hit object represents a sphere hit.
Note: NV-only.
Signature
float4 HitObject.GetSpherePositionAndRadius();
HitObject.GetLssPositionsAndRadii
Description
Returns the positions and radii of a linear swept sphere primitive. Valid if the hit object represents an LSS hit.
Note: NV-only.
Signature
float2x4 HitObject.GetLssPositionsAndRadii();
HitObject.IsSphereHit
Description
Returns true if the HitObject represents a hit on a sphere primitive, otherwise returns false.
Note: NV-only.
Signature
bool HitObject.IsSphereHit();
HitObject.IsLssHit
Description
Returns true if the HitObject represents a hit on a linear swept sphere primitive, otherwise returns false.
Note: NV-only.
Signature
bool HitObject.IsLssHit();
ReorderThread
Description
Reorders threads based on a coherence hint value. NumCoherenceHintBits indicates how many of the least significant bits of CoherenceHint should be considered during reordering (max: 16). Applications should set this to the lowest value required to represent all possible values in CoherenceHint. For best performance, all threads should provide the same value for NumCoherenceHintBits. Where possible, reordering will also attempt to retain locality in the thread’s launch indices (DispatchRaysIndex in DXR).
ReorderThread(HitOrMiss) is equivalent to
void ReorderThread( HitObject HitOrMiss, uint CoherenceHint, uint NumCoherenceHintBitsFromLSB );
With CoherenceHint and NumCoherenceHintBitsFromLSB as 0, meaning they are ignored.
Signature
void ReorderThread(
uint CoherenceHint,
uint NumCoherenceHintBitsFromLSB);
void ReorderThread(
HitObject HitOrMiss,
uint CoherenceHint,
uint NumCoherenceHintBitsFromLSB);
void ReorderThread(HitObject HitOrMiss);
ReorderExecute
Description
Fused operation that reorders threads by HitObject and then executes the shader. Equivalent to calling ReorderThread followed by HitObject.Invoke.
Note: Vulkan EXT only. Available via hitObjectReorderExecuteEXT in GLSL.
Signature
// GLSL: hitObjectReorderExecuteEXT(hitObject, payload)
void ReorderExecute<payload_t>(
HitObject HitOrMiss,
inout payload_t Payload);
// GLSL: hitObjectReorderExecuteEXT(hitObject, hint, bits, payload)
void ReorderExecute<payload_t>(
HitObject HitOrMiss,
uint CoherenceHint,
uint NumCoherenceHintBitsFromLSB,
inout payload_t Payload);
TraceReorderExecute
Description
Fused operation that traces a ray, reorders threads by the resulting HitObject, and executes the shader. Equivalent to calling HitObject.TraceRay, ReorderThread, and HitObject.Invoke in sequence.
Note: Vulkan EXT only. Available via hitObjectTraceReorderExecuteEXT in GLSL.
Signature
// GLSL: hitObjectTraceReorderExecuteEXT(...)
void TraceReorderExecute<payload_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint RayFlags,
uint InstanceInclusionMask,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
uint MissShaderIndex,
RayDesc Ray,
inout payload_t Payload);
// With coherence hint
void TraceReorderExecute<payload_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint RayFlags,
uint InstanceInclusionMask,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
uint MissShaderIndex,
RayDesc Ray,
uint CoherenceHint,
uint NumCoherenceHintBitsFromLSB,
inout payload_t Payload);
TraceMotionReorderExecute
Description
Fused operation for motion blur that traces a motion ray, reorders threads, and executes the shader.
Note: Vulkan EXT only. Available via hitObjectTraceMotionReorderExecuteEXT in GLSL. Requires motion blur support.
Signature
void TraceMotionReorderExecute<payload_t>(
RaytracingAccelerationStructure AccelerationStructure,
uint RayFlags,
uint InstanceInclusionMask,
uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
uint MissShaderIndex,
RayDesc Ray,
float CurrentTime,
uint CoherenceHint,
uint NumCoherenceHintBitsFromLSB,
inout payload_t Payload);