Skip to content
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