diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 94e153d664..067345edd1 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -2426,6 +2426,14 @@ ID Name Description 309 VectorReduceAnd Bitwise AND reduction of the vector returning a scalar 310 VectorReduceOr Bitwise OR reduction of the vector returning a scalar 311 FDot computes the n-dimensional vector dot-product +312 ClusterID Returns the user-defined ClusterID of the intersected CLAS +313 RayQuery_CandidateClusterID returns candidate hit cluster ID +314 RayQuery_CommittedClusterID returns committed hit cluster ID +315 HitObject_ClusterID Returns the cluster ID of this committed hit +316 TriangleObjectPosition Returns triangle vertices in object space as <9 x float> +317 RayQuery_CandidateTriangleObjectPosition Returns candidate triangle vertices in object space as <9 x float> +318 RayQuery_CommittedTriangleObjectPosition Returns committed triangle vertices in object space as <9 x float> +319 HitObject_TriangleObjectPosition Returns triangle vertices in object space as <9 x float> === ===================================================== ======================================================================================================================================================================================================================= diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index d66f14a1e9..6a4d3dd8e8 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -676,6 +676,7 @@ enum class OpCode : unsigned { AllocateRayQuery = 178, // allocates space for RayQuery and return handle AllocateRayQuery2 = 258, // allocates space for RayQuery and return handle RayQuery_Abort = 181, // aborts a ray query + RayQuery_CandidateClusterID = 313, // returns candidate hit cluster ID RayQuery_CandidateGeometryIndex = 203, // returns candidate hit geometry index RayQuery_CandidateInstanceContributionToHitGroupIndex = 214, // returns candidate hit InstanceContributionToHitGroupIndex @@ -696,6 +697,8 @@ enum class OpCode : unsigned { 193, // returns candidate triangle hit barycentrics RayQuery_CandidateTriangleFrontFace = 191, // returns if current candidate triangle is front facing + RayQuery_CandidateTriangleObjectPosition = + 317, // Returns candidate triangle vertices in object space as <9 x float> RayQuery_CandidateTriangleRayT = 199, // returns float representing the parametric point on the ray for the // current candidate triangle hit. @@ -709,6 +712,7 @@ enum class OpCode : unsigned { 182, // commits a non opaque triangle hit RayQuery_CommitProceduralPrimitiveHit = 183, // commits a procedural primitive hit + RayQuery_CommittedClusterID = 314, // returns committed hit cluster ID RayQuery_CommittedGeometryIndex = 209, // returns committed hit geometry index RayQuery_CommittedInstanceContributionToHitGroupIndex = 215, // returns committed hit InstanceContributionToHitGroupIndex @@ -732,6 +736,8 @@ enum class OpCode : unsigned { 194, // returns committed triangle hit barycentrics RayQuery_CommittedTriangleFrontFace = 192, // returns if current committed triangle is front facing + RayQuery_CommittedTriangleObjectPosition = + 318, // Returns committed triangle vertices in object space as <9 x float> RayQuery_CommittedWorldToObject3x4 = 189, // returns matrix for transforming from world-space to object-space // for a Committed hit. @@ -832,6 +838,10 @@ enum class OpCode : unsigned { RayTMin = 153, // float representing the parametric starting point for the ray. + // Raytracing System Values + TriangleObjectPosition = + 316, // Returns triangle vertices in object space as <9 x float> + // Raytracing hit uint System Values HitKind = 143, // Returns the value passed as HitKind in ReportIntersection(). // If intersection was reported by fixed-function triangle @@ -851,7 +861,8 @@ enum class OpCode : unsigned { PrimitiveIndex = 161, // PrimitiveIndex for raytracing shaders // Raytracing uint System Values - RayFlags = 144, // uint containing the current ray flags. + ClusterID = 312, // Returns the user-defined ClusterID of the intersected CLAS + RayFlags = 144, // uint containing the current ray flags. // Resources - gather TextureGather = 73, // gathers the four texels that would be used in a @@ -914,6 +925,7 @@ enum class OpCode : unsigned { // Shader Execution Reordering HitObject_Attributes = 289, // Returns the attributes set for this HitObject + HitObject_ClusterID = 315, // Returns the cluster ID of this committed hit HitObject_FromRayQuery = 263, // Creates a new HitObject representing a // committed hit from a RayQuery HitObject_FromRayQueryWithAttrs = @@ -949,6 +961,8 @@ enum class OpCode : unsigned { 286, // Returns the shader table index set for this HitObject HitObject_TraceRay = 262, // Analogous to TraceRay but without invoking CH/MS // and returns the intermediate state as a HitObject + HitObject_TriangleObjectPosition = + 319, // Returns triangle vertices in object space as <9 x float> HitObject_WorldRayDirection = 276, // Returns the ray direction in world space HitObject_WorldRayOrigin = 275, // Returns the ray origin in world space HitObject_WorldToObject3x4 = 280, // Returns the world to object space @@ -1089,7 +1103,7 @@ enum class OpCode : unsigned { NumOpCodes_Dxil_1_8 = 258, NumOpCodes_Dxil_1_9 = 312, - NumOpCodes = 312 // exclusive last value of enumeration + NumOpCodes = 320 // exclusive last value of enumeration }; // OPCODE-ENUM:END @@ -1213,8 +1227,10 @@ enum class OpCodeClass : unsigned { AllocateRayQuery, AllocateRayQuery2, RayQuery_Abort, + RayQuery_CandidateTriangleObjectPosition, RayQuery_CommitNonOpaqueTriangleHit, RayQuery_CommitProceduralPrimitiveHit, + RayQuery_CommittedTriangleObjectPosition, RayQuery_Proceed, RayQuery_StateMatrix, RayQuery_StateScalar, @@ -1288,6 +1304,9 @@ enum class OpCodeClass : unsigned { RayTCurrent, RayTMin, + // Raytracing System Values + TriangleObjectPosition, + // Raytracing hit uint System Values HitKind, @@ -1300,6 +1319,7 @@ enum class OpCodeClass : unsigned { PrimitiveIndex, // Raytracing uint System Values + ClusterID, RayFlags, // Resources - gather @@ -1355,6 +1375,7 @@ enum class OpCodeClass : unsigned { HitObject_StateScalar, HitObject_StateVector, HitObject_TraceRay, + HitObject_TriangleObjectPosition, MaybeReorderThread, // Synchronization @@ -1425,7 +1446,7 @@ enum class OpCodeClass : unsigned { NumOpClasses_Dxil_1_8 = 174, NumOpClasses_Dxil_1_9 = 196, - NumOpClasses = 196 // exclusive last value of enumeration + NumOpClasses = 201 // exclusive last value of enumeration }; // OPCODECLASS-ENUM:END diff --git a/include/dxc/DXIL/DxilInstructions.h b/include/dxc/DXIL/DxilInstructions.h index 726d9615ac..550eadf8b4 100644 --- a/include/dxc/DXIL/DxilInstructions.h +++ b/include/dxc/DXIL/DxilInstructions.h @@ -10231,5 +10231,213 @@ struct DxilInst_FDot { llvm::Value *get_b() const { return Instr->getOperand(2); } void set_b(llvm::Value *val) { Instr->setOperand(2, val); } }; + +/// This instruction Returns the user-defined ClusterID of the intersected CLAS +struct DxilInst_ClusterID { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_ClusterID(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::ClusterID); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (1 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } +}; + +/// This instruction returns candidate hit cluster ID +struct DxilInst_RayQuery_CandidateClusterID { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_RayQuery_CandidateClusterID(llvm::Instruction *pInstr) + : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::RayQuery_CandidateClusterID); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (2 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_rayQueryHandle = 1, + }; + // Accessors + llvm::Value *get_rayQueryHandle() const { return Instr->getOperand(1); } + void set_rayQueryHandle(llvm::Value *val) { Instr->setOperand(1, val); } +}; + +/// This instruction returns committed hit cluster ID +struct DxilInst_RayQuery_CommittedClusterID { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_RayQuery_CommittedClusterID(llvm::Instruction *pInstr) + : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::RayQuery_CommittedClusterID); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (2 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_rayQueryHandle = 1, + }; + // Accessors + llvm::Value *get_rayQueryHandle() const { return Instr->getOperand(1); } + void set_rayQueryHandle(llvm::Value *val) { Instr->setOperand(1, val); } +}; + +/// This instruction Returns the cluster ID of this committed hit +struct DxilInst_HitObject_ClusterID { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_HitObject_ClusterID(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::HitObject_ClusterID); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (2 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_hitObject = 1, + }; + // Accessors + llvm::Value *get_hitObject() const { return Instr->getOperand(1); } + void set_hitObject(llvm::Value *val) { Instr->setOperand(1, val); } +}; + +/// This instruction Returns triangle vertices in object space as <9 x float> +struct DxilInst_TriangleObjectPosition { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_TriangleObjectPosition(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::TriangleObjectPosition); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (1 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } +}; + +/// This instruction Returns candidate triangle vertices in object space as <9 x +/// float> +struct DxilInst_RayQuery_CandidateTriangleObjectPosition { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_RayQuery_CandidateTriangleObjectPosition(llvm::Instruction *pInstr) + : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::RayQuery_CandidateTriangleObjectPosition); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (2 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_rayQueryHandle = 1, + }; + // Accessors + llvm::Value *get_rayQueryHandle() const { return Instr->getOperand(1); } + void set_rayQueryHandle(llvm::Value *val) { Instr->setOperand(1, val); } +}; + +/// This instruction Returns committed triangle vertices in object space as <9 x +/// float> +struct DxilInst_RayQuery_CommittedTriangleObjectPosition { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_RayQuery_CommittedTriangleObjectPosition(llvm::Instruction *pInstr) + : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::RayQuery_CommittedTriangleObjectPosition); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (2 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_rayQueryHandle = 1, + }; + // Accessors + llvm::Value *get_rayQueryHandle() const { return Instr->getOperand(1); } + void set_rayQueryHandle(llvm::Value *val) { Instr->setOperand(1, val); } +}; + +/// This instruction Returns triangle vertices in object space as <9 x float> +struct DxilInst_HitObject_TriangleObjectPosition { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_HitObject_TriangleObjectPosition(llvm::Instruction *pInstr) + : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::HitObject_TriangleObjectPosition); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (2 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_hitObject = 1, + }; + // Accessors + llvm::Value *get_hitObject() const { return Instr->getOperand(1); } + void set_hitObject(llvm::Value *val) { Instr->setOperand(1, val); } +}; // INSTR-HELPER:END } // namespace hlsl diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index 9902ef8d14..a723b3716c 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -2714,6 +2714,82 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = { 1, {{0x400}}, {{0x3}}}, // Overloads: (pOverloadType)->getElementType(_y)) @@ -6044,6 +6142,56 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { A(pETy); A(pETy); break; + + // Raytracing uint System Values + case OpCode::ClusterID: + A(pI32); + A(pI32); + break; + + // Inline Ray Query + case OpCode::RayQuery_CandidateClusterID: + A(pI32); + A(pI32); + A(pI32); + break; + case OpCode::RayQuery_CommittedClusterID: + A(pI32); + A(pI32); + A(pI32); + break; + + // Shader Execution Reordering + case OpCode::HitObject_ClusterID: + A(pI32); + A(pI32); + A(pHit); + break; + + // Raytracing System Values + case OpCode::TriangleObjectPosition: + VEC9(pETy); + A(pI32); + break; + + // Inline Ray Query + case OpCode::RayQuery_CandidateTriangleObjectPosition: + VEC9(pETy); + A(pI32); + A(pI32); + break; + case OpCode::RayQuery_CommittedTriangleObjectPosition: + VEC9(pETy); + A(pI32); + A(pI32); + break; + + // Shader Execution Reordering + case OpCode::HitObject_TriangleObjectPosition: + VEC9(pETy); + A(pI32); + A(pHit); + break; // OPCODE-OLOAD-FUNCS:END default: DXASSERT(false, "otherwise unhandled case"); @@ -6380,6 +6528,10 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::HitObject_PrimitiveIndex: case OpCode::HitObject_HitKind: case OpCode::HitObject_ShaderTableIndex: + case OpCode::ClusterID: + case OpCode::RayQuery_CandidateClusterID: + case OpCode::RayQuery_CommittedClusterID: + case OpCode::HitObject_ClusterID: return IntegerType::get(Ctx, 32); case OpCode::CalculateLOD: case OpCode::DomainLocation: @@ -6449,6 +6601,12 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { StructType *ST = cast(Ty); return ST->getElementType(0); } + case OpCode::TriangleObjectPosition: + case OpCode::RayQuery_CandidateTriangleObjectPosition: + case OpCode::RayQuery_CommittedTriangleObjectPosition: + case OpCode::HitObject_TriangleObjectPosition: + // These return <9 x float> vectors directly + return cast(Ty)->getElementType(); case OpCode::MatVecMul: case OpCode::MatVecMulAdd: if (FT->getNumParams() < 2) diff --git a/tools/clang/test/DXILValidation/clusterid_passing.ll b/tools/clang/test/DXILValidation/clusterid_passing.ll new file mode 100644 index 0000000000..0ee24f2e46 --- /dev/null +++ b/tools/clang/test/DXILValidation/clusterid_passing.ll @@ -0,0 +1,74 @@ +; RUN: %dxv %s | FileCheck %s + +; CHECK: Validation succeeded. + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +%dx.types.Handle = type { i8* } +%struct.Payload = type { <4 x float> } +%struct.BuiltInTriangleIntersectionAttributes = type { <2 x float> } +%dx.types.ResourceProperties = type { i32, i32 } +%dx.types.HitObject = type { i8* } + +; Function Attrs: nounwind +define void @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z"(%struct.Payload* noalias nocapture %payload, %struct.BuiltInTriangleIntersectionAttributes* nocapture readnone %attr) #0 { + %1 = call i32 @dx.op.clusterID.i32(i32 312) ; ClusterID() + ret void +} + +; Function Attrs: nounwind +define void @"\01?test_raygeneration@@YAXXZ"() #0 { + %1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop() + %2 = call i32 @dx.op.hitObject_StateScalar.i32(i32 315, %dx.types.HitObject %1) ; HitObject_ClusterID(hitObject) + %3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags) + %4 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 313, i32 %3) ; RayQuery_CandidateClusterID(rayQueryHandle) + %5 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 314, i32 %3) ; RayQuery_CommittedClusterID(rayQueryHandle) + ret void +} + +; Function Attrs: nounwind readnone +declare i32 @dx.op.clusterID.i32(i32) #1 + +; Function Attrs: nounwind readnone +declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1 + +; Function Attrs: nounwind readnone +declare i32 @dx.op.hitObject_StateScalar.i32(i32, %dx.types.HitObject) #1 + +; Function Attrs: nounwind +declare i32 @dx.op.allocateRayQuery(i32, i32) #0 + +; Function Attrs: nounwind readonly +declare i32 @dx.op.rayQuery_StateScalar.i32(i32, i32) #2 + +attributes #0 = { nounwind } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readonly } + +!dx.version = !{!0} +!dx.valver = !{!0} +!dx.shaderModel = !{!1} +!dx.typeAnnotations = !{!2} +!dx.dxrPayloadAnnotations = !{!9} +!dx.entryPoints = !{!12, !14, !17} + +!0 = !{i32 1, i32 10} +!1 = !{!"lib", i32 6, i32 10} +!2 = !{i32 1, void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !3, void ()* @"\01?test_raygeneration@@YAXXZ", !8} +!3 = !{!4, !6, !7} +!4 = !{i32 1, !5, !5} +!5 = !{} +!6 = !{i32 2, !5, !5} +!7 = !{i32 0, !5, !5} +!8 = !{!4} +!9 = !{i32 0, %struct.Payload undef, !10} +!10 = !{!11} +!11 = !{i32 0, i32 33} +!12 = !{null, !"", null, null, !13} +!13 = !{i32 0, i64 33554432} +!14 = !{void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", null, null, !15} +!15 = !{i32 8, i32 10, i32 6, i32 16, i32 7, i32 8, i32 5, !16} +!16 = !{i32 0} +!17 = !{void ()* @"\01?test_raygeneration@@YAXXZ", !"\01?test_raygeneration@@YAXXZ", null, null, !18} +!18 = !{i32 8, i32 7, i32 5, !16} diff --git a/tools/clang/test/DXILValidation/triangle_position_passing.ll b/tools/clang/test/DXILValidation/triangle_position_passing.ll new file mode 100644 index 0000000000..0591120fb2 --- /dev/null +++ b/tools/clang/test/DXILValidation/triangle_position_passing.ll @@ -0,0 +1,77 @@ +; RUN: %dxv %s | FileCheck %s + +; CHECK: Validation succeeded. + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +%dx.types.Handle = type { i8* } +%struct.Payload = type { <4 x float> } +%struct.BuiltInTriangleIntersectionAttributes = type { <2 x float> } +%dx.types.ResourceProperties = type { i32, i32 } +%dx.types.HitObject = type { i8* } + +; Function Attrs: nounwind +define void @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z"(%struct.Payload* noalias nocapture %payload, %struct.BuiltInTriangleIntersectionAttributes* nocapture readnone %attr) #0 { + %1 = call <9 x float> @dx.op.triangleObjectPosition.f32(i32 316) ; TriangleObjectPosition() + ret void +} + +; Function Attrs: nounwind +define void @"\01?test_raygeneration@@YAXXZ"() #0 { + %1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop() + %2 = call <9 x float> @dx.op.hitObject_TriangleObjectPosition.f32(i32 319, %dx.types.HitObject %1) ; HitObject_TriangleObjectPosition(hitObject) + %3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags) + %4 = call <9 x float> @dx.op.rayQuery_CandidateTriangleObjectPosition.f32(i32 317, i32 %3) ; RayQuery_CandidateTriangleObjectPosition(rayQueryHandle) + %5 = call <9 x float> @dx.op.rayQuery_CommittedTriangleObjectPosition.f32(i32 318, i32 %3) ; RayQuery_CommittedTriangleObjectPosition(rayQueryHandle) + ret void +} + +; Function Attrs: nounwind readnone +declare <9 x float> @dx.op.triangleObjectPosition.f32(i32) #1 + +; Function Attrs: nounwind readnone +declare <9 x float> @dx.op.hitObject_TriangleObjectPosition.f32(i32, %dx.types.HitObject) #1 + +; Function Attrs: nounwind readnone +declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1 + +; Function Attrs: nounwind +declare i32 @dx.op.allocateRayQuery(i32, i32) #0 + +; Function Attrs: nounwind readonly +declare <9 x float> @dx.op.rayQuery_CandidateTriangleObjectPosition.f32(i32, i32) #2 + +; Function Attrs: nounwind readonly +declare <9 x float> @dx.op.rayQuery_CommittedTriangleObjectPosition.f32(i32, i32) #2 + +attributes #0 = { nounwind } +attributes #1 = { nounwind readnone } +attributes #2 = { nounwind readonly } + +!dx.version = !{!0} +!dx.valver = !{!0} +!dx.shaderModel = !{!1} +!dx.typeAnnotations = !{!2} +!dx.dxrPayloadAnnotations = !{!9} +!dx.entryPoints = !{!12, !14, !17} + +!0 = !{i32 1, i32 10} +!1 = !{!"lib", i32 6, i32 10} +!2 = !{i32 1, void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !3, void ()* @"\01?test_raygeneration@@YAXXZ", !8} +!3 = !{!4, !6, !7} +!4 = !{i32 1, !5, !5} +!5 = !{} +!6 = !{i32 2, !5, !5} +!7 = !{i32 0, !5, !5} +!8 = !{!4} +!9 = !{i32 0, %struct.Payload undef, !10} +!10 = !{!11} +!11 = !{i32 0, i32 33} +!12 = !{null, !"", null, null, !13} +!13 = !{i32 0, i64 33554432} +!14 = !{void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", null, null, !15} +!15 = !{i32 8, i32 10, i32 6, i32 16, i32 7, i32 8, i32 5, !16} +!16 = !{i32 0} +!17 = !{void ()* @"\01?test_raygeneration@@YAXXZ", !"\01?test_raygeneration@@YAXXZ", null, null, !18} +!18 = !{i32 8, i32 7, i32 5, !16} diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 5d86d1a3e9..599e2d859d 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -878,6 +878,48 @@ def populate_categories_and_models(self): ).split(","): self.name_idx[i].category = "Linear Algebra Operations" self.name_idx[i].shader_model = 6, 10 + for i in ("ClusterID").split(","): + self.name_idx[i].category = "Raytracing uint System Values" + self.name_idx[i].shader_model = 6, 10 + self.name_idx[i].shader_stages = ( + "library", + "anyhit", + "closesthit", + ) + for i in ("TriangleObjectPosition").split(","): + self.name_idx[i].category = "Raytracing System Values" + self.name_idx[i].shader_model = 6, 10 + self.name_idx[i].shader_stages = ( + "library", + "anyhit", + "closesthit", + ) + for i in ("RayQuery_CandidateClusterID,RayQuery_CommittedClusterID").split(","): + self.name_idx[i].category = "Inline Ray Query" + self.name_idx[i].shader_model = 6, 10 + for i in ( + "RayQuery_CandidateTriangleObjectPosition,RayQuery_CommittedTriangleObjectPosition" + ).split(","): + self.name_idx[i].category = "Inline Ray Query" + self.name_idx[i].shader_model = 6, 10 + for i in ("HitObject_ClusterID").split(","): + self.name_idx[i].category = "Shader Execution Reordering" + self.name_idx[i].shader_model = 6, 10 + self.name_idx[i].shader_stages = ( + "library", + "raygeneration", + "closesthit", + "miss", + ) + for i in ("HitObject_TriangleObjectPosition").split(","): + self.name_idx[i].category = "Shader Execution Reordering" + self.name_idx[i].shader_model = 6, 10 + self.name_idx[i].shader_stages = ( + "library", + "raygeneration", + "closesthit", + "miss", + ) def populate_llvm_instructions(self): # Add instructions that map to LLVM instructions. @@ -6384,6 +6426,123 @@ def UFI(name, **mappings): % next_op_idx ) + # Clustered Geometry + self.add_dxil_op( + "ClusterID", + next_op_idx, + "ClusterID", + "Returns the user-defined ClusterID of the intersected CLAS", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateClusterID", + next_op_idx, + "RayQuery_StateScalar", + "returns candidate hit cluster ID", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedClusterID", + next_op_idx, + "RayQuery_StateScalar", + "returns committed hit cluster ID", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "HitObject_ClusterID", + next_op_idx, + "HitObject_StateScalar", + "Returns the cluster ID of this committed hit", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "hit_object", "hitObject", "hit"), + ], + ) + next_op_idx += 1 + + # Triangle Object Positions + self.add_dxil_op( + "TriangleObjectPosition", + next_op_idx, + "TriangleObjectPosition", + "Returns triangle vertices in object space as <9 x float>", + "f", + "rn", + [ + db_dxil_param(0, "$vec9", "", "operation result"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateTriangleObjectPosition", + next_op_idx, + "RayQuery_CandidateTriangleObjectPosition", + "Returns candidate triangle vertices in object space as <9 x float>", + "f", + "ro", + [ + db_dxil_param(0, "$vec9", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedTriangleObjectPosition", + next_op_idx, + "RayQuery_CommittedTriangleObjectPosition", + "Returns committed triangle vertices in object space as <9 x float>", + "f", + "ro", + [ + db_dxil_param(0, "$vec9", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "HitObject_TriangleObjectPosition", + next_op_idx, + "HitObject_TriangleObjectPosition", + "Returns triangle vertices in object space as <9 x float>", + "f", + "rn", + [ + db_dxil_param(0, "$vec9", "", "operation result"), + db_dxil_param(2, "hit_object", "hitObject", "hit"), + ], + ) + next_op_idx += 1 + + # NOTE!! Update and uncomment when DXIL 1.10 opcodes are finalized: + # self.set_op_count_for_version(1, 10, next_op_idx) + # assert next_op_idx == NNN, ( + # "NNN is expected next operation index but encountered %d and thus opcodes are broken" + # % next_op_idx + # ) + # Set interesting properties. self.build_indices() for ( diff --git a/utils/hct/hctdb_instrhelp.py b/utils/hct/hctdb_instrhelp.py index 9debd6e07f..3f28db1fbc 100644 --- a/utils/hct/hctdb_instrhelp.py +++ b/utils/hct/hctdb_instrhelp.py @@ -617,6 +617,7 @@ def print_opfunc_table(self): "u8": "A(pI8);", "v": "A(pV);", "$vec4": "VEC4(pETy);", + "$vec9": "VEC9(pETy);", "w": "A(pWav);", "SamplePos": "A(pPos);", "udt": "A(udt);", @@ -674,6 +675,7 @@ def print_opfunc_oload_type(self): # grouped by the set of overload parameter indices. extended_dict = collections.OrderedDict() struct_list = [] + vec9_list = [] # For $vec9 operations that return native vectors extended_list = [] for instr in self.instrs: @@ -696,7 +698,11 @@ def print_opfunc_oload_type(self): continue if ret_ty.startswith(vec_ty): - struct_list.append(instr.name) + # $vec9 returns native <9 x float> vectors, not struct wrappers + if ret_ty == "$vec9": + vec9_list.append(instr.name) + else: + struct_list.append(instr.name) continue in_param_ty = False @@ -813,6 +819,15 @@ def print_opfunc_oload_type(self): line = line + "}" print(line) + # Generate code for $vec9 operations (native <9 x float> vectors) + if vec9_list: + line = "" + for opcode in vec9_list: + line = line + "case OpCode::{name}".format(name=opcode + ":\n") + line = line + " // These return <9 x float> vectors directly\n" + line = line + " return cast(Ty)->getElementType();" + print(line) + for instr in extended_list: # Collect indices for overloaded return and types, make a tuple of # indices the key, and add the opcode to a list of opcodes for that