Skip to content

Commit 8280d0f

Browse files
authored
[SER] HitObject_Invoke|TraceRay DXIL opcodes and check-pass test (microsoft#7278)
Add the DXIL operations and a passing validation test for: - HitObject_TraceRay - HitObject_Invoke DXC SER implementation tracker: microsoft#7214
1 parent 94f9275 commit 8280d0f

File tree

7 files changed

+349
-52
lines changed

7 files changed

+349
-52
lines changed

include/dxc/DXIL/DxilConstants.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,11 +502,9 @@ enum class OpCode : unsigned {
502502
ReservedA0 = 259, // reserved
503503
ReservedA1 = 260, // reserved
504504
ReservedA2 = 261, // reserved
505-
ReservedB0 = 262, // reserved
506505
ReservedB28 = 290, // reserved
507506
ReservedB29 = 291, // reserved
508507
ReservedB30 = 292, // reserved
509-
ReservedB5 = 267, // reserved
510508
ReservedB6 = 268, // reserved
511509
ReservedC0 = 293, // reserved
512510
ReservedC1 = 294, // reserved
@@ -903,6 +901,8 @@ enum class OpCode : unsigned {
903901
HitObject_HitKind = 285, // Returns the HitKind of the hit
904902
HitObject_InstanceID = 283, // Returns the instance id committed on hit
905903
HitObject_InstanceIndex = 282, // Returns the instance index committed on hit
904+
HitObject_Invoke = 267, // Represents the invocation of the CH/MS shader
905+
// represented by the HitObject
906906
HitObject_IsHit = 270, // Returns `true` if the HitObject is a NOP-HitObject
907907
HitObject_IsMiss = 269, // Returns `true` if the HitObject represents a miss
908908
HitObject_IsNop = 271, // Returns `true` if the HitObject represents a nop
@@ -925,6 +925,8 @@ enum class OpCode : unsigned {
925925
287, // Returns a HitObject with updated shader table index
926926
HitObject_ShaderTableIndex =
927927
286, // Returns the shader table index set for this HitObject
928+
HitObject_TraceRay = 262, // Analogous to TraceRay but without invoking CH/MS
929+
// and returns the intermediate state as a HitObject
928930
HitObject_WorldRayDirection = 276, // Returns the ray direction in world space
929931
HitObject_WorldRayOrigin = 275, // Returns the ray origin in world space
930932
HitObject_WorldToObject3x4 = 280, // Returns the world to object space
@@ -1308,13 +1310,15 @@ enum class OpCodeClass : unsigned {
13081310
HitObject_Attributes,
13091311
HitObject_FromRayQuery,
13101312
HitObject_FromRayQueryWithAttrs,
1313+
HitObject_Invoke,
13111314
HitObject_LoadLocalRootTableConstant,
13121315
HitObject_MakeMiss,
13131316
HitObject_MakeNop,
13141317
HitObject_SetShaderTableIndex,
13151318
HitObject_StateMatrix,
13161319
HitObject_StateScalar,
13171320
HitObject_StateVector,
1321+
HitObject_TraceRay,
13181322

13191323
// Synchronization
13201324
AtomicBinOp,
@@ -1380,7 +1384,7 @@ enum class OpCodeClass : unsigned {
13801384
NumOpClasses_Dxil_1_7 = 153,
13811385
NumOpClasses_Dxil_1_8 = 174,
13821386

1383-
NumOpClasses = 187 // exclusive last value of enumeration
1387+
NumOpClasses = 189 // exclusive last value of enumeration
13841388
};
13851389
// OPCODECLASS-ENUM:END
13861390

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 committed hit from a
88548940
/// RayQuery
88558941
struct DxilInst_HitObject_FromRayQuery {
@@ -8987,6 +9073,37 @@ struct DxilInst_HitObject_MakeNop {
89879073
bool requiresUniformInputs() const { return false; }
89889074
};
89899075

9076+
/// This instruction Represents the invocation of the CH/MS shader represented
9077+
/// by the HitObject
9078+
struct DxilInst_HitObject_Invoke {
9079+
llvm::Instruction *Instr;
9080+
// Construction and identification
9081+
DxilInst_HitObject_Invoke(llvm::Instruction *pInstr) : Instr(pInstr) {}
9082+
operator bool() const {
9083+
return hlsl::OP::IsDxilOpFuncCallInst(Instr,
9084+
hlsl::OP::OpCode::HitObject_Invoke);
9085+
}
9086+
// Validation support
9087+
bool isAllowed() const { return true; }
9088+
bool isArgumentListValid() const {
9089+
if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
9090+
return false;
9091+
return true;
9092+
}
9093+
// Metadata
9094+
bool requiresUniformInputs() const { return false; }
9095+
// Operand indexes
9096+
enum OperandIdx {
9097+
arg_hitObject = 1,
9098+
arg_payload = 2,
9099+
};
9100+
// Accessors
9101+
llvm::Value *get_hitObject() const { return Instr->getOperand(1); }
9102+
void set_hitObject(llvm::Value *val) { Instr->setOperand(1, val); }
9103+
llvm::Value *get_payload() const { return Instr->getOperand(2); }
9104+
void set_payload(llvm::Value *val) { Instr->setOperand(2, val); }
9105+
};
9106+
89909107
/// This instruction Returns `true` if the HitObject represents a miss
89919108
struct DxilInst_HitObject_IsMiss {
89929109
llvm::Instruction *Instr;

lib/DXIL/DxilOperations.cpp

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,16 +2303,16 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
23032303
0,
23042304
{},
23052305
{}}, // Overloads: v
2306-
{OC::ReservedB0,
2307-
"ReservedB0",
2308-
OCC::Reserved,
2309-
"reserved",
2310-
Attribute::None,
2311-
0,
2312-
{},
2313-
{}}, // Overloads: v
23142306

23152307
// Shader Execution Reordering
2308+
{OC::HitObject_TraceRay,
2309+
"HitObject_TraceRay",
2310+
OCC::HitObject_TraceRay,
2311+
"hitObject_TraceRay",
2312+
Attribute::None,
2313+
1,
2314+
{{0x100}},
2315+
{{0x0}}}, // Overloads: u
23162316
{OC::HitObject_FromRayQuery,
23172317
"HitObject_FromRayQuery",
23182318
OCC::HitObject_FromRayQuery,
@@ -2345,15 +2345,15 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
23452345
0,
23462346
{},
23472347
{}}, // Overloads: v
2348-
2349-
{OC::ReservedB5,
2350-
"ReservedB5",
2351-
OCC::Reserved,
2352-
"reserved",
2348+
{OC::HitObject_Invoke,
2349+
"HitObject_Invoke",
2350+
OCC::HitObject_Invoke,
2351+
"hitObject_Invoke",
23532352
Attribute::None,
2354-
0,
2355-
{},
2356-
{}}, // Overloads: v
2353+
1,
2354+
{{0x100}},
2355+
{{0x0}}}, // Overloads: u
2356+
23572357
{OC::ReservedB6,
23582358
"ReservedB6",
23592359
OCC::Reserved,
@@ -3449,19 +3449,20 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
34493449
minor = 9;
34503450
return;
34513451
}
3452-
// Instructions: HitObject_FromRayQuery=263,
3452+
// Instructions: HitObject_TraceRay=262, HitObject_FromRayQuery=263,
34533453
// HitObject_FromRayQueryWithAttrs=264, HitObject_MakeMiss=265,
3454-
// HitObject_MakeNop=266, HitObject_IsMiss=269, HitObject_IsHit=270,
3455-
// HitObject_IsNop=271, HitObject_RayFlags=272, HitObject_RayTMin=273,
3456-
// HitObject_RayTCurrent=274, HitObject_WorldRayOrigin=275,
3457-
// HitObject_WorldRayDirection=276, HitObject_ObjectRayOrigin=277,
3458-
// HitObject_ObjectRayDirection=278, HitObject_ObjectToWorld3x4=279,
3459-
// HitObject_WorldToObject3x4=280, HitObject_GeometryIndex=281,
3460-
// HitObject_InstanceIndex=282, HitObject_InstanceID=283,
3461-
// HitObject_PrimitiveIndex=284, HitObject_HitKind=285,
3462-
// HitObject_ShaderTableIndex=286, HitObject_SetShaderTableIndex=287,
3454+
// HitObject_MakeNop=266, HitObject_Invoke=267, HitObject_IsMiss=269,
3455+
// HitObject_IsHit=270, HitObject_IsNop=271, HitObject_RayFlags=272,
3456+
// HitObject_RayTMin=273, HitObject_RayTCurrent=274,
3457+
// HitObject_WorldRayOrigin=275, HitObject_WorldRayDirection=276,
3458+
// HitObject_ObjectRayOrigin=277, HitObject_ObjectRayDirection=278,
3459+
// HitObject_ObjectToWorld3x4=279, HitObject_WorldToObject3x4=280,
3460+
// HitObject_GeometryIndex=281, HitObject_InstanceIndex=282,
3461+
// HitObject_InstanceID=283, HitObject_PrimitiveIndex=284,
3462+
// HitObject_HitKind=285, HitObject_ShaderTableIndex=286,
3463+
// HitObject_SetShaderTableIndex=287,
34633464
// HitObject_LoadLocalRootTableConstant=288, HitObject_Attributes=289
3464-
if ((263 <= op && op <= 266) || (269 <= op && op <= 289)) {
3465+
if ((262 <= op && op <= 267) || (269 <= op && op <= 289)) {
34653466
major = 6;
34663467
minor = 9;
34673468
mask =
@@ -5632,12 +5633,27 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
56325633
A(pV);
56335634
A(pI32);
56345635
break;
5635-
case OpCode::ReservedB0:
5636-
A(pV);
5637-
A(pI32);
5638-
break;
56395636

56405637
// Shader Execution Reordering
5638+
case OpCode::HitObject_TraceRay:
5639+
A(pHit);
5640+
A(pI32);
5641+
A(pRes);
5642+
A(pI32);
5643+
A(pI32);
5644+
A(pI32);
5645+
A(pI32);
5646+
A(pI32);
5647+
A(pF32);
5648+
A(pF32);
5649+
A(pF32);
5650+
A(pF32);
5651+
A(pF32);
5652+
A(pF32);
5653+
A(pF32);
5654+
A(pF32);
5655+
A(udt);
5656+
break;
56415657
case OpCode::HitObject_FromRayQuery:
56425658
A(pHit);
56435659
A(pI32);
@@ -5668,12 +5684,14 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
56685684
A(pHit);
56695685
A(pI32);
56705686
break;
5671-
5672-
//
5673-
case OpCode::ReservedB5:
5687+
case OpCode::HitObject_Invoke:
56745688
A(pV);
56755689
A(pI32);
5690+
A(pHit);
5691+
A(udt);
56765692
break;
5693+
5694+
//
56775695
case OpCode::ReservedB6:
56785696
A(pV);
56795697
A(pI32);
@@ -6007,6 +6025,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
60076025
case OpCode::TempRegStore:
60086026
case OpCode::CallShader:
60096027
case OpCode::Pack4x8:
6028+
case OpCode::HitObject_Invoke:
60106029
case OpCode::HitObject_Attributes:
60116030
if (FT->getNumParams() <= 2)
60126031
return nullptr;
@@ -6048,6 +6067,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
60486067
return nullptr;
60496068
return FT->getParamType(5);
60506069
case OpCode::TraceRay:
6070+
case OpCode::HitObject_TraceRay:
60516071
if (FT->getNumParams() <= 15)
60526072
return nullptr;
60536073
return FT->getParamType(15);
@@ -6135,11 +6155,9 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
61356155
case OpCode::ReservedA0:
61366156
case OpCode::ReservedA1:
61376157
case OpCode::ReservedA2:
6138-
case OpCode::ReservedB0:
61396158
case OpCode::HitObject_FromRayQuery:
61406159
case OpCode::HitObject_MakeMiss:
61416160
case OpCode::HitObject_MakeNop:
6142-
case OpCode::ReservedB5:
61436161
case OpCode::ReservedB6:
61446162
case OpCode::HitObject_SetShaderTableIndex:
61456163
case OpCode::HitObject_LoadLocalRootTableConstant:

lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -905,13 +905,14 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
905905
case DXIL::OpCode::BufferUpdateCounter:
906906
readWrite = ShaderAccessFlags::Counter;
907907
break;
908+
case DXIL::OpCode::HitObject_TraceRay:
908909
case DXIL::OpCode::TraceRay: {
909910
// Read of AccelerationStructure; doesn't match function attribute
910-
auto res = GetResourceFromHandle(Call->getArgOperand(1), DM);
911-
if (res.accessStyle == AccessStyle::None) {
911+
auto Res = GetResourceFromHandle(Call->getArgOperand(1), DM);
912+
if (Res.accessStyle == AccessStyle::None) {
912913
continue;
913914
}
914-
if (EmitResourceAccess(DM, res, Call, HlslOP, Ctx,
915+
if (EmitResourceAccess(DM, Res, Call, HlslOP, Ctx,
915916
ShaderAccessFlags::Read)) {
916917
Modified = true;
917918
}

lib/DxilValidation/DxilValidation.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,15 @@ static bool ValidateStorageMasks(Instruction *I, DXIL::OpCode Opcode,
10061006
return true;
10071007
}
10081008

1009+
static void ValidateASHandle(CallInst *CI, Value *Hdl,
1010+
ValidationContext &ValCtx) {
1011+
DxilResourceProperties RP = ValCtx.GetResourceFromVal(Hdl);
1012+
if (RP.getResourceClass() == DXIL::ResourceClass::Invalid ||
1013+
RP.getResourceKind() != DXIL::ResourceKind::RTAccelerationStructure) {
1014+
ValCtx.EmitInstrError(CI, ValidationRule::InstrResourceKindForTraceRay);
1015+
}
1016+
}
1017+
10091018
static void ValidateResourceDxilOp(CallInst *CI, DXIL::OpCode Opcode,
10101019
ValidationContext &ValCtx) {
10111020
switch (Opcode) {
@@ -1587,14 +1596,12 @@ static void ValidateResourceDxilOp(CallInst *CI, DXIL::OpCode Opcode,
15871596
case DXIL::OpCode::TraceRay: {
15881597
DxilInst_TraceRay TraceRay(CI);
15891598
Value *Hdl = TraceRay.get_AccelerationStructure();
1590-
DxilResourceProperties RP = ValCtx.GetResourceFromVal(Hdl);
1591-
if (RP.getResourceClass() == DXIL::ResourceClass::Invalid) {
1592-
ValCtx.EmitInstrError(CI, ValidationRule::InstrResourceKindForTraceRay);
1593-
return;
1594-
}
1595-
if (RP.getResourceKind() != DXIL::ResourceKind::RTAccelerationStructure) {
1596-
ValCtx.EmitInstrError(CI, ValidationRule::InstrResourceKindForTraceRay);
1597-
}
1599+
ValidateASHandle(CI, Hdl, ValCtx);
1600+
} break;
1601+
case DXIL::OpCode::HitObject_TraceRay: {
1602+
DxilInst_HitObject_TraceRay HOTraceRay(CI);
1603+
Value *Hdl = HOTraceRay.get_accelerationStructure();
1604+
ValidateASHandle(CI, Hdl, ValCtx);
15981605
} break;
15991606
default:
16001607
break;

0 commit comments

Comments
 (0)