From 9016e5afa8efde664e66fda0d40a2b93aec9cae9 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 11:49:19 -0700 Subject: [PATCH 01/13] Merge HLSL and DXIL specs --- proposals/NNNN-triangle-object-positions.md | 434 ++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 proposals/NNNN-triangle-object-positions.md diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md new file mode 100644 index 00000000..dabecab4 --- /dev/null +++ b/proposals/NNNN-triangle-object-positions.md @@ -0,0 +1,434 @@ + + +# HLSL TriangleObjectPositions + +* Proposal: [NNNN](NNNN-triangle-object-positions.md) +* Author(s): [Tex Riddell](https://github.com/tex3d), [Jesse Natalie](https://github.com/jenatali) +* Sponsor: [Jesse Natalie](https://github.com/jenatali) +* Status: **Under Consideration** + +--- + +## Introduction + +This proposal adds intrinsics that can be called from an Any hit or Closest +hit shader to obtain the positions of the vertices for the triangle that has +been hit. + +--- + +## Motivation + +Developers often need to know the positions of the vertices for the triangle +that was hit in an Any/Closest hit shader. Currently, the only way to do this is +for the developer to provide separate buffers containing this data. This +information is also available in the acceleration structure, but there is +currently no way to access it. + +If developers can access this data from their shader code then this will remove +the need have a duplicate copy of it. In addition, this will provide drivers +with opportunities to optimize the data layout for their implementations. + +--- + +## Proposed solution + +Add intrinsics to look up the object-space vertex positions of the triangle for +the current hit, or RayQuery candidate/committed hits. + +For context, see related sections in DirectX Raytracing Specification: +[TriangleObjectPositions][dxr-tri-obj-pos], +[RayQuery::CandidateTriangleObjectPositions][dxr-rq-can-tri-obj-pos], +[RayQuery::CommittedTriangleObjectPositions][dxr-rq-com-tri-obj-pos]. + +--- + +## Detailed design + +--- + +### HLSL Additions + +A new built-in structure for returning all three object-space triangle +positions is added: `BuiltInTrianglePositions`. + +> See Issue [Return Type](#return-type) + +```cpp +/// \brief Stores the positions for all vertices of a triangle +struct BuiltInTrianglePositions { + float3 p0, p1, p2; +}; +``` + +A new intrinsic function to retrieve triangle object-space positions for the +currently hit triangle: `TriangleObjectPositions`. + +> See Issue [Intrinsic Naming](#intrinsic-naming) + +```cpp +/// \brief Retrieve current hit triangle object-space vertex positions +/// \returns position of vertex in object-space +/// +/// Minimum shader model: (Version TBD) +/// Allowed shader types: anyhit, closesthit. +/// +/// Hit kind must be a triangle, where HitKind() returns either +/// HIT_KIND_TRIANGLE_FRONT_FACE (254) or HIT_KIND_TRIANGLE_BACK_FACE (255), +/// otherwise undefined behavior results. +/// +/// Ordering of positions returned is based on the order used to build the +/// acceleration structure, and must match barycentric ordering. +BuiltInTrianglePositions TriangleObjectPositions(); +``` + +Two new intrinsic methods on `RayQuery` to retrieve triangle object-space +positions for the candidate or committed triangle hits: +`CandidateTriangleObjectPositions`, and `CommittedTriangleObjectPositions`. + +```cpp +template +class RayQuery { + // Existing Methods: no change. + + // New Methods: + + /// \brief Retrieve candidate hit triangle object-space vertex positions + /// \returns position of vertex in object-space + /// + /// Minimum shader model: (Version TBD) + /// + /// The RayQuery must be in a state where `RayQuery::Proceed()` has returned + /// true, and where `RayQuery::CandidateType()` returns + /// `CANDIDATE_TYPE::CANDIDATE_NON_OPAQUE_TRIANGLE`, otherwise undefined + /// behavior results. + /// + /// Ordering of positions returned is based on the order used to build the + /// acceleration structure, and must match barycentric ordering. + BuiltInTrianglePositions CandidateTriangleObjectPositions() const; + + /// \brief Retrieve committed hit triangle object-space vertex positions + /// \returns position of vertex in object-space + /// + /// Minimum shader model: (Version TBD) + /// + /// The RayQuery must be in a state with a committed triangle hit, + /// where `CommittedStatus()` returns + /// `COMMITTED_STATUS::COMMITTED_TRIANGLE_HIT`, otherwise undefined behavior + /// results. + /// + /// Ordering of positions returned is based on the order used to build the + /// acceleration structure, and must match barycentric ordering. + BuiltInTrianglePositions CommittedTriangleObjectPositions() const; +}; +``` + +These return the object-space position for all vertices that make up the +triangle for a hit. The hit is the current hit inside an +[AnyHit][dxr-anyhit] or [ClosestHit][dxr-closesthit] shader, or +the candidate or committed hit state of a RayQuery object. + +May only be used if the hit BLAS was built with +`D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DATA_ACCESS` +(See [build flags defined here][dxr-build-flags]), +otherwise behavior is undefined. + +These intrinsics may only be used with a triangle hit, otherwise behavior is +undefined. A shader can check for a triangle hit with +[`HitKind()`][dxr-hitkind], [`RayQuery::CandidateType()`][dxr-rq-can-type], or +[`CommittedStatus()`][dxr-rq-com-status] depending on the context. + +Shader model (Version TBD) is required to use these intrinsics. + +--- + +### Diagnostic Changes + +New diagnostics: + +* When any intrinsic is used and the Shader Model is less than (Version TBD): + * `" is only available on Shader Model (Version TBD) or newer"` +* When the `TriangleObjectPositions` intrinsic is used outside an `anyhit` or + `closesthit` shader: + * `"TriangleObjectPositions is not available in on Shader Model "` + +> Open Issue: [Use Availability Attributes](#use-availability-attributes) + +--- + +#### Validation Changes + +New Validation: + +* When the VertexInTri or ColumnIndex is not an immediate constant or out of + range: + * `" %select{VertexInTri|ColumnIndex}0 (%1) must be an immediate constant value in range [0..2]"` + +Existing infrastructure for enforcing shader model and shader stage +requirements for DXIL ops will be used. +Existing validation for RayQuery handle will be used. + +--- + +### Runtime Additions + +--- + +#### Device Capability + +Use of Triangle Object Positions intrinsics require Shader Model (Version TBD) and +[D3D12_RAYTRACING_TIER_1_0][dxr-tier]. + +> Note: any raytracing tier requirement is implied by the shader stage +> requirement or use of RayQuery, so no other changes are required in the +> compiler, aside from the shader model requirement. + +--- + +## Testing + +--- + +### Compiler output + +* Test AST generation for each new HLSL intrinsic +* Test CodeGen for each new HLSL intrinsic +* Test final DXIL output for each HLSL intrinsic + * Test static and dynamic vertex index +* Use D3DReflect test to verify min shader model of (Version TBD) with each intrinsic + usage for library target. + +--- + +### Diagnostics + +* Test shader model diagnostic for each new HLSL intrinsic. +* Test shader stage diagnostic for `TriangleObjectPositions` intrinsic. + +--- + +### Interchange Format Additions + +```llvm +; Availability: Shader Model (Version TBD)+ +; Availability: anyhit,closesthit +; Function Attrs: nounwind readnone +declare f32 @dx.op.triangleObjectPosition.f32( + i32, ; DXIL OpCode + i32, ; VertexInTri, immediate constant [0..2] + i32) ; ColumnIndex, immediate constant [0..2] + +; Availability: Shader Model (Version TBD)+ +; Function Attrs: nounwind readonly +declare f32 @dx.op.rayQuery_CandidateTriangleObjectPosition.f32( + i32, ; DXIL OpCode + i32, ; RayQuery Handle + i32, ; VertexInTri, immediate constant [0..2] + i32) ; ColumnIndex, immediate constant [0..2] + +; Availability: Shader Model (Version TBD)+ +; Function Attrs: nounwind readonly +declare f32 @dx.op.rayQuery_CommittedTriangleObjectPosition.f32( + i32, ; DXIL OpCode + i32, ; RayQuery Handle + i32, ; VertexInTri, immediate constant [0..2] + i32) ; ColumnIndex, immediate constant [0..2] +``` + +New DXIL operations: `TriangleObjectPosition`, +`RayQuery_CandidateTriangleObjectPosition`, +`RayQuery_CommittedTriangleObjectPosition`. +These accept an immediate constant `VertexInTri`, and immediate constant +`ColumnIndex` to read a single `x`, `y`, or `z` component from the specified +vertex position for the triangle. + +All of these DXIL operations require Shader Model (Version TBD). + +`TriangleObjectPosition` may only be called from entry functions of type +`anyhit` or `closesthit`. + +`TriangleObjectPosition` has `readnone` attribute because it reads fixed state +for the shader invocation. +However, the new RayQuery methods must be `readonly` because they read from +RayQuery state, which is impacted by various other RayQuery methods. + +--- + +### Diagnostic Changes + +--- + +#### Validation Changes + +New Validation: + +* When the VertexInTri or ColumnIndex is not an immediate constant or out of + range: + * `" %select{VertexInTri|ColumnIndex}0 (%1) must be an immediate constant value in range [0..2]"` + +Existing infrastructure for enforcing shader model and shader stage +requirements for DXIL ops will be used. +Existing validation for RayQuery handle will be used. + +--- + +### Runtime Additions + +--- + +#### Runtime information + +Use of any of these new DXIL ops will set the +`RuntimeDataFunctionInfo::MinShaderTarget` shader model to a minimum of (Version TBD) in +the `RDAT` part for the calling function. + +--- + +## Testing + +--- + +### Validation + +* Test shader model requirement for all DXIL ops. +* Test shader stage requirement for `TriangleObjectPosition` op. + * Include called no-inline function usage scenario. +* Test non-constant argument validation with each DXIL op. +* Test out-of-range argument validation with each DXIL op. + +--- + +### Execution + +Testing for triangle object position operations will be added to the existing +Raytracing HLK tests. + +--- + +## Resolved Issues + +--- + +### Return Type + +Other approaches have been proposed for the return type of this intrinsic: + +* Current approach: return built-in struct containing all three vertices as `float3` fields: + * Benefit: all values returned from one call + * Benefit: user can use same struct elsewhere and easily assign to result of call + * Benefit: no appearance of native dynamic indexing support + * Benefit: should work with DXC intrinsic system relatively easily +* Add a vertex index parameter to the intrinsic and return a single position: `float3`: + * Drawback: three calls required to store all vertices in a single variable in HLSL + * Drawback: checking index requires an explicit diagnostic check + * Benefit: A dynamic vertex index would easily lower directly to underlying DXIL op parameter without ugly codegen, if support for this was desired. +* Use a matrix return type: `float3x3`: + * Drawback: It's not really a matrix + * Drawback: language suggests native indexing supported, which would result in ugly codegen + * Drawback: layout isn't obvious +* Use a by-value array return type: `float3[3]`: + * checking static index is automatic + * Drawback: likely difficult to introduce this into intrinsic system + * Drawback: language suggests native indexing supported, which would result in ugly codegen + * Drawback: might want to remove return array-by-value support in future HLSL version, as this is not allowed in C++. +* Use a constant reference-to-array return type: `const float3[3] &`: + * checking static index is automatic + * Drawback: likely difficult to introduce this into intrinsic system + * Drawback: language suggests native indexing supported, which would result in ugly codegen +* Return a special object type that implements the array subscript, returning `float3`: + * Benefit: precedent in DXC intrinsic system for such a device + * Drawback: checking index requires custom diagnostic check + * Drawback: language suggests native indexing supported, which would result in ugly codegen + * Drawback: new special built-in object with special codegen/lowering + * Drawback: three calls+subscript operations required to store all vertices somewhere, unless intermediate object is exposed somehow + * Drawback: potential exposure of intermediate object could complicate things + +**Resolution**: Return built-in struct containing all three positions. + +--- + +### Intrinsic Naming + +`TriangleObjectPositions` doesn't match the name used in SPIR-V, which is more +like `HitTriangleVertexPositions`. Should we adjust naming to align? + +**Resolution**: `TriangleObjectPositions` aligns with our conventions for related +intrinsics. + +--- + +### Share OpCodeClass + +Should RayQuery DXIL methods share OpCodeClass for the DXIL ops? +There doesn't appear to be any reason they couldn't, since they have identical +signatures and function attributes. If so, these could be replaced with +`dx.op.rayQuery_TriangleObjectPosition.f32` which would differentiate between +candidate and committed via the DXIL OpCode. This would reduce the number of +redundant DXIL function declarations, and thus the size of DXIL by a small +amount when both are used. + +This would diverge from other RayQuery methods that are split into different +opcode classes for no good reason. + +**Resolution**: Use separate OpCodeClass for consistency with related ops. + +--- + +### Return type for DXIL ops + +There is some open debate about the return type used for DXIL operations. +The current approach is to return one component at a time, as this matches the +similar pre-existing operations for looking up matrix components for +object/world transforms. Keeping the DXIL operations consistent with the other +operations in the same area would seem to carry less risk and keep the DXIL +more regular. This seems to outweigh a desire to do something special here. + +A couple other options: + +* Use built-in struct containing all positions. + * struct layout up for debate + * actual form in op signature up for debate (return value, return pointer, sret - write to output pointer arg?). +* Use native llvm array type, actual form in op signature up for debate. + +**Resolution**: Keep DXIL op scalar for consistency with other ops. + +--- + +## Open Issues + +--- + +### Built-in struct return type + +`BuiltInTrianglePositions` isn't necessarily the best name for the struct, +so suggestions for a better name are welcome. + +--- + +### Use Availability Attributes + +Instead of custom diagnostics for these functions, we could potentially use +availability attributes for a more general mechanism. For DXC, this will +require some investigation into the intrinsic system to see how these +attributes could be added to intrinsic function declarations that are created +on-demand in a custom way. + +--- + +## Acknowledgments + +* Amar Patel + + + +[dxr-tri-obj-pos]: "TriangleObjectPositions" +[dxr-rq-can-tri-obj-pos]: "RayQuery CandidateTriangleObjectPositions" +[dxr-rq-com-tri-obj-pos]: "RayQuery CommittedTriangleObjectPositions" +[dxr-anyhit]: "AnyHit Shader" +[dxr-closesthit]: "ClosestHit Shader" +[dxr-build-flags]: "D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS" +[dxr-hitkind]: "HitKind()" +[dxr-rq-can-type]: "RayQuery CandidateType" +[dxr-rq-com-status]: "RayQuery CommittedStatus" + + From d8c49195adeb3d233b6eb76163c5d54cd713d6e3 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 11:50:37 -0700 Subject: [PATCH 02/13] Update (Version TBD) to 6.10 --- proposals/NNNN-triangle-object-positions.md | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index dabecab4..ce9b31d8 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -70,7 +70,7 @@ currently hit triangle: `TriangleObjectPositions`. /// \brief Retrieve current hit triangle object-space vertex positions /// \returns position of vertex in object-space /// -/// Minimum shader model: (Version TBD) +/// Minimum shader model: 6.10 /// Allowed shader types: anyhit, closesthit. /// /// Hit kind must be a triangle, where HitKind() returns either @@ -96,7 +96,7 @@ class RayQuery { /// \brief Retrieve candidate hit triangle object-space vertex positions /// \returns position of vertex in object-space /// - /// Minimum shader model: (Version TBD) + /// Minimum shader model: 6.10 /// /// The RayQuery must be in a state where `RayQuery::Proceed()` has returned /// true, and where `RayQuery::CandidateType()` returns @@ -110,7 +110,7 @@ class RayQuery { /// \brief Retrieve committed hit triangle object-space vertex positions /// \returns position of vertex in object-space /// - /// Minimum shader model: (Version TBD) + /// Minimum shader model: 6.10 /// /// The RayQuery must be in a state with a committed triangle hit, /// where `CommittedStatus()` returns @@ -138,7 +138,7 @@ undefined. A shader can check for a triangle hit with [`HitKind()`][dxr-hitkind], [`RayQuery::CandidateType()`][dxr-rq-can-type], or [`CommittedStatus()`][dxr-rq-com-status] depending on the context. -Shader model (Version TBD) is required to use these intrinsics. +Shader model 6.10 is required to use these intrinsics. --- @@ -146,8 +146,8 @@ Shader model (Version TBD) is required to use these intrinsics. New diagnostics: -* When any intrinsic is used and the Shader Model is less than (Version TBD): - * `" is only available on Shader Model (Version TBD) or newer"` +* When any intrinsic is used and the Shader Model is less than 6.10: + * `" is only available on Shader Model 6.10 or newer"` * When the `TriangleObjectPositions` intrinsic is used outside an `anyhit` or `closesthit` shader: * `"TriangleObjectPositions is not available in on Shader Model "` @@ -176,7 +176,7 @@ Existing validation for RayQuery handle will be used. #### Device Capability -Use of Triangle Object Positions intrinsics require Shader Model (Version TBD) and +Use of Triangle Object Positions intrinsics require Shader Model 6.10 and [D3D12_RAYTRACING_TIER_1_0][dxr-tier]. > Note: any raytracing tier requirement is implied by the shader stage @@ -195,7 +195,7 @@ Use of Triangle Object Positions intrinsics require Shader Model (Version TBD) a * Test CodeGen for each new HLSL intrinsic * Test final DXIL output for each HLSL intrinsic * Test static and dynamic vertex index -* Use D3DReflect test to verify min shader model of (Version TBD) with each intrinsic +* Use D3DReflect test to verify min shader model of 6.10 with each intrinsic usage for library target. --- @@ -210,7 +210,7 @@ Use of Triangle Object Positions intrinsics require Shader Model (Version TBD) a ### Interchange Format Additions ```llvm -; Availability: Shader Model (Version TBD)+ +; Availability: Shader Model 6.10+ ; Availability: anyhit,closesthit ; Function Attrs: nounwind readnone declare f32 @dx.op.triangleObjectPosition.f32( @@ -218,7 +218,7 @@ declare f32 @dx.op.triangleObjectPosition.f32( i32, ; VertexInTri, immediate constant [0..2] i32) ; ColumnIndex, immediate constant [0..2] -; Availability: Shader Model (Version TBD)+ +; Availability: Shader Model 6.10+ ; Function Attrs: nounwind readonly declare f32 @dx.op.rayQuery_CandidateTriangleObjectPosition.f32( i32, ; DXIL OpCode @@ -226,7 +226,7 @@ declare f32 @dx.op.rayQuery_CandidateTriangleObjectPosition.f32( i32, ; VertexInTri, immediate constant [0..2] i32) ; ColumnIndex, immediate constant [0..2] -; Availability: Shader Model (Version TBD)+ +; Availability: Shader Model 6.10+ ; Function Attrs: nounwind readonly declare f32 @dx.op.rayQuery_CommittedTriangleObjectPosition.f32( i32, ; DXIL OpCode @@ -242,7 +242,7 @@ These accept an immediate constant `VertexInTri`, and immediate constant `ColumnIndex` to read a single `x`, `y`, or `z` component from the specified vertex position for the triangle. -All of these DXIL operations require Shader Model (Version TBD). +All of these DXIL operations require Shader Model 6.10. `TriangleObjectPosition` may only be called from entry functions of type `anyhit` or `closesthit`. @@ -279,7 +279,7 @@ Existing validation for RayQuery handle will be used. #### Runtime information Use of any of these new DXIL ops will set the -`RuntimeDataFunctionInfo::MinShaderTarget` shader model to a minimum of (Version TBD) in +`RuntimeDataFunctionInfo::MinShaderTarget` shader model to a minimum of 6.10 in the `RDAT` part for the calling function. --- From 4f322154642572b782c34f0990751aac4900c6ad Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 11:52:02 -0700 Subject: [PATCH 03/13] Resolve 'use availability attributes' open issue --- proposals/NNNN-triangle-object-positions.md | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index ce9b31d8..50879b3e 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -394,6 +394,18 @@ A couple other options: --- +### Use Availability Attributes + +Instead of custom diagnostics for these functions, we could potentially use +availability attributes for a more general mechanism. For DXC, this will +require some investigation into the intrinsic system to see how these +attributes could be added to intrinsic function declarations that are created +on-demand in a custom way. + +**Resolution**: This seems worthwhile to investigate in Clang but out of scope for DXC. + +--- + ## Open Issues --- @@ -405,16 +417,6 @@ so suggestions for a better name are welcome. --- -### Use Availability Attributes - -Instead of custom diagnostics for these functions, we could potentially use -availability attributes for a more general mechanism. For DXC, this will -require some investigation into the intrinsic system to see how these -attributes could be added to intrinsic function declarations that are created -on-demand in a custom way. - ---- - ## Acknowledgments * Amar Patel From 7fea56254708c1d5785c31550196f7ef53abad03 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 11:55:53 -0700 Subject: [PATCH 04/13] Unresolve 'return type for DXIL ops' open issue --- proposals/NNNN-triangle-object-positions.md | 43 +++++++++++---------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index 50879b3e..ae69fc83 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -374,26 +374,6 @@ opcode classes for no good reason. --- -### Return type for DXIL ops - -There is some open debate about the return type used for DXIL operations. -The current approach is to return one component at a time, as this matches the -similar pre-existing operations for looking up matrix components for -object/world transforms. Keeping the DXIL operations consistent with the other -operations in the same area would seem to carry less risk and keep the DXIL -more regular. This seems to outweigh a desire to do something special here. - -A couple other options: - -* Use built-in struct containing all positions. - * struct layout up for debate - * actual form in op signature up for debate (return value, return pointer, sret - write to output pointer arg?). -* Use native llvm array type, actual form in op signature up for debate. - -**Resolution**: Keep DXIL op scalar for consistency with other ops. - ---- - ### Use Availability Attributes Instead of custom diagnostics for these functions, we could potentially use @@ -417,6 +397,29 @@ so suggestions for a better name are welcome. --- +### Return type for DXIL ops + +There is some open debate about the return type used for DXIL operations. +The current approach is to return one component at a time, as this matches the +similar pre-existing operations for looking up matrix components for +object/world transforms. Keeping the DXIL operations consistent with the other +operations in the same area would seem to carry less risk and keep the DXIL +more regular. This seems to outweigh a desire to do something special here. + +A couple other options: + +* Use built-in struct containing all positions. + * struct layout up for debate + * actual form in op signature up for debate (return value, return pointer, sret - write to output pointer arg?). +* Use native llvm array type, actual form in op signature up for debate. +* Leverage shader model 6.9 vectorized DXIL and return + * one `<3 x float>` per call, taking a vertex ID as a parameter + * one `<9 x float>` with all values at once + +**Proposed Resolution**: Keep DXIL op scalar for consistency with other ops. + +--- + ## Acknowledgments * Amar Patel From 86c9657eb52d2354b80ffec0aeab18638e44fa49 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 12:19:36 -0700 Subject: [PATCH 05/13] Add SER HitObject accessors --- proposals/NNNN-triangle-object-positions.md | 64 ++++++++++++++++----- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index ae69fc83..cc14f1bc 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -75,7 +75,7 @@ currently hit triangle: `TriangleObjectPositions`. /// /// Hit kind must be a triangle, where HitKind() returns either /// HIT_KIND_TRIANGLE_FRONT_FACE (254) or HIT_KIND_TRIANGLE_BACK_FACE (255), -/// otherwise undefined behavior results. +/// otherwise results are undefined. /// /// Ordering of positions returned is based on the order used to build the /// acceleration structure, and must match barycentric ordering. @@ -100,8 +100,8 @@ class RayQuery { /// /// The RayQuery must be in a state where `RayQuery::Proceed()` has returned /// true, and where `RayQuery::CandidateType()` returns - /// `CANDIDATE_TYPE::CANDIDATE_NON_OPAQUE_TRIANGLE`, otherwise undefined - /// behavior results. + /// `CANDIDATE_TYPE::CANDIDATE_NON_OPAQUE_TRIANGLE`, otherwise results + /// are undefined. /// /// Ordering of positions returned is based on the order used to build the /// acceleration structure, and must match barycentric ordering. @@ -114,8 +114,8 @@ class RayQuery { /// /// The RayQuery must be in a state with a committed triangle hit, /// where `CommittedStatus()` returns - /// `COMMITTED_STATUS::COMMITTED_TRIANGLE_HIT`, otherwise undefined behavior - /// results. + /// `COMMITTED_STATUS::COMMITTED_TRIANGLE_HIT`, otherwise results are + /// undefined. /// /// Ordering of positions returned is based on the order used to build the /// acceleration structure, and must match barycentric ordering. @@ -123,10 +123,29 @@ class RayQuery { }; ``` +One new intrinsic method for `HitObject` to retrieve triangle object-space +positions: + +```c++ +/// \brief Retrieve current hit triangle object-space vertex positions +/// \returns position of vertex in object-space +/// +/// Minimum shader model: 6.10 +/// +/// Hit kind must be a triangle, where dx::HitObject::GetHitKind() returns +/// HIT_KIND_TRIANGLE_FRONT_FACE (254) or HIT_KIND_TRIANGLE_BACK_FACE (255), +/// or else results are undefined. +/// +/// Ordering of positions returned is based on the order used to build the +/// acceleration structure, and must match barycentric ordering. +BuiltInTriangleHitPositions dx::HitObject::TriangleObjectPositions() const; +``` + These return the object-space position for all vertices that make up the triangle for a hit. The hit is the current hit inside an [AnyHit][dxr-anyhit] or [ClosestHit][dxr-closesthit] shader, or -the candidate or committed hit state of a RayQuery object. +the candidate or committed hit state of a RayQuery object, or the +committed hit state of a HitObject. May only be used if the hit BLAS was built with `D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DATA_ACCESS` @@ -136,7 +155,8 @@ otherwise behavior is undefined. These intrinsics may only be used with a triangle hit, otherwise behavior is undefined. A shader can check for a triangle hit with [`HitKind()`][dxr-hitkind], [`RayQuery::CandidateType()`][dxr-rq-can-type], or -[`CommittedStatus()`][dxr-rq-com-status] depending on the context. +[`CommittedStatus()`][dxr-rq-com-status], or +[`dx::HitObject::GetHitKind()`](dxr-ser-hit-kind) depending on the context. Shader model 6.10 is required to use these intrinsics. @@ -167,6 +187,7 @@ New Validation: Existing infrastructure for enforcing shader model and shader stage requirements for DXIL ops will be used. Existing validation for RayQuery handle will be used. +Existing validation for HitObject handle will be used. --- @@ -179,9 +200,15 @@ Existing validation for RayQuery handle will be used. Use of Triangle Object Positions intrinsics require Shader Model 6.10 and [D3D12_RAYTRACING_TIER_1_0][dxr-tier]. +Use of RayQuery intrinsics require Shader Model 6.10 and +[D3D12_RAYTRACING_TIER_1_1][dxr-tier]. + +Use of HitObject intrinsics require Shader Model 6.10 and +[D3D12_RATRACING_TIER_1_2][dxr-tier]. + > Note: any raytracing tier requirement is implied by the shader stage -> requirement or use of RayQuery, so no other changes are required in the -> compiler, aside from the shader model requirement. +> requirement or use of RayQuery or use of HitObject, so no other changes +> are required in the compiler, aside from the shader model requirement. --- @@ -207,7 +234,7 @@ Use of Triangle Object Positions intrinsics require Shader Model 6.10 and --- -### Interchange Format Additions +### DXIL Additions ```llvm ; Availability: Shader Model 6.10+ @@ -233,11 +260,20 @@ declare f32 @dx.op.rayQuery_CommittedTriangleObjectPosition.f32( i32, ; RayQuery Handle i32, ; VertexInTri, immediate constant [0..2] i32) ; ColumnIndex, immediate constant [0..2] + +; Availability: Shader Model 6.10+ +; Function Attrs: nounwind readonly +declare f32 @dx.op.hitObject_TriangleObjectPosition.f32( + i32, ; DXIL OpCode + %dx.types.HitObject, ; HitObject handle + i32, ; VertexInTri, immediate constant [0..2] + i32) ; ColumnIndex, immediate constant [0..2] ``` New DXIL operations: `TriangleObjectPosition`, `RayQuery_CandidateTriangleObjectPosition`, -`RayQuery_CommittedTriangleObjectPosition`. +`RayQuery_CommittedTriangleObjectPosition`, +`HitObject_TriangleObjectPosition`. These accept an immediate constant `VertexInTri`, and immediate constant `ColumnIndex` to read a single `x`, `y`, or `z` component from the specified vertex position for the triangle. @@ -327,12 +363,13 @@ Other approaches have been proposed for the return type of this intrinsic: * Drawback: language suggests native indexing supported, which would result in ugly codegen * Drawback: layout isn't obvious * Use a by-value array return type: `float3[3]`: - * checking static index is automatic + * Benefit: checking static index is automatic + * Benefit: convergence with SPIR-V * Drawback: likely difficult to introduce this into intrinsic system * Drawback: language suggests native indexing supported, which would result in ugly codegen * Drawback: might want to remove return array-by-value support in future HLSL version, as this is not allowed in C++. * Use a constant reference-to-array return type: `const float3[3] &`: - * checking static index is automatic + * Benefit: checking static index is automatic * Drawback: likely difficult to introduce this into intrinsic system * Drawback: language suggests native indexing supported, which would result in ugly codegen * Return a special object type that implements the array subscript, returning `float3`: @@ -435,5 +472,6 @@ A couple other options: [dxr-hitkind]: "HitKind()" [dxr-rq-can-type]: "RayQuery CandidateType" [dxr-rq-com-status]: "RayQuery CommittedStatus" +[dxr-ser-hit-kind]: "dx::HitObject::GetHitKind()" From 13e2a6c5744442ba9b5833877c1aa75040c81d91 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 12:30:52 -0700 Subject: [PATCH 06/13] Add SPIR-V implementation details --- proposals/NNNN-triangle-object-positions.md | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index cc14f1bc..3fb4c8d3 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -290,6 +290,34 @@ RayQuery state, which is impacted by various other RayQuery methods. --- +### SPIR-V Mapping + +The `TriangleObjectPositions()` HLSL intrinsic can be implemented against the +[`SPV_KHR_ray_tracing_position_fetch`](spv-ext) extension by effectively +using the following inline HLSL: + +```c++ +[[vk::builtin("HitTriangleVertexPositionsKHR")]] +float3 HitTriangleVertexPositionsKHR[3]; + +inline BuiltInTrianglePositions TriangleObjectPositions() +{ + BuiltInTrianglePositions result; + result.p0 = HitTriangleVertexPositionsKHR[0]; + result.p1 = HitTriangleVertexPositionsKHR[1]; + result.p2 = HitTriangleVertexPositionsKHR[2]; + return result; +} +``` + +The `RayQuery` methods can be implemented against the same extension by mapping +HLSL intrinsic to the `OpRayQueryGetIntersectionTriangleVertexPositionsKHR` +opcode, with `Intersection` set to `RayQueryCandidateIntersectionKHR` for +`CandidateTriangleObjectPositions`, and `Intersection` set to +`RayQueryCommittedIntersectionKHR` for `CommittedTriangleObjectPositions`. + +--- + ### Diagnostic Changes --- From 7b13cb9db667376976e8ca8e62dc55d2968b3ba4 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Mon, 8 Sep 2025 14:04:17 -0700 Subject: [PATCH 07/13] Delete a few duplicate sections --- proposals/NNNN-triangle-object-positions.md | 22 --------------------- 1 file changed, 22 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index 3fb4c8d3..d9bccde4 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -318,28 +318,6 @@ opcode, with `Intersection` set to `RayQueryCandidateIntersectionKHR` for --- -### Diagnostic Changes - ---- - -#### Validation Changes - -New Validation: - -* When the VertexInTri or ColumnIndex is not an immediate constant or out of - range: - * `" %select{VertexInTri|ColumnIndex}0 (%1) must be an immediate constant value in range [0..2]"` - -Existing infrastructure for enforcing shader model and shader stage -requirements for DXIL ops will be used. -Existing validation for RayQuery handle will be used. - ---- - -### Runtime Additions - ---- - #### Runtime information Use of any of these new DXIL ops will set the From d854df16efb6597abed519858fcaca1612d366f4 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 11 Sep 2025 09:12:00 -0700 Subject: [PATCH 08/13] Apply suggestions from code review Co-authored-by: Damyan Pepper --- proposals/NNNN-triangle-object-positions.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index d9bccde4..3b5ca7de 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -1,12 +1,12 @@ - - -# HLSL TriangleObjectPositions - -* Proposal: [NNNN](NNNN-triangle-object-positions.md) -* Author(s): [Tex Riddell](https://github.com/tex3d), [Jesse Natalie](https://github.com/jenatali) -* Sponsor: [Jesse Natalie](https://github.com/jenatali) -* Status: **Under Consideration** - +--- +title: NNNN - TriangleObjectPositions +params: + authors: + - tex3d: Tex Riddell + - jenatali: Jesse Natalie + sponsors: + - jenatali: Jesse Natalie + status: Under Review --- ## Introduction @@ -480,4 +480,3 @@ A couple other options: [dxr-rq-com-status]: "RayQuery CommittedStatus" [dxr-ser-hit-kind]: "dx::HitObject::GetHitKind()" - From 48f75eb42016afe5d2cc5bb488d744040206481b Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 11 Sep 2025 09:46:11 -0700 Subject: [PATCH 09/13] Fix link formatting --- proposals/NNNN-triangle-object-positions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index 3b5ca7de..747a7420 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -198,13 +198,13 @@ Existing validation for HitObject handle will be used. #### Device Capability Use of Triangle Object Positions intrinsics require Shader Model 6.10 and -[D3D12_RAYTRACING_TIER_1_0][dxr-tier]. +[D3D12_RAYTRACING_TIER_1_0](dxr-tier). Use of RayQuery intrinsics require Shader Model 6.10 and -[D3D12_RAYTRACING_TIER_1_1][dxr-tier]. +[D3D12_RAYTRACING_TIER_1_1](dxr-tier). Use of HitObject intrinsics require Shader Model 6.10 and -[D3D12_RATRACING_TIER_1_2][dxr-tier]. +[D3D12_RATRACING_TIER_1_2](dxr-tier). > Note: any raytracing tier requirement is implied by the shader stage > requirement or use of RayQuery or use of HitObject, so no other changes From b82021e9e4931362f892eda00ac03651b8012a1e Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 11 Sep 2025 09:48:15 -0700 Subject: [PATCH 10/13] More link fixes --- proposals/NNNN-triangle-object-positions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index 747a7420..83d79a77 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -156,7 +156,7 @@ These intrinsics may only be used with a triangle hit, otherwise behavior is undefined. A shader can check for a triangle hit with [`HitKind()`][dxr-hitkind], [`RayQuery::CandidateType()`][dxr-rq-can-type], or [`CommittedStatus()`][dxr-rq-com-status], or -[`dx::HitObject::GetHitKind()`](dxr-ser-hit-kind) depending on the context. +[`dx::HitObject::GetHitKind()`][dxr-ser-hit-kind] depending on the context. Shader model 6.10 is required to use these intrinsics. @@ -479,4 +479,5 @@ A couple other options: [dxr-rq-can-type]: "RayQuery CandidateType" [dxr-rq-com-status]: "RayQuery CommittedStatus" [dxr-ser-hit-kind]: "dx::HitObject::GetHitKind()" +[dxr-tier]: "D3D12_RAYTRACING_TIER" From d0d19f0be1732194e47533ddbff46101f1e7dced Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 11 Sep 2025 09:49:29 -0700 Subject: [PATCH 11/13] One more try --- proposals/NNNN-triangle-object-positions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index 83d79a77..c9b79358 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -198,13 +198,13 @@ Existing validation for HitObject handle will be used. #### Device Capability Use of Triangle Object Positions intrinsics require Shader Model 6.10 and -[D3D12_RAYTRACING_TIER_1_0](dxr-tier). +[D3D12_RAYTRACING_TIER_1_0][dxr-tier]. Use of RayQuery intrinsics require Shader Model 6.10 and -[D3D12_RAYTRACING_TIER_1_1](dxr-tier). +[D3D12_RAYTRACING_TIER_1_1][dxr-tier]. Use of HitObject intrinsics require Shader Model 6.10 and -[D3D12_RATRACING_TIER_1_2](dxr-tier). +[D3D12_RATRACING_TIER_1_2][dxr-tier]. > Note: any raytracing tier requirement is implied by the shader stage > requirement or use of RayQuery or use of HitObject, so no other changes From 1bb0d12019c579bc91b7f814cc707838bab676e8 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 11 Sep 2025 10:24:59 -0700 Subject: [PATCH 12/13] Remove excess dividers --- proposals/NNNN-triangle-object-positions.md | 52 --------------------- 1 file changed, 52 deletions(-) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/NNNN-triangle-object-positions.md index c9b79358..b48cee26 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/NNNN-triangle-object-positions.md @@ -15,8 +15,6 @@ This proposal adds intrinsics that can be called from an Any hit or Closest hit shader to obtain the positions of the vertices for the triangle that has been hit. ---- - ## Motivation Developers often need to know the positions of the vertices for the triangle @@ -29,8 +27,6 @@ If developers can access this data from their shader code then this will remove the need have a duplicate copy of it. In addition, this will provide drivers with opportunities to optimize the data layout for their implementations. ---- - ## Proposed solution Add intrinsics to look up the object-space vertex positions of the triangle for @@ -41,12 +37,8 @@ For context, see related sections in DirectX Raytracing Specification: [RayQuery::CandidateTriangleObjectPositions][dxr-rq-can-tri-obj-pos], [RayQuery::CommittedTriangleObjectPositions][dxr-rq-com-tri-obj-pos]. ---- - ## Detailed design ---- - ### HLSL Additions A new built-in structure for returning all three object-space triangle @@ -160,8 +152,6 @@ undefined. A shader can check for a triangle hit with Shader model 6.10 is required to use these intrinsics. ---- - ### Diagnostic Changes New diagnostics: @@ -174,8 +164,6 @@ New diagnostics: > Open Issue: [Use Availability Attributes](#use-availability-attributes) ---- - #### Validation Changes New Validation: @@ -189,12 +177,8 @@ requirements for DXIL ops will be used. Existing validation for RayQuery handle will be used. Existing validation for HitObject handle will be used. ---- - ### Runtime Additions ---- - #### Device Capability Use of Triangle Object Positions intrinsics require Shader Model 6.10 and @@ -210,12 +194,8 @@ Use of HitObject intrinsics require Shader Model 6.10 and > requirement or use of RayQuery or use of HitObject, so no other changes > are required in the compiler, aside from the shader model requirement. ---- - ## Testing ---- - ### Compiler output * Test AST generation for each new HLSL intrinsic @@ -225,15 +205,11 @@ Use of HitObject intrinsics require Shader Model 6.10 and * Use D3DReflect test to verify min shader model of 6.10 with each intrinsic usage for library target. ---- - ### Diagnostics * Test shader model diagnostic for each new HLSL intrinsic. * Test shader stage diagnostic for `TriangleObjectPositions` intrinsic. ---- - ### DXIL Additions ```llvm @@ -288,8 +264,6 @@ for the shader invocation. However, the new RayQuery methods must be `readonly` because they read from RayQuery state, which is impacted by various other RayQuery methods. ---- - ### SPIR-V Mapping The `TriangleObjectPositions()` HLSL intrinsic can be implemented against the @@ -316,20 +290,14 @@ opcode, with `Intersection` set to `RayQueryCandidateIntersectionKHR` for `CandidateTriangleObjectPositions`, and `Intersection` set to `RayQueryCommittedIntersectionKHR` for `CommittedTriangleObjectPositions`. ---- - #### Runtime information Use of any of these new DXIL ops will set the `RuntimeDataFunctionInfo::MinShaderTarget` shader model to a minimum of 6.10 in the `RDAT` part for the calling function. ---- - ## Testing ---- - ### Validation * Test shader model requirement for all DXIL ops. @@ -338,19 +306,13 @@ the `RDAT` part for the calling function. * Test non-constant argument validation with each DXIL op. * Test out-of-range argument validation with each DXIL op. ---- - ### Execution Testing for triangle object position operations will be added to the existing Raytracing HLK tests. ---- - ## Resolved Issues ---- - ### Return Type Other approaches have been proposed for the return type of this intrinsic: @@ -388,8 +350,6 @@ Other approaches have been proposed for the return type of this intrinsic: **Resolution**: Return built-in struct containing all three positions. ---- - ### Intrinsic Naming `TriangleObjectPositions` doesn't match the name used in SPIR-V, which is more @@ -398,8 +358,6 @@ like `HitTriangleVertexPositions`. Should we adjust naming to align? **Resolution**: `TriangleObjectPositions` aligns with our conventions for related intrinsics. ---- - ### Share OpCodeClass Should RayQuery DXIL methods share OpCodeClass for the DXIL ops? @@ -415,8 +373,6 @@ opcode classes for no good reason. **Resolution**: Use separate OpCodeClass for consistency with related ops. ---- - ### Use Availability Attributes Instead of custom diagnostics for these functions, we could potentially use @@ -427,19 +383,13 @@ on-demand in a custom way. **Resolution**: This seems worthwhile to investigate in Clang but out of scope for DXC. ---- - ## Open Issues ---- - ### Built-in struct return type `BuiltInTrianglePositions` isn't necessarily the best name for the struct, so suggestions for a better name are welcome. ---- - ### Return type for DXIL ops There is some open debate about the return type used for DXIL operations. @@ -461,8 +411,6 @@ A couple other options: **Proposed Resolution**: Keep DXIL op scalar for consistency with other ops. ---- - ## Acknowledgments * Amar Patel From 6a64bb34bdc4bc3d49e835e91dc5f6cff1820b57 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Thu, 11 Sep 2025 12:58:48 -0700 Subject: [PATCH 13/13] Assign 0041 --- ...le-object-positions.md => 0041-triangle-object-positions.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{NNNN-triangle-object-positions.md => 0041-triangle-object-positions.md} (99%) diff --git a/proposals/NNNN-triangle-object-positions.md b/proposals/0041-triangle-object-positions.md similarity index 99% rename from proposals/NNNN-triangle-object-positions.md rename to proposals/0041-triangle-object-positions.md index b48cee26..097380d3 100644 --- a/proposals/NNNN-triangle-object-positions.md +++ b/proposals/0041-triangle-object-positions.md @@ -1,5 +1,5 @@ --- -title: NNNN - TriangleObjectPositions +title: 0041 - TriangleObjectPositions params: authors: - tex3d: Tex Riddell