From 64a43b17a76d7a8269f55cbe67ef708cd464774c Mon Sep 17 00:00:00 2001 From: "Harsh Aggarwal (NVIDIA)" Date: Mon, 12 May 2025 13:05:34 +0530 Subject: cluster acceleration structure optix 6431 (#7028) * Add cluster geometry intrinsics for ray tracing - Added GetClusterID() method to HitObject class - Added CandidateClusterID() and CommittedClusterID() methods to RayQuery class - Added SPV_NV_cluster_acceleration_structure extension support - Added GL_NV_cluster_acceleration_structure extension support - Added test files for RayQuery and HitObject cluster methods Fixes #6431 * OpRayQueryGetIntersectionClusterIdNV - unrecognized spirv Disabling spirv backend for SPV_NV_cluster_acceleration_structure hlsl.meta.slang(18674): error 29100: unrecognized spirv opcode: OpRayQueryGetIntersectionClusterIdNV result:$$int = OpRayQueryGetIntersectionClusterIdNV &this $iCandidateOrCommitted; ^~~~~~ hlsl.meta.slang(18670): error 30019: expected an expression of type 'int', got 'void' return spirv_asm ^~~~~~~~~ ninja: build stopped: subcommand failed. * 6431 - Fix spirv opcode * Remove tests * Add relevant tests * Review - Simplify tests --- source/slang/glsl.meta.slang | 29 +++++++++++ source/slang/hlsl.meta.slang | 95 +++++++++++++++++++++++++++++++++- source/slang/slang-capabilities.capdef | 13 +++++ source/slang/slang-emit-spirv.cpp | 7 +++ 4 files changed, 143 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang index 00ad88add..05cef836c 100644 --- a/source/slang/glsl.meta.slang +++ b/source/slang/glsl.meta.slang @@ -4893,6 +4893,35 @@ public property uint gl_HitKindEXT } } +public property int gl_ClusterIDNV +{ + [require(glsl_spirv, raytracing_anyhit_closesthit)] + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __requireTargetExtension("GL_NV_cluster_acceleration_structure"); + __intrinsic_asm "(gl_ClusterIDNV)"; + } + case spirv: + { + return spirv_asm + { + OpCapability RayTracingClusterAccelerationStructureNV; + OpExtension "SPV_NV_cluster_acceleration_structure"; + result:$$int = OpLoad builtin(ClusterIDNV:int); + }; + } + } + } +} +// Constant to indicate that a cluster acceleration structure was not hit. +// Corresponds to VK_GEOMETRY_INSTANCE_CLUSTER_ID_NONE_NV in Vulkan +public static const int gl_ClusterIDNoneNV = -1; + public property mat4x3 gl_ObjectToWorldEXT { [require(glsl_spirv, raytracing_anyhit_closesthit_intersection)] diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 99eba0a42..34423d4f3 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -17889,6 +17889,26 @@ float RayCurrentTime() } } +/// @category raytracing +[__requiresNVAPI] +__glsl_extension(GL_NV_cluster_acceleration_structure) +__glsl_extension(GL_EXT_ray_tracing) +[NonUniformReturn] +[require(cuda_glsl_hlsl_spirv, raytracing_anyhit_closesthit)] +int GetClusterID() +{ + __target_switch + { + case hlsl: __intrinsic_asm "NvRtGetClusterID"; + case glsl: __intrinsic_asm "(gl_ClusterIDNV)"; + case cuda: __intrinsic_asm "optixGetClusterId"; + case spirv: + return spirv_asm + { + result:$$int = OpLoad builtin(ClusterIDNV:int); + }; + } +} // Note: The provisional DXR spec included these unadorned // `ObjectToWorld()` and `WorldToObject()` functions, so // we will forward them to the new names as a convience @@ -18683,6 +18703,31 @@ struct RayQuery } } + /// Gets the cluster ID of the candidate hit. + /// @return Cluster ID for the candidate hit + /// @remarks HLSL/GLSL/SPIRV + [__requiresNVAPI] + __glsl_extension(GL_NV_cluster_acceleration_structure) + __glsl_extension(GL_EXT_ray_query) + [__NoSideEffect] + [require(glsl_hlsl_spirv, rayquery)] + int CandidateClusterID() + { + __target_switch + { + case hlsl: __intrinsic_asm "NvRtGetCandidateClusterID"; + case glsl: __intrinsic_asm "rayQueryGetIntersectionClusterIdNV($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + OpExtension "SPV_NV_cluster_acceleration_structure"; + OpCapability RayTracingClusterAccelerationStructureNV; + result:$$int = OpRayQueryGetClusterIdNV &this $iCandidateOrCommitted; + }; + } + } + /// Gets the custom index of the instance containing the committed hit. /// @return User-provided instance identifier /// @remarks GLSL/SPIRV only @@ -18698,7 +18743,32 @@ struct RayQuery uint iCandidateOrCommitted = 1; return spirv_asm { - result:$$int = OpRayQueryGetIntersectionInstanceCustomIndexKHR &this $iCandidateOrCommitted; + result:$$int = OpRayQueryGetClusterIdNV &this $iCandidateOrCommitted; + }; + } + } + + /// Gets the cluster ID of the committed hit. + /// @return Cluster ID for the committed hit + /// @remarks HLSL/GLSL/SPIRV + [__requiresNVAPI] + __glsl_extension(GL_NV_cluster_acceleration_structure) + __glsl_extension(GL_EXT_ray_query) + [__NoSideEffect] + [require(glsl_hlsl_spirv, rayquery)] + int CommittedClusterID() + { + __target_switch + { + case hlsl: __intrinsic_asm "NvRtGetCommittedClusterID"; + case glsl: __intrinsic_asm "rayQueryGetIntersectionClusterIdNV($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; // 1 for committed + return spirv_asm + { + OpExtension "SPV_NV_cluster_acceleration_structure"; + OpCapability RayTracingClusterAccelerationStructureNV; + result:$$int = OpRayQueryGetClusterIdNV &this $iCandidateOrCommitted; }; } } @@ -20354,6 +20424,29 @@ struct HitObject } } + /// Returns the cluster ID of the current hit. Valid if the hit object represents a hit. + [__requiresNVAPI] + __glsl_extension(GL_NV_cluster_acceleration_structure) + __glsl_extension(GL_EXT_ray_tracing) + [ForceInline] + [require(cuda_glsl_hlsl_spirv, ser_raygen_closesthit_miss)] + int GetClusterID() + { + __target_switch + { + case hlsl: __intrinsic_asm ".GetClusterID"; + case glsl: __intrinsic_asm "hitObjectGetClusterIdNV($0)"; + case cuda: __intrinsic_asm "optixHitObjectGetClusterId"; + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_cluster_acceleration_structure"; + OpCapability RayTracingClusterAccelerationStructureNV; + result:$$int = OpHitObjectGetClusterIdNV &this; + }; + } + } + [__requiresNVAPI] __glsl_extension(GL_EXT_ray_tracing) [ForceInline] diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef index b50519a72..fafcb214f 100644 --- a/source/slang/slang-capabilities.capdef +++ b/source/slang/slang-capabilities.capdef @@ -539,6 +539,10 @@ def SPV_NV_ray_tracing_motion_blur : _spirv_1_0; /// [EXT] def SPV_NV_shader_invocation_reorder : _spirv_1_5 + SPV_KHR_ray_tracing; +/// Represents the SPIR-V extension for cluster acceleration structure. +/// [EXT] +def SPV_NV_cluster_acceleration_structure : _spirv_1_0; + /// Represents the SPIR-V extension for shader image footprint. /// [EXT] def SPV_NV_shader_image_footprint : _spirv_1_0; @@ -689,6 +693,10 @@ def spvRayQueryPositionFetchKHR : SPV_KHR_ray_tracing_position_fetch + spvRayQue /// [EXT] def spvShaderInvocationReorderNV : SPV_NV_shader_invocation_reorder; +/// Represents the SPIR-V capability for cluster acceleration structure. +/// [EXT] +def spvRayTracingClusterAccelerationStructureNV : SPV_NV_cluster_acceleration_structure; + /// Represents the SPIR-V capability for shader clock. /// [EXT] def spvShaderClockKHR : SPV_KHR_shader_clock; @@ -809,6 +817,7 @@ def _GL_NV_shader_atomic_fp16_vector : _GL_NV_gpu_shader5; def _GL_NV_shader_invocation_reorder : _GLSL_460; def _GL_NV_shader_subgroup_partitioned : _GLSL_140; def _GL_NV_shader_texture_footprint : _GLSL_450; +def _GL_NV_cluster_acceleration_structure : _GLSL_460; // GLSL extension and SPV extension associations. @@ -1044,6 +1053,10 @@ alias GL_NV_shader_subgroup_partitioned = _GL_NV_shader_subgroup_partitioned | s /// [EXT] alias GL_NV_shader_texture_footprint = _GL_NV_shader_texture_footprint | spvImageFootprintNV; +/// Represents the GL_NV_cluster_acceleration_structure extension. +/// [EXT] +alias GL_NV_cluster_acceleration_structure = _GL_NV_cluster_acceleration_structure | spvRayTracingClusterAccelerationStructureNV; + // Define feature names not reliant on shader stages /// NVAPI capability for HLSL diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index bd9b23b2d..096e7d8bc 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1433,6 +1433,13 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex return ensureExtensionDeclaration(name); } + // Ensure cluster acceleration structure extensions and capabilities are declared + void requireRayTracingClusterAccelerationStructure() + { + requireSPIRVCapability(SpvCapabilityRayTracingClusterAccelerationStructureNV); + ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_cluster_acceleration_structure")); + } + bool hasExtensionDeclaration(const UnownedStringSlice& name) { return m_extensionInsts.containsKey(name); -- cgit v1.2.3