diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 29e198610f..e9514212dd 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -3062,11 +3062,21 @@ Given width, offset: Opcode Table ExperimentalOps, id=32768: Experimental DXIL operations -========== =============== ================ -ID Name Description -========== =============== ================ -2147483648 ExperimentalNop nop does nothing -========== =============== ================ +========== ======================================== ================================================================== +ID Name Description +========== ======================================== ================================================================== +2147483648 ExperimentalNop nop does nothing +2147483649 GetGroupWaveIndex returns the index of the wave in the thread group +2147483650 GetGroupWaveCount returns the number of waves in the thread group +2147483651 ClusterID returns the user-defined ClusterID of the intersected CLAS +2147483652 RayQuery_CandidateClusterID returns candidate hit cluster ID +2147483653 RayQuery_CommittedClusterID returns committed hit cluster ID +2147483654 HitObject_ClusterID returns the cluster ID of this committed hit +2147483655 TriangleObjectPosition returns triangle vertices in object space as <9 x float> +2147483656 RayQuery_CandidateTriangleObjectPosition returns candidate triangle vertices in object space as <9 x float> +2147483657 RayQuery_CommittedTriangleObjectPosition returns committed triangle vertices in object space as <9 x float> +2147483658 HitObject_TriangleObjectPosition returns triangle vertices in object space as <9 x float> +========== ======================================== ================================================================== .. OPCODES-RST:END diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index 6f1f1d66ea..83615dabfd 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -511,10 +511,34 @@ namespace ExperimentalOps { static const OpCodeTableID TableID = OpCodeTableID::ExperimentalOps; // Enumeration for ExperimentalOps DXIL operations enum class OpCode : unsigned { + // Group Wave Ops + GetGroupWaveCount = 2, // returns the number of waves in the thread group + GetGroupWaveIndex = 1, // returns the index of the wave in the thread group + + // Inline Ray Query + RayQuery_CandidateClusterID = 4, // returns candidate hit cluster ID + RayQuery_CandidateTriangleObjectPosition = + 8, // returns candidate triangle vertices in object space as <9 x float> + RayQuery_CommittedClusterID = 5, // returns committed hit cluster ID + RayQuery_CommittedTriangleObjectPosition = + 9, // returns committed triangle vertices in object space as <9 x float> + // No-op ExperimentalNop = 0, // nop does nothing - NumOpCodes = 1, // exclusive last value of enumeration + // Raytracing System Values + TriangleObjectPosition = + 7, // returns triangle vertices in object space as <9 x float> + + // Raytracing uint System Values + ClusterID = 3, // returns the user-defined ClusterID of the intersected CLAS + + // Shader Execution Reordering + HitObject_ClusterID = 6, // returns the cluster ID of this committed hit + HitObject_TriangleObjectPosition = + 10, // returns triangle vertices in object space as <9 x float> + + NumOpCodes = 11, // exclusive last value of enumeration }; } // namespace ExperimentalOps static const unsigned NumOpCodeTables = 2; @@ -1131,6 +1155,38 @@ enum class OpCode : unsigned { // OpCodeTableID = 32768 // ExperimentalOps EXP_OPCODE(ExperimentalOps, ExperimentalNop), // nop does nothing + EXP_OPCODE( + ExperimentalOps, + GetGroupWaveIndex), // returns the index of the wave in the thread group + EXP_OPCODE( + ExperimentalOps, + GetGroupWaveCount), // returns the number of waves in the thread group + EXP_OPCODE( + ExperimentalOps, + ClusterID), // returns the user-defined ClusterID of the intersected CLAS + EXP_OPCODE(ExperimentalOps, + RayQuery_CandidateClusterID), // returns candidate hit cluster ID + EXP_OPCODE(ExperimentalOps, + RayQuery_CommittedClusterID), // returns committed hit cluster ID + EXP_OPCODE( + ExperimentalOps, + HitObject_ClusterID), // returns the cluster ID of this committed hit + EXP_OPCODE(ExperimentalOps, + TriangleObjectPosition), // returns triangle vertices in object + // space as <9 x float> + EXP_OPCODE( + ExperimentalOps, + RayQuery_CandidateTriangleObjectPosition), // returns candidate triangle + // vertices in object space as + // <9 x float> + EXP_OPCODE( + ExperimentalOps, + RayQuery_CommittedTriangleObjectPosition), // returns committed triangle + // vertices in object space as + // <9 x float> + EXP_OPCODE(ExperimentalOps, + HitObject_TriangleObjectPosition), // returns triangle vertices in + // object space as <9 x float> }; // OPCODE-ENUM:END #undef EXP_OPCODE @@ -1242,6 +1298,10 @@ enum class OpCodeClass : unsigned { // Graphics shader ViewID, + // Group Wave Ops + GetGroupWaveCount, + GetGroupWaveIndex, + // Helper Lanes IsHelperLane, @@ -1261,8 +1321,10 @@ enum class OpCodeClass : unsigned { AllocateRayQuery, AllocateRayQuery2, RayQuery_Abort, + RayQuery_CandidateTriangleObjectPosition, RayQuery_CommitNonOpaqueTriangleHit, RayQuery_CommitProceduralPrimitiveHit, + RayQuery_CommittedTriangleObjectPosition, RayQuery_Proceed, RayQuery_StateMatrix, RayQuery_StateScalar, @@ -1339,6 +1401,9 @@ enum class OpCodeClass : unsigned { RayTCurrent, RayTMin, + // Raytracing System Values + TriangleObjectPosition, + // Raytracing hit uint System Values HitKind, @@ -1351,6 +1416,7 @@ enum class OpCodeClass : unsigned { PrimitiveIndex, // Raytracing uint System Values + ClusterID, RayFlags, // Resources - gather @@ -1406,6 +1472,7 @@ enum class OpCodeClass : unsigned { HitObject_StateScalar, HitObject_StateVector, HitObject_TraceRay, + HitObject_TriangleObjectPosition, MaybeReorderThread, // Synchronization @@ -1465,7 +1532,7 @@ enum class OpCodeClass : unsigned { NodeOutputIsValid, OutputComplete, - NumOpClasses = 197, // exclusive last value of enumeration + NumOpClasses = 204, // exclusive last value of enumeration }; // OPCODECLASS-ENUM:END diff --git a/include/dxc/DXIL/DxilInstructions.h b/include/dxc/DXIL/DxilInstructions.h index 52a3efaaac..2bef121009 100644 --- a/include/dxc/DXIL/DxilInstructions.h +++ b/include/dxc/DXIL/DxilInstructions.h @@ -10251,5 +10251,253 @@ struct DxilInst_ExperimentalNop { // Metadata bool requiresUniformInputs() const { return false; } }; + +/// This instruction returns the index of the wave in the thread group +struct DxilInst_GetGroupWaveIndex { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_GetGroupWaveIndex(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst(Instr, + hlsl::OP::OpCode::GetGroupWaveIndex); + } + // 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 the number of waves in the thread group +struct DxilInst_GetGroupWaveCount { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_GetGroupWaveCount(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst(Instr, + hlsl::OP::OpCode::GetGroupWaveCount); + } + // 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 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/include/dxc/HlslIntrinsicOp.h b/include/dxc/HlslIntrinsicOp.h index e1c1b3e7f5..aae269cfa1 100644 --- a/include/dxc/HlslIntrinsicOp.h +++ b/include/dxc/HlslIntrinsicOp.h @@ -13,6 +13,7 @@ enum class IntrinsicOp { IOP_Barrier = 5, IOP_CallShader = 6, IOP_CheckAccessFullyMapped = 7, + IOP_ClusterID = 397, IOP_CreateResourceFromHeap = 8, IOP_D3DCOLORtoUBYTE4 = 9, IOP_DeviceMemoryBarrier = 10, @@ -25,6 +26,8 @@ enum class IntrinsicOp { IOP_EvaluateAttributeSnapped = 17, IOP_GeometryIndex = 18, IOP_GetAttributeAtVertex = 19, + IOP_GetGroupWaveCount = 395, + IOP_GetGroupWaveIndex = 396, IOP_GetRemainingRecursionLevels = 20, IOP_GetRenderTargetSampleCount = 21, IOP_GetRenderTargetSamplePosition = 22, @@ -75,6 +78,7 @@ enum class IntrinsicOp { IOP_ReportHit = 67, IOP_SetMeshOutputCounts = 68, IOP_TraceRay = 69, + IOP_TriangleObjectPosition = 401, IOP_WaveActiveAllEqual = 70, IOP_WaveActiveAllTrue = 71, IOP_WaveActiveAnyTrue = 72, @@ -302,6 +306,7 @@ enum class IntrinsicOp { MOP_WriteSamplerFeedbackGrad = 286, MOP_WriteSamplerFeedbackLevel = 287, MOP_Abort = 288, + MOP_CandidateClusterID = 398, MOP_CandidateGeometryIndex = 289, MOP_CandidateInstanceContributionToHitGroupIndex = 290, MOP_CandidateInstanceID = 291, @@ -314,12 +319,14 @@ enum class IntrinsicOp { MOP_CandidateProceduralPrimitiveNonOpaque = 298, MOP_CandidateTriangleBarycentrics = 299, MOP_CandidateTriangleFrontFace = 300, + MOP_CandidateTriangleObjectPosition = 402, MOP_CandidateTriangleRayT = 301, MOP_CandidateType = 302, MOP_CandidateWorldToObject3x4 = 303, MOP_CandidateWorldToObject4x3 = 304, MOP_CommitNonOpaqueTriangleHit = 305, MOP_CommitProceduralPrimitiveHit = 306, + MOP_CommittedClusterID = 399, MOP_CommittedGeometryIndex = 307, MOP_CommittedInstanceContributionToHitGroupIndex = 308, MOP_CommittedInstanceID = 309, @@ -333,6 +340,7 @@ enum class IntrinsicOp { MOP_CommittedStatus = 317, MOP_CommittedTriangleBarycentrics = 318, MOP_CommittedTriangleFrontFace = 319, + MOP_CommittedTriangleObjectPosition = 403, MOP_CommittedWorldToObject3x4 = 320, MOP_CommittedWorldToObject4x3 = 321, MOP_Proceed = 322, @@ -341,6 +349,7 @@ enum class IntrinsicOp { MOP_TraceRayInline = 325, MOP_WorldRayDirection = 326, MOP_WorldRayOrigin = 327, + MOP_DxHitObject_ClusterID = 400, MOP_DxHitObject_FromRayQuery = 363, MOP_DxHitObject_GetAttributes = 364, MOP_DxHitObject_GetGeometryIndex = 365, @@ -369,6 +378,7 @@ enum class IntrinsicOp { MOP_DxHitObject_MakeNop = 358, MOP_DxHitObject_SetShaderTableIndex = 388, MOP_DxHitObject_TraceRay = 389, + MOP_DxHitObject_TriangleObjectPosition = 404, IOP_DxMaybeReorderThread = 359, MOP_Count = 328, MOP_FinishedCrossGroupSharing = 329, @@ -401,7 +411,7 @@ enum class IntrinsicOp { IOP_usign = 355, MOP_InterlockedUMax = 356, MOP_InterlockedUMin = 357, - Num_Intrinsics = 395, + Num_Intrinsics = 405, }; inline bool HasUnsignedIntrinsicOpcode(IntrinsicOp opcode) { switch (opcode) { diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index e03682959a..1e38138347 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -2728,6 +2728,100 @@ static const OP::OpCodeProperty ExperimentalOps_OpCodeProps[] = { 0, {}, {}}, // Overloads: v + + // Group Wave Ops + {OC::GetGroupWaveIndex, + "GetGroupWaveIndex", + OCC::GetGroupWaveIndex, + "getGroupWaveIndex", + Attribute::ReadNone, + 0, + {}, + {}}, // Overloads: v + {OC::GetGroupWaveCount, + "GetGroupWaveCount", + OCC::GetGroupWaveCount, + "getGroupWaveCount", + Attribute::ReadNone, + 0, + {}, + {}}, // Overloads: v + + // Raytracing uint System Values + {OC::ClusterID, + "ClusterID", + OCC::ClusterID, + "clusterID", + Attribute::ReadNone, + 0, + {}, + {}}, // Overloads: v + + // Inline Ray Query + {OC::RayQuery_CandidateClusterID, + "RayQuery_CandidateClusterID", + OCC::RayQuery_StateScalar, + "rayQuery_StateScalar", + Attribute::ReadOnly, + 0, + {}, + {}}, // Overloads: v + {OC::RayQuery_CommittedClusterID, + "RayQuery_CommittedClusterID", + OCC::RayQuery_StateScalar, + "rayQuery_StateScalar", + Attribute::ReadOnly, + 0, + {}, + {}}, // Overloads: v + + // Shader Execution Reordering + {OC::HitObject_ClusterID, + "HitObject_ClusterID", + OCC::HitObject_StateScalar, + "hitObject_StateScalar", + Attribute::ReadNone, + 0, + {}, + {}}, // Overloads: v + + // Raytracing System Values + {OC::TriangleObjectPosition, + "TriangleObjectPosition", + OCC::TriangleObjectPosition, + "triangleObjectPosition", + Attribute::ReadNone, + 1, + {{0x2}}, + {{0x0}}}, // Overloads: f + + // Inline Ray Query + {OC::RayQuery_CandidateTriangleObjectPosition, + "RayQuery_CandidateTriangleObjectPosition", + OCC::RayQuery_CandidateTriangleObjectPosition, + "rayQuery_CandidateTriangleObjectPosition", + Attribute::ReadOnly, + 1, + {{0x2}}, + {{0x0}}}, // Overloads: f + {OC::RayQuery_CommittedTriangleObjectPosition, + "RayQuery_CommittedTriangleObjectPosition", + OCC::RayQuery_CommittedTriangleObjectPosition, + "rayQuery_CommittedTriangleObjectPosition", + Attribute::ReadOnly, + 1, + {{0x2}}, + {{0x0}}}, // Overloads: f + + // Shader Execution Reordering + {OC::HitObject_TriangleObjectPosition, + "HitObject_TriangleObjectPosition", + OCC::HitObject_TriangleObjectPosition, + "hitObject_TriangleObjectPosition", + Attribute::ReadNone, + 1, + {{0x2}}, + {{0x0}}}, // Overloads: f }; static_assert(_countof(ExperimentalOps_OpCodeProps) == (size_t)DXIL::ExperimentalOps::OpCode::NumOpCodes, @@ -3066,9 +3160,11 @@ bool OP::IsDxilOpWave(OpCode C) { // WaveReadLaneFirst=118, WaveActiveOp=119, WaveActiveBit=120, // WavePrefixOp=121, QuadReadLaneAt=122, QuadOp=123, WaveAllBitCount=135, // WavePrefixBitCount=136, WaveMatch=165, WaveMultiPrefixOp=166, - // WaveMultiPrefixBitCount=167, QuadVote=222 + // WaveMultiPrefixBitCount=167, QuadVote=222, GetGroupWaveIndex=2147483649, + // GetGroupWaveCount=2147483650 return (110 <= op && op <= 123) || (135 <= op && op <= 136) || - (165 <= op && op <= 167) || op == 222; + (165 <= op && op <= 167) || op == 222 || + (2147483649 <= op && op <= 2147483650); // OPCODE-WAVE:END } @@ -3636,10 +3732,39 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation, return; } // Instructions: MatVecMul=305, MatVecMulAdd=306, OuterProductAccumulate=307, - // VectorAccumulate=308, ExperimentalNop=2147483648 - if ((305 <= op && op <= 308) || op == 2147483648) { + // VectorAccumulate=308, ExperimentalNop=2147483648, + // RayQuery_CandidateClusterID=2147483652, + // RayQuery_CommittedClusterID=2147483653, + // RayQuery_CandidateTriangleObjectPosition=2147483656, + // RayQuery_CommittedTriangleObjectPosition=2147483657 + if ((305 <= op && op <= 308) || op == 2147483648 || + (2147483652 <= op && op <= 2147483653) || + (2147483656 <= op && op <= 2147483657)) { + major = 6; + minor = 10; + return; + } + // Instructions: GetGroupWaveIndex=2147483649, GetGroupWaveCount=2147483650 + if ((2147483649 <= op && op <= 2147483650)) { + major = 6; + minor = 10; + mask = SFLAG(Compute) | SFLAG(Mesh) | SFLAG(Amplification) | SFLAG(Library); + return; + } + // Instructions: ClusterID=2147483651, TriangleObjectPosition=2147483655 + if (op == 2147483651 || op == 2147483655) { major = 6; minor = 10; + mask = SFLAG(Library) | SFLAG(AnyHit) | SFLAG(ClosestHit); + return; + } + // Instructions: HitObject_ClusterID=2147483654, + // HitObject_TriangleObjectPosition=2147483658 + if (op == 2147483654 || op == 2147483658) { + major = 6; + minor = 10; + mask = + SFLAG(Library) | SFLAG(RayGeneration) | SFLAG(ClosestHit) | SFLAG(Miss); return; } // OPCODE-SMMASK:END @@ -6147,6 +6272,66 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { A(pV); A(pI32); break; + + // Group Wave Ops + case OpCode::GetGroupWaveIndex: + A(pI32); + A(pI32); + break; + case OpCode::GetGroupWaveCount: + A(pI32); + A(pI32); + 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: + A(pV); + A(pI32); + break; + + // Inline Ray Query + case OpCode::RayQuery_CandidateTriangleObjectPosition: + A(pV); + A(pI32); + A(pI32); + break; + case OpCode::RayQuery_CommittedTriangleObjectPosition: + A(pV); + A(pI32); + A(pI32); + break; + + // Shader Execution Reordering + case OpCode::HitObject_TriangleObjectPosition: + A(pV); + A(pI32); + A(pHit); + break; // OPCODE-OLOAD-FUNCS:END default: DXASSERT(false, "otherwise unhandled case"); @@ -6438,6 +6623,12 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::ReservedC8: case OpCode::ReservedC9: case OpCode::ExperimentalNop: + case OpCode::GetGroupWaveIndex: + case OpCode::GetGroupWaveCount: + case OpCode::ClusterID: + case OpCode::RayQuery_CandidateClusterID: + case OpCode::RayQuery_CommittedClusterID: + case OpCode::HitObject_ClusterID: return Type::getVoidTy(Ctx); case OpCode::CheckAccessFullyMapped: case OpCode::SampleIndex: @@ -6517,6 +6708,10 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::HitObject_ObjectRayDirection: case OpCode::HitObject_ObjectToWorld3x4: case OpCode::HitObject_WorldToObject3x4: + case OpCode::TriangleObjectPosition: + case OpCode::RayQuery_CandidateTriangleObjectPosition: + case OpCode::RayQuery_CommittedTriangleObjectPosition: + case OpCode::HitObject_TriangleObjectPosition: return Type::getFloatTy(Ctx); case OpCode::MakeDouble: case OpCode::SplitDouble: diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index c9c9bb4c88..7ec0ead0eb 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -7512,7 +7512,30 @@ IntrinsicLower gLowerTable[] = { TranslateOuterProductAccumulate, DXIL::OpCode::OuterProductAccumulate}, {IntrinsicOp::IOP___builtin_VectorAccumulate, TranslateVectorAccumulate, DXIL::OpCode::VectorAccumulate}, + {IntrinsicOp::IOP_isnormal, TrivialIsSpecialFloat, DXIL::OpCode::IsNormal}, + + {IntrinsicOp::IOP_GetGroupWaveIndex, EmptyLower, + DXIL::OpCode::GetGroupWaveIndex}, + {IntrinsicOp::IOP_GetGroupWaveCount, EmptyLower, + DXIL::OpCode::GetGroupWaveCount}, + + {IntrinsicOp::IOP_ClusterID, EmptyLower, DXIL::OpCode::ClusterID}, + {IntrinsicOp::MOP_CandidateClusterID, EmptyLower, + DXIL::OpCode::RayQuery_CandidateClusterID}, + {IntrinsicOp::MOP_CommittedClusterID, EmptyLower, + DXIL::OpCode::RayQuery_CommittedClusterID}, + {IntrinsicOp::MOP_DxHitObject_ClusterID, EmptyLower, + DXIL::OpCode::HitObject_ClusterID}, + + {IntrinsicOp::IOP_TriangleObjectPosition, EmptyLower, + DXIL::OpCode::TriangleObjectPosition}, + {IntrinsicOp::MOP_CandidateTriangleObjectPosition, EmptyLower, + DXIL::OpCode::RayQuery_CandidateTriangleObjectPosition}, + {IntrinsicOp::MOP_CommittedTriangleObjectPosition, EmptyLower, + DXIL::OpCode::RayQuery_CommittedTriangleObjectPosition}, + {IntrinsicOp::MOP_DxHitObject_TriangleObjectPosition, EmptyLower, + DXIL::OpCode::HitObject_TriangleObjectPosition}, }; } // namespace static_assert( diff --git a/utils/hct/gen_intrin_main.txt b/utils/hct/gen_intrin_main.txt index 3fb30781b0..8b10f733a8 100644 --- a/utils/hct/gen_intrin_main.txt +++ b/utils/hct/gen_intrin_main.txt @@ -303,6 +303,8 @@ $type1 [[]] QuadReadAcrossY(in numeric<> value); $type1 [[]] QuadReadAcrossDiagonal(in numeric<> value); bool [[]] QuadAny(in bool cond); bool [[]] QuadAll(in bool cond); +uint [[rn,min_sm=6.10]] GetGroupWaveIndex(); +uint [[rn,min_sm=6.10]] GetGroupWaveCount(); // Raytracing void [[]] TraceRay(in acceleration_struct AccelerationStructure, in uint RayFlags, in uint InstanceInclusionMask, in uint RayContributionToHitGroupIndex, in uint MultiplierForGeometryContributionToHitGroupIndex, in uint MissShaderIndex, in ray_desc Ray, inout udt Payload); @@ -336,6 +338,10 @@ float<3,4> [[rn]] WorldToObject3x4(); float<4,3> [[rn]] ObjectToWorld4x3(); float<4,3> [[rn]] WorldToObject4x3(); +uint [[ro,min_sm=6.10]] ClusterID(); +// TODO: Update return type for TriangleObjectPosition(): +void [[ro,min_sm=6.10]] TriangleObjectPosition(); + // Packed dot products with accumulate: uint [[rn]] dot4add_u8packed(in uint a, in $type1 b, in uint c); int [[rn]] dot4add_i8packed(in uint a, in $type1 b, in int c); @@ -1101,6 +1107,11 @@ float<3> [[ro]] CommittedObjectRayOrigin(); float<3> [[ro]] CommittedObjectRayDirection(); uint [[ro]] CandidateInstanceContributionToHitGroupIndex(); uint [[ro]] CommittedInstanceContributionToHitGroupIndex(); +uint [[ro,min_sm=6.10]] CandidateClusterID(); +uint [[ro,min_sm=6.10]] CommittedClusterID(); +// TODO: Update return type for *TriangleObjectPosition(): +void [[ro,min_sm=6.10]] CandidateTriangleObjectPosition(); +void [[ro,min_sm=6.10]] CommittedTriangleObjectPosition(); } namespace @@ -1135,6 +1146,9 @@ namespace DxHitObjectMethods { void [[class_prefix,min_sm=6.9]] GetAttributes(out udt Attributes); void [[class_prefix,min_sm=6.9]] SetShaderTableIndex(in uint RecordIndex); uint [[ro,class_prefix,min_sm=6.9]] LoadLocalRootTableConstant(in uint RootConstantOffsetInBytes); + uint [[ro,class_prefix,min_sm=6.10]] ClusterID(); + // TODO: Update return type for TriangleObjectPosition(): + void [[ro,class_prefix,min_sm=6.10]] TriangleObjectPosition(); } namespace namespace DxIntrinsics { diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 490ce8080f..2ae135ebc8 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -501,6 +501,12 @@ def get_all_insts(self): for i in table: yield i + def get_insts_by_names(self, *names): + "Get instructions by strings of names separated by commas." + for names_to_split in names: + for name in names_to_split.split(","): + yield self.name_idx[name.strip()] + def add_dxil_op_table(self, id, name, doc): "Add a new DXIL operation table." assert name not in self.op_table_idx, f"DXIL op table '{name}' already exists" @@ -1043,9 +1049,70 @@ def populate_categories_and_models_ExperimentalOps(self): # Note: Experimental ops must be set to a shader model higher than the # most recent release until infrastructure is in place to opt-in to # experimental ops and the validator can force use of the PREVIEW hash. - for i in "ExperimentalNop".split(","): - self.name_idx[i].category = "No-op" - self.name_idx[i].shader_model = 6, 10 + + # Update experimental_sm to released + 1 minor version when highest + # released shader model is updated in latest-release.json. + experimental_sm = 6, 10 + + insts = self.get_insts_by_names + + for i in insts("ExperimentalNop"): + i.category = "No-op" + i.shader_model = experimental_sm + + # Group Wave Index / Count + for i in insts("GetGroupWaveIndex,GetGroupWaveCount"): + i.category = "Group Wave Ops" + i.shader_model = experimental_sm + i.shader_stages = ("compute", "mesh", "amplification", "library") + i.is_wave = True + + # Clustered Geometry + for i in insts("ClusterID"): + i.category = "Raytracing uint System Values" + i.shader_model = experimental_sm + i.shader_stages = ( + "library", + "anyhit", + "closesthit", + ) + for i in insts("RayQuery_CandidateClusterID,RayQuery_CommittedClusterID"): + i.category = "Inline Ray Query" + i.shader_model = experimental_sm + for i in insts("HitObject_ClusterID"): + i.category = "Shader Execution Reordering" + i.shader_model = experimental_sm + i.shader_stages = ( + "library", + "raygeneration", + "closesthit", + "miss", + ) + + # Triangle Object Positions + for i in insts("TriangleObjectPosition"): + i.category = "Raytracing System Values" + i.shader_model = experimental_sm + i.shader_stages = ( + "library", + "anyhit", + "closesthit", + ) + for i in insts( + "RayQuery_CandidateTriangleObjectPosition", + "RayQuery_CommittedTriangleObjectPosition", + ): + i.category = "Inline Ray Query" + i.shader_model = experimental_sm + for i in insts("HitObject_TriangleObjectPosition"): + i.category = "Shader Execution Reordering" + i.shader_model = experimental_sm + i.shader_stages = ( + "library", + "raygeneration", + "closesthit", + "miss", + ) def populate_llvm_instructions(self): # Add instructions that map to LLVM instructions. @@ -6063,8 +6130,10 @@ def populate_ExperimentalOps(self): op_table = self.add_dxil_op_table( 0x8000, "ExperimentalOps", "Experimental DXIL operations" ) + add_dxil_op = op_table.add_dxil_op + # Add Nop to test experimental table infrastructure. - op_table.add_dxil_op( + add_dxil_op( "ExperimentalNop", "Nop", "nop does nothing", @@ -6075,6 +6144,112 @@ def populate_ExperimentalOps(self): ], ) + # Group Wave Operations + add_dxil_op( + "GetGroupWaveIndex", + "GetGroupWaveIndex", + "returns the index of the wave in the thread group", + "v", + "rn", + [db_dxil_param(0, "i32", "", "operation result")], + ) + add_dxil_op( + "GetGroupWaveCount", + "GetGroupWaveCount", + "returns the number of waves in the thread group", + "v", + "rn", + [db_dxil_param(0, "i32", "", "operation result")], + ) + + # Clustered Geometry + add_dxil_op( + "ClusterID", + "ClusterID", + "returns the user-defined ClusterID of the intersected CLAS", + "v", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + add_dxil_op( + "RayQuery_CandidateClusterID", + "RayQuery_StateScalar", + "returns candidate hit cluster ID", + "v", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + add_dxil_op( + "RayQuery_CommittedClusterID", + "RayQuery_StateScalar", + "returns committed hit cluster ID", + "v", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + add_dxil_op( + "HitObject_ClusterID", + "HitObject_StateScalar", + "returns the cluster ID of this committed hit", + "v", + "rn", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "hit_object", "hitObject", "hit"), + ], + ) + + # Triangle Object Positions + add_dxil_op( + "TriangleObjectPosition", + "TriangleObjectPosition", + "returns triangle vertices in object space as <9 x float>", + "f", + "rn", + [ + db_dxil_param(0, "v", "", "operation result"), # TODO: $vec9 + ], + ) + add_dxil_op( + "RayQuery_CandidateTriangleObjectPosition", + "RayQuery_CandidateTriangleObjectPosition", + "returns candidate triangle vertices in object space as <9 x float>", + "f", + "ro", + [ + db_dxil_param(0, "v", "", "operation result"), # TODO: $vec9 + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + add_dxil_op( + "RayQuery_CommittedTriangleObjectPosition", + "RayQuery_CommittedTriangleObjectPosition", + "returns committed triangle vertices in object space as <9 x float>", + "f", + "ro", + [ + db_dxil_param(0, "v", "", "operation result"), # TODO: $vec9 + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + add_dxil_op( + "HitObject_TriangleObjectPosition", + "HitObject_TriangleObjectPosition", + "returns triangle vertices in object space as <9 x float>", + "f", + "rn", + [ + db_dxil_param(0, "v", "", "operation result"), # TODO: $vec9 + db_dxil_param(2, "hit_object", "hitObject", "hit"), + ], + ) + def finalize_dxil_operations(self): "Finalize DXIL operations by setting properties and verifying consistency." diff --git a/utils/hct/hlsl_intrinsic_opcodes.json b/utils/hct/hlsl_intrinsic_opcodes.json index eb22fd7464..e2d3c6f290 100644 --- a/utils/hct/hlsl_intrinsic_opcodes.json +++ b/utils/hct/hlsl_intrinsic_opcodes.json @@ -1,6 +1,6 @@ { "IntrinsicOpCodes": { - "Num_Intrinsics": 395, + "Num_Intrinsics": 405, "IOP_AcceptHitAndEndSearch": 0, "IOP_AddUint64": 1, "IOP_AllMemoryBarrier": 2, @@ -395,6 +395,16 @@ "IOP___builtin_MatVecMulAdd": 391, "IOP___builtin_OuterProductAccumulate": 392, "IOP___builtin_VectorAccumulate": 393, - "IOP_isnormal": 394 + "IOP_isnormal": 394, + "IOP_GetGroupWaveCount": 395, + "IOP_GetGroupWaveIndex": 396, + "IOP_ClusterID": 397, + "MOP_CandidateClusterID": 398, + "MOP_CommittedClusterID": 399, + "MOP_DxHitObject_ClusterID": 400, + "IOP_TriangleObjectPosition": 401, + "MOP_CandidateTriangleObjectPosition": 402, + "MOP_CommittedTriangleObjectPosition": 403, + "MOP_DxHitObject_TriangleObjectPosition": 404 } }