diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index 4f8c521851..2146a3ffdb 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -503,7 +503,6 @@ enum class OpCode : unsigned { ReservedA1 = 260, // reserved ReservedA2 = 261, // reserved ReservedB0 = 262, // reserved - ReservedB1 = 263, // reserved ReservedB10 = 272, // reserved ReservedB11 = 273, // reserved ReservedB12 = 274, // reserved @@ -514,7 +513,6 @@ enum class OpCode : unsigned { ReservedB17 = 279, // reserved ReservedB18 = 280, // reserved ReservedB19 = 281, // reserved - ReservedB2 = 264, // reserved ReservedB20 = 282, // reserved ReservedB21 = 283, // reserved ReservedB22 = 284, // reserved @@ -916,6 +914,11 @@ enum class OpCode : unsigned { // operation with a mipmap-level offset // Shader Execution Reordering + HitObject_FromRayQuery = 263, // Creates a new HitObject representing a + // committed hit from a RayQuery + HitObject_FromRayQueryWithAttrs = + 264, // Creates a new HitObject representing a committed hit from a + // RayQuery and committed attributes HitObject_MakeMiss = 265, // Creates a new HitObject representing a miss HitObject_MakeNop = 266, // Creates an empty nop HitObject @@ -1294,6 +1297,8 @@ enum class OpCodeClass : unsigned { WriteSamplerFeedbackLevel, // Shader Execution Reordering + HitObject_FromRayQuery, + HitObject_FromRayQueryWithAttrs, HitObject_MakeMiss, HitObject_MakeNop, @@ -1361,7 +1366,7 @@ enum class OpCodeClass : unsigned { NumOpClasses_Dxil_1_7 = 153, NumOpClasses_Dxil_1_8 = 174, - NumOpClasses = 179 // exclusive last value of enumeration + NumOpClasses = 181 // exclusive last value of enumeration }; // OPCODECLASS-ENUM:END diff --git a/include/dxc/DXIL/DxilInstructions.h b/include/dxc/DXIL/DxilInstructions.h index 6ee22869a5..15f7a1362b 100644 --- a/include/dxc/DXIL/DxilInstructions.h +++ b/include/dxc/DXIL/DxilInstructions.h @@ -8850,6 +8850,69 @@ struct DxilInst_AllocateRayQuery2 { } }; +/// This instruction Creates a new HitObject representing a committed hit from a +/// RayQuery +struct DxilInst_HitObject_FromRayQuery { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_HitObject_FromRayQuery(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::HitObject_FromRayQuery); + } + // 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 Creates a new HitObject representing a committed hit from a +/// RayQuery and committed attributes +struct DxilInst_HitObject_FromRayQueryWithAttrs { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_HitObject_FromRayQueryWithAttrs(llvm::Instruction *pInstr) + : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst( + Instr, hlsl::OP::OpCode::HitObject_FromRayQueryWithAttrs); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (4 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } + // Operand indexes + enum OperandIdx { + arg_rayQueryHandle = 1, + arg_HitKind = 2, + arg_CommittedAttribs = 3, + }; + // Accessors + llvm::Value *get_rayQueryHandle() const { return Instr->getOperand(1); } + void set_rayQueryHandle(llvm::Value *val) { Instr->setOperand(1, val); } + llvm::Value *get_HitKind() const { return Instr->getOperand(2); } + void set_HitKind(llvm::Value *val) { Instr->setOperand(2, val); } + llvm::Value *get_CommittedAttribs() const { return Instr->getOperand(3); } + void set_CommittedAttribs(llvm::Value *val) { Instr->setOperand(3, val); } +}; + /// This instruction Creates a new HitObject representing a miss struct DxilInst_HitObject_MakeMiss { llvm::Instruction *Instr; diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index 0b4c7218d4..1b8c6ebfcf 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -2310,24 +2310,24 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = { 0, {}, {}}, // Overloads: v - {OC::ReservedB1, - "ReservedB1", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::ReservedB2, - "ReservedB2", - OCC::Reserved, - "reserved", - Attribute::None, + + // Shader Execution Reordering + {OC::HitObject_FromRayQuery, + "HitObject_FromRayQuery", + OCC::HitObject_FromRayQuery, + "hitObject_FromRayQuery", + Attribute::ReadOnly, 0, {}, {}}, // Overloads: v - - // Shader Execution Reordering + {OC::HitObject_FromRayQueryWithAttrs, + "HitObject_FromRayQueryWithAttrs", + OCC::HitObject_FromRayQueryWithAttrs, + "hitObject_FromRayQueryWithAttrs", + Attribute::ReadOnly, + 1, + {{0x100}}, + {{0x0}}}, // Overloads: u {OC::HitObject_MakeMiss, "HitObject_MakeMiss", OCC::HitObject_MakeMiss, @@ -3415,8 +3415,10 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation, minor = 9; return; } - // Instructions: HitObject_MakeMiss=265, HitObject_MakeNop=266 - if ((265 <= op && op <= 266)) { + // Instructions: HitObject_FromRayQuery=263, + // HitObject_FromRayQueryWithAttrs=264, HitObject_MakeMiss=265, + // HitObject_MakeNop=266 + if ((263 <= op && op <= 266)) { major = 6; minor = 9; mask = @@ -5584,16 +5586,20 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { A(pV); A(pI32); break; - case OpCode::ReservedB1: - A(pV); + + // Shader Execution Reordering + case OpCode::HitObject_FromRayQuery: + A(pHit); + A(pI32); A(pI32); break; - case OpCode::ReservedB2: - A(pV); + case OpCode::HitObject_FromRayQueryWithAttrs: + A(pHit); + A(pI32); + A(pI32); A(pI32); + A(udt); break; - - // Shader Execution Reordering case OpCode::HitObject_MakeMiss: A(pHit); A(pI32); @@ -5959,6 +5965,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { return nullptr; return FT->getParamType(15); case OpCode::ReportHit: + case OpCode::HitObject_FromRayQueryWithAttrs: if (FT->getNumParams() <= 3) return nullptr; return FT->getParamType(3); @@ -6042,8 +6049,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::ReservedA1: case OpCode::ReservedA2: case OpCode::ReservedB0: - case OpCode::ReservedB1: - case OpCode::ReservedB2: + case OpCode::HitObject_FromRayQuery: case OpCode::HitObject_MakeMiss: case OpCode::HitObject_MakeNop: case OpCode::ReservedB5: diff --git a/tools/clang/test/LitDXILValidation/ser_hitobject_fromrayquery_passing.ll b/tools/clang/test/LitDXILValidation/ser_hitobject_fromrayquery_passing.ll new file mode 100644 index 0000000000..5b0c65fd6b --- /dev/null +++ b/tools/clang/test/LitDXILValidation/ser_hitobject_fromrayquery_passing.ll @@ -0,0 +1,84 @@ +; REQUIRES: dxil-1-9 +; 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 { <3 x float> } +%struct.CustomAttrs = type { float, float } +%dx.types.ResourceProperties = type { i32, i32 } +%dx.types.HitObject = type { i8* } +%struct.RaytracingAccelerationStructure = type { i32 } + +@"\01?RTAS@@3URaytracingAccelerationStructure@@A" = external constant %dx.types.Handle, align 4 + +; Function Attrs: nounwind +declare void @llvm.lifetime.start(i64, i8* nocapture) #0 + +; Function Attrs: nounwind +declare void @llvm.lifetime.end(i64, i8* nocapture) #0 + +; Function Attrs: nounwind +define void @"\01?main@@YAXXZ"() #0 { + %1 = load %dx.types.Handle, %dx.types.Handle* @"\01?RTAS@@3URaytracingAccelerationStructure@@A", align 4 + %2 = alloca %struct.CustomAttrs, align 4 + %3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 5) ; AllocateRayQuery(constRayFlags) + %4 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource) + %5 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %4, %dx.types.ResourceProperties { i32 16, i32 0 }) ; AnnotateHandle(res,props) resource: RTAccelerationStructure + call void @dx.op.rayQuery_TraceRayInline(i32 179, i32 %3, %dx.types.Handle %5, i32 0, i32 255, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float 0.000000e+00, float 9.999000e+03) ; RayQuery_TraceRayInline(rayQueryHandle,accelerationStructure,rayFlags,instanceInclusionMask,origin_X,origin_Y,origin_Z,tMin,direction_X,direction_Y,direction_Z,tMax) + %6 = call %dx.types.HitObject @dx.op.hitObject_FromRayQuery(i32 263, i32 %3) ; HitObject_FromRayQuery(rayQueryHandle) + %7 = call %dx.types.HitObject @dx.op.hitObject_FromRayQueryWithAttrs.struct.CustomAttrs(i32 264, i32 %3, i32 16, %struct.CustomAttrs* nonnull %2) ; HitObject_FromRayQueryWithAttrs(rayQueryHandle,HitKind,CommittedAttribs) + ret void +} + +; Function Attrs: nounwind +declare i32 @dx.op.allocateRayQuery(i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.rayQuery_TraceRayInline(i32, i32, %dx.types.Handle, i32, i32, float, float, float, float, float, float, float, float) #0 + +; Function Attrs: nounwind readonly +declare %dx.types.HitObject @dx.op.hitObject_FromRayQueryWithAttrs.struct.CustomAttrs(i32, i32, i32, %struct.CustomAttrs*) #1 + +; Function Attrs: nounwind readonly +declare %dx.types.HitObject @dx.op.hitObject_FromRayQuery(i32, i32) #1 + +; Function Attrs: nounwind readnone +declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #2 + +; Function Attrs: nounwind readonly +declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #1 + +attributes #0 = { nounwind } +attributes #1 = { nounwind readonly } +attributes #2 = { nounwind readnone } + +!dx.version = !{!0} +!dx.valver = !{!0} +!dx.shaderModel = !{!1} +!dx.resources = !{!2} +!dx.typeAnnotations = !{!6} +!dx.dxrPayloadAnnotations = !{!10} +!dx.entryPoints = !{!13, !15} + +!0 = !{i32 1, i32 9} +!1 = !{!"lib", i32 6, i32 9} +!2 = !{!3, null, null, null} +!3 = !{!4} +!4 = !{i32 0, %struct.RaytracingAccelerationStructure* bitcast (%dx.types.Handle* @"\01?RTAS@@3URaytracingAccelerationStructure@@A" to %struct.RaytracingAccelerationStructure*), !"RTAS", i32 -1, i32 -1, i32 1, i32 16, i32 0, !5} +!5 = !{i32 0, i32 4} +!6 = !{i32 1, void ()* @"\01?main@@YAXXZ", !7} +!7 = !{!8} +!8 = !{i32 1, !9, !9} +!9 = !{} +!10 = !{i32 0, %struct.Payload undef, !11} +!11 = !{!12} +!12 = !{i32 0, i32 8210} +!13 = !{null, !"", null, !2, !14} +!14 = !{i32 0, i64 33554432} +!15 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !16} +!16 = !{i32 8, i32 7, i32 5, !17} +!17 = !{i32 0} diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 0008b752b1..2110bc6393 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -848,7 +848,10 @@ def populate_categories_and_models(self): self.name_idx[i].category = "Extended Command Information" self.name_idx[i].shader_stages = ("vertex",) self.name_idx[i].shader_model = 6, 8 - for i in ("HitObject_MakeMiss,HitObject_MakeNop").split(","): + for i in ( + "HitObject_MakeMiss,HitObject_MakeNop" + + ",HitObject_FromRayQuery,HitObject_FromRayQueryWithAttrs" + ).split(","): self.name_idx[i].category = "Shader Execution Reordering" self.name_idx[i].shader_model = 6, 9 self.name_idx[i].shader_stages = ( @@ -5739,7 +5742,46 @@ def UFI(name, **mappings): next_op_idx = self.reserve_dxil_op_range("ReservedA", next_op_idx, 3) # Shader Execution Reordering - next_op_idx = self.reserve_dxil_op_range("ReservedB", next_op_idx, 3) + next_op_idx = self.reserve_dxil_op_range("ReservedB", next_op_idx, 1) + + self.add_dxil_op( + "HitObject_FromRayQuery", + next_op_idx, + "HitObject_FromRayQuery", + "Creates a new HitObject representing a committed hit from a RayQuery", + "v", + "ro", + [ + db_dxil_param( + 0, "hit_object", "", "HitObject created from RayQuery object" + ), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "HitObject_FromRayQueryWithAttrs", + next_op_idx, + "HitObject_FromRayQueryWithAttrs", + "Creates a new HitObject representing a committed hit from a RayQuery and committed attributes", + "u", + "ro", + [ + db_dxil_param( + 0, "hit_object", "", "HitObject created from RayQuery object" + ), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param( + 3, + "i32", + "HitKind", + "User-specified value in range of 0-127 to identify the type of hit", + ), + db_dxil_param(4, "udt", "CommittedAttribs", "Committed attributes"), + ], + ) + next_op_idx += 1 self.add_dxil_op( "HitObject_MakeMiss",