Skip to content

[SER] HitObject_FromRayQuery[WithAttrs] DXIL opcodes and check-pass #7277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions include/dxc/DXIL/DxilConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -1294,6 +1297,8 @@ enum class OpCodeClass : unsigned {
WriteSamplerFeedbackLevel,

// Shader Execution Reordering
HitObject_FromRayQuery,
HitObject_FromRayQueryWithAttrs,
HitObject_MakeMiss,
HitObject_MakeNop,

Expand Down Expand Up @@ -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

Expand Down
63 changes: 63 additions & 0 deletions include/dxc/DXIL/DxilInstructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<llvm::CallInst>(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<llvm::CallInst>(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;
Expand Down
56 changes: 31 additions & 25 deletions lib/DXIL/DxilOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -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}
46 changes: 44 additions & 2 deletions utils/hct/hctdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand Down Expand Up @@ -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",
Expand Down