Skip to content

Commit e73afb0

Browse files
committed
[SER] HitObject_Invoke|TraceRay DXIL opcodes and check-pass test
DXC SER implementation tracker: microsoft#7214
1 parent 206b775 commit e73afb0

File tree

5 files changed

+337
-27
lines changed

5 files changed

+337
-27
lines changed

include/dxc/DXIL/DxilConstants.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,6 @@ enum class OpCode : unsigned {
497497
ReservedA0 = 259, // reserved
498498
ReservedA1 = 260, // reserved
499499
ReservedA2 = 261, // reserved
500-
ReservedB0 = 262, // reserved
501500
ReservedB1 = 263, // reserved
502501
ReservedB10 = 272, // reserved
503502
ReservedB11 = 273, // reserved
@@ -521,7 +520,6 @@ enum class OpCode : unsigned {
521520
ReservedB28 = 290, // reserved
522521
ReservedB29 = 291, // reserved
523522
ReservedB30 = 292, // reserved
524-
ReservedB5 = 267, // reserved
525523
ReservedB6 = 268, // reserved
526524
ReservedB7 = 269, // reserved
527525
ReservedB8 = 270, // reserved
@@ -908,8 +906,12 @@ enum class OpCode : unsigned {
908906
// operation with a mipmap-level offset
909907

910908
// Shader Execution Reordering
909+
HitObject_Invoke = 267, // Represents the invocation of the CH/MS shader
910+
// represented by the HitObject
911911
HitObject_MakeMiss = 265, // Creates a new HitObject representing a miss
912912
HitObject_MakeNop = 266, // Creates an empty nop HitObject
913+
HitObject_TraceRay = 262, // Analogous to TraceRay but without invoking CH/MS
914+
// and returns the intermediate state as a HitObject
913915

914916
// Synchronization
915917
AtomicBinOp = 78, // performs an atomic operation on two operands
@@ -1284,8 +1286,10 @@ enum class OpCodeClass : unsigned {
12841286
WriteSamplerFeedbackLevel,
12851287

12861288
// Shader Execution Reordering
1289+
HitObject_Invoke,
12871290
HitObject_MakeMiss,
12881291
HitObject_MakeNop,
1292+
HitObject_TraceRay,
12891293

12901294
// Synchronization
12911295
AtomicBinOp,
@@ -1351,7 +1355,7 @@ enum class OpCodeClass : unsigned {
13511355
NumOpClasses_Dxil_1_7 = 153,
13521356
NumOpClasses_Dxil_1_8 = 174,
13531357

1354-
NumOpClasses = 177 // exclusive last value of enumeration
1358+
NumOpClasses = 179 // exclusive last value of enumeration
13551359
};
13561360
// OPCODECLASS-ENUM:END
13571361

include/dxc/DXIL/DxilInstructions.h

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8850,6 +8850,92 @@ struct DxilInst_AllocateRayQuery2 {
88508850
}
88518851
};
88528852

8853+
/// This instruction Analogous to TraceRay but without invoking CH/MS and
8854+
/// returns the intermediate state as a HitObject
8855+
struct DxilInst_HitObject_TraceRay {
8856+
llvm::Instruction *Instr;
8857+
// Construction and identification
8858+
DxilInst_HitObject_TraceRay(llvm::Instruction *pInstr) : Instr(pInstr) {}
8859+
operator bool() const {
8860+
return hlsl::OP::IsDxilOpFuncCallInst(Instr,
8861+
hlsl::OP::OpCode::HitObject_TraceRay);
8862+
}
8863+
// Validation support
8864+
bool isAllowed() const { return true; }
8865+
bool isArgumentListValid() const {
8866+
if (16 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
8867+
return false;
8868+
return true;
8869+
}
8870+
// Metadata
8871+
bool requiresUniformInputs() const { return false; }
8872+
// Operand indexes
8873+
enum OperandIdx {
8874+
arg_accelerationStructure = 1,
8875+
arg_rayFlags = 2,
8876+
arg_instanceInclusionMask = 3,
8877+
arg_rayContributionToHitGroupIndex = 4,
8878+
arg_multiplierForGeometryContributionToHitGroupIndex = 5,
8879+
arg_missShaderIndex = 6,
8880+
arg_Origin_X = 7,
8881+
arg_Origin_Y = 8,
8882+
arg_Origin_Z = 9,
8883+
arg_TMin = 10,
8884+
arg_Direction_X = 11,
8885+
arg_Direction_Y = 12,
8886+
arg_Direction_Z = 13,
8887+
arg_TMax = 14,
8888+
arg_payload = 15,
8889+
};
8890+
// Accessors
8891+
llvm::Value *get_accelerationStructure() const {
8892+
return Instr->getOperand(1);
8893+
}
8894+
void set_accelerationStructure(llvm::Value *val) {
8895+
Instr->setOperand(1, val);
8896+
}
8897+
llvm::Value *get_rayFlags() const { return Instr->getOperand(2); }
8898+
void set_rayFlags(llvm::Value *val) { Instr->setOperand(2, val); }
8899+
llvm::Value *get_instanceInclusionMask() const {
8900+
return Instr->getOperand(3);
8901+
}
8902+
void set_instanceInclusionMask(llvm::Value *val) {
8903+
Instr->setOperand(3, val);
8904+
}
8905+
llvm::Value *get_rayContributionToHitGroupIndex() const {
8906+
return Instr->getOperand(4);
8907+
}
8908+
void set_rayContributionToHitGroupIndex(llvm::Value *val) {
8909+
Instr->setOperand(4, val);
8910+
}
8911+
llvm::Value *get_multiplierForGeometryContributionToHitGroupIndex() const {
8912+
return Instr->getOperand(5);
8913+
}
8914+
void set_multiplierForGeometryContributionToHitGroupIndex(llvm::Value *val) {
8915+
Instr->setOperand(5, val);
8916+
}
8917+
llvm::Value *get_missShaderIndex() const { return Instr->getOperand(6); }
8918+
void set_missShaderIndex(llvm::Value *val) { Instr->setOperand(6, val); }
8919+
llvm::Value *get_Origin_X() const { return Instr->getOperand(7); }
8920+
void set_Origin_X(llvm::Value *val) { Instr->setOperand(7, val); }
8921+
llvm::Value *get_Origin_Y() const { return Instr->getOperand(8); }
8922+
void set_Origin_Y(llvm::Value *val) { Instr->setOperand(8, val); }
8923+
llvm::Value *get_Origin_Z() const { return Instr->getOperand(9); }
8924+
void set_Origin_Z(llvm::Value *val) { Instr->setOperand(9, val); }
8925+
llvm::Value *get_TMin() const { return Instr->getOperand(10); }
8926+
void set_TMin(llvm::Value *val) { Instr->setOperand(10, val); }
8927+
llvm::Value *get_Direction_X() const { return Instr->getOperand(11); }
8928+
void set_Direction_X(llvm::Value *val) { Instr->setOperand(11, val); }
8929+
llvm::Value *get_Direction_Y() const { return Instr->getOperand(12); }
8930+
void set_Direction_Y(llvm::Value *val) { Instr->setOperand(12, val); }
8931+
llvm::Value *get_Direction_Z() const { return Instr->getOperand(13); }
8932+
void set_Direction_Z(llvm::Value *val) { Instr->setOperand(13, val); }
8933+
llvm::Value *get_TMax() const { return Instr->getOperand(14); }
8934+
void set_TMax(llvm::Value *val) { Instr->setOperand(14, val); }
8935+
llvm::Value *get_payload() const { return Instr->getOperand(15); }
8936+
void set_payload(llvm::Value *val) { Instr->setOperand(15, val); }
8937+
};
8938+
88538939
/// This instruction Creates a new HitObject representing a miss
88548940
struct DxilInst_HitObject_MakeMiss {
88558941
llvm::Instruction *Instr;
@@ -8923,5 +9009,36 @@ struct DxilInst_HitObject_MakeNop {
89239009
// Metadata
89249010
bool requiresUniformInputs() const { return false; }
89259011
};
9012+
9013+
/// This instruction Represents the invocation of the CH/MS shader represented
9014+
/// by the HitObject
9015+
struct DxilInst_HitObject_Invoke {
9016+
llvm::Instruction *Instr;
9017+
// Construction and identification
9018+
DxilInst_HitObject_Invoke(llvm::Instruction *pInstr) : Instr(pInstr) {}
9019+
operator bool() const {
9020+
return hlsl::OP::IsDxilOpFuncCallInst(Instr,
9021+
hlsl::OP::OpCode::HitObject_Invoke);
9022+
}
9023+
// Validation support
9024+
bool isAllowed() const { return true; }
9025+
bool isArgumentListValid() const {
9026+
if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
9027+
return false;
9028+
return true;
9029+
}
9030+
// Metadata
9031+
bool requiresUniformInputs() const { return false; }
9032+
// Operand indexes
9033+
enum OperandIdx {
9034+
arg_hitObject = 1,
9035+
arg_payload = 2,
9036+
};
9037+
// Accessors
9038+
llvm::Value *get_hitObject() const { return Instr->getOperand(1); }
9039+
void set_hitObject(llvm::Value *val) { Instr->setOperand(1, val); }
9040+
llvm::Value *get_payload() const { return Instr->getOperand(2); }
9041+
void set_payload(llvm::Value *val) { Instr->setOperand(2, val); }
9042+
};
89269043
// INSTR-HELPER:END
89279044
} // namespace hlsl

lib/DXIL/DxilOperations.cpp

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,15 +2643,20 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
26432643
false},
26442644
Attribute::None,
26452645
},
2646+
2647+
// Shader Execution Reordering void, h, f, d, i1, i8, i16,
2648+
// i32, i64, udt, obj , function attribute
26462649
{
2647-
OC::ReservedB0,
2648-
"ReservedB0",
2649-
OCC::Reserved,
2650-
"reserved",
2651-
{true, false, false, false, false, false, false, false, false, false,
2650+
OC::HitObject_TraceRay,
2651+
"HitObject_TraceRay",
2652+
OCC::HitObject_TraceRay,
2653+
"hitObject_TraceRay",
2654+
{false, false, false, false, false, false, false, false, false, true,
26522655
false},
26532656
Attribute::None,
26542657
},
2658+
2659+
// void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
26552660
{
26562661
OC::ReservedB1,
26572662
"ReservedB1",
@@ -2691,17 +2696,17 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
26912696
false},
26922697
Attribute::ReadNone,
26932698
},
2694-
2695-
// void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
26962699
{
2697-
OC::ReservedB5,
2698-
"ReservedB5",
2699-
OCC::Reserved,
2700-
"reserved",
2701-
{true, false, false, false, false, false, false, false, false, false,
2700+
OC::HitObject_Invoke,
2701+
"HitObject_Invoke",
2702+
OCC::HitObject_Invoke,
2703+
"hitObject_Invoke",
2704+
{false, false, false, false, false, false, false, false, false, true,
27022705
false},
27032706
Attribute::None,
27042707
},
2708+
2709+
// void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
27052710
{
27062711
OC::ReservedB6,
27072712
"ReservedB6",
@@ -3755,8 +3760,9 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
37553760
minor = 9;
37563761
return;
37573762
}
3758-
// Instructions: HitObject_MakeMiss=265, HitObject_MakeNop=266
3759-
if ((265 <= op && op <= 266)) {
3763+
// Instructions: HitObject_TraceRay=262, HitObject_MakeMiss=265,
3764+
// HitObject_MakeNop=266, HitObject_Invoke=267
3765+
if (op == 262 || (265 <= op && op <= 267)) {
37603766
major = 6;
37613767
minor = 9;
37623768
mask =
@@ -5875,10 +5881,29 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
58755881
A(pV);
58765882
A(pI32);
58775883
break;
5878-
case OpCode::ReservedB0:
5879-
A(pV);
5884+
5885+
// Shader Execution Reordering
5886+
case OpCode::HitObject_TraceRay:
5887+
A(pHit);
5888+
A(pI32);
5889+
A(pRes);
5890+
A(pI32);
5891+
A(pI32);
58805892
A(pI32);
5893+
A(pI32);
5894+
A(pI32);
5895+
A(pF32);
5896+
A(pF32);
5897+
A(pF32);
5898+
A(pF32);
5899+
A(pF32);
5900+
A(pF32);
5901+
A(pF32);
5902+
A(pF32);
5903+
A(udt);
58815904
break;
5905+
5906+
//
58825907
case OpCode::ReservedB1:
58835908
A(pV);
58845909
A(pI32);
@@ -5907,12 +5932,14 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
59075932
A(pHit);
59085933
A(pI32);
59095934
break;
5910-
5911-
//
5912-
case OpCode::ReservedB5:
5935+
case OpCode::HitObject_Invoke:
59135936
A(pV);
59145937
A(pI32);
5938+
A(pHit);
5939+
A(udt);
59155940
break;
5941+
5942+
//
59165943
case OpCode::ReservedB6:
59175944
A(pV);
59185945
A(pI32);
@@ -6190,6 +6217,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
61906217
case OpCode::TempRegStore:
61916218
case OpCode::CallShader:
61926219
case OpCode::Pack4x8:
6220+
case OpCode::HitObject_Invoke:
61936221
if (FT->getNumParams() <= 2)
61946222
return nullptr;
61956223
return FT->getParamType(2);
@@ -6229,6 +6257,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
62296257
return nullptr;
62306258
return FT->getParamType(5);
62316259
case OpCode::TraceRay:
6260+
case OpCode::HitObject_TraceRay:
62326261
if (FT->getNumParams() <= 15)
62336262
return nullptr;
62346263
return FT->getParamType(15);
@@ -6315,12 +6344,10 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
63156344
case OpCode::ReservedA0:
63166345
case OpCode::ReservedA1:
63176346
case OpCode::ReservedA2:
6318-
case OpCode::ReservedB0:
63196347
case OpCode::ReservedB1:
63206348
case OpCode::ReservedB2:
63216349
case OpCode::HitObject_MakeMiss:
63226350
case OpCode::HitObject_MakeNop:
6323-
case OpCode::ReservedB5:
63246351
case OpCode::ReservedB6:
63256352
case OpCode::ReservedB7:
63266353
case OpCode::ReservedB8:
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
; RUN: %dxv %s | FileCheck %s
2+
3+
; CHECK: Validation succeeded.
4+
5+
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"
6+
target triple = "dxil-ms-dx"
7+
8+
%dx.types.Handle = type { i8* }
9+
%struct.Payload = type { <3 x float> }
10+
%dx.types.ResourceProperties = type { i32, i32 }
11+
%dx.types.HitObject = type { i8* }
12+
%struct.RaytracingAccelerationStructure = type { i32 }
13+
14+
@"\01?RTAS@@3URaytracingAccelerationStructure@@A" = external constant %dx.types.Handle, align 4
15+
16+
; Function Attrs: nounwind
17+
define void @"\01?main@@YAXXZ"() #0 {
18+
%payload = alloca %struct.Payload, align 4
19+
%rtas = load %dx.types.Handle, %dx.types.Handle* @"\01?RTAS@@3URaytracingAccelerationStructure@@A", align 4
20+
21+
; Setup acceleration structure handle
22+
%handle = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %rtas) ; CreateHandleForLib(Resource)
23+
%annotatedHandle = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %handle, %dx.types.ResourceProperties { i32 16, i32 0 }) ; AnnotateHandle(res,props) resource: RTAccelerationStructure
24+
25+
; Test HitObject_TraceRay (opcode 262)
26+
%r262 = call %dx.types.HitObject @dx.op.hitObject_TraceRay.struct.Payload(i32 262, %dx.types.Handle %annotatedHandle, i32 513, i32 1, i32 2, i32 4, i32 0, float 0.000000e+00, float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00, %struct.Payload* nonnull %payload) ; HitObject_TraceRay(accelerationStructure,rayFlags,instanceInclusionMask,rayContributionToHitGroupIndex,multiplierForGeometryContributionToHitGroupIndex,missShaderIndex,Origin_X,Origin_Y,Origin_Z,TMin,Direction_X,Direction_Y,Direction_Z,TMax,payload)
27+
28+
; Test HitObject_Invoke (opcode 267)
29+
%nop = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
30+
call void @dx.op.hitObject_Invoke.struct.Payload(i32 267, %dx.types.HitObject %r262, %struct.Payload* nonnull %payload) ; HitObject_Invoke(hitObject,payload)
31+
32+
ret void
33+
}
34+
35+
; Function Attrs: nounwind
36+
declare %dx.types.HitObject @dx.op.hitObject_TraceRay.struct.Payload(i32, %dx.types.Handle, i32, i32, i32, i32, i32, float, float, float, float, float, float, float, float, %struct.Payload*) #0
37+
38+
; Function Attrs: nounwind
39+
declare void @dx.op.hitObject_Invoke.struct.Payload(i32, %dx.types.HitObject, %struct.Payload*) #0
40+
41+
; Function Attrs: nounwind readnone
42+
declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1
43+
44+
; Function Attrs: nounwind readnone
45+
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
46+
47+
; Function Attrs: nounwind readonly
48+
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #2
49+
50+
attributes #0 = { nounwind }
51+
attributes #1 = { nounwind readnone }
52+
attributes #2 = { nounwind readonly }
53+
54+
!0 = !{i32 1, i32 9}
55+
!1 = !{!"lib", i32 6, i32 9}
56+
!2 = !{!3, null, null, null}
57+
!3 = !{!4}
58+
!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}
59+
!5 = !{i32 0, i32 4}
60+
!6 = !{i32 1, void ()* @"\01?main@@YAXXZ", !7}
61+
!7 = !{!8}
62+
!8 = !{i32 1, !5, !5}
63+
!9 = !{null, !"", null, !2, !10}
64+
!10 = !{i32 0, i64 33554432}
65+
!11 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !12}
66+
!12 = !{i32 8, i32 7, i32 5, !13}
67+
!13 = !{i32 0}
68+
69+
!dx.version = !{!0}
70+
!dx.valver = !{!0}
71+
!dx.shaderModel = !{!1}
72+
!dx.resources = !{!2}
73+
!dx.typeAnnotations = !{!6}
74+
!dx.entryPoints = !{!9, !11}

0 commit comments

Comments
 (0)