Skip to content

Commit bddee27

Browse files
authored
[SER] HitObject accessors HLSL -> DXIL lowering (#7360)
Lowering for all HitObject accessors (ex GetAttributes) Specification: https://github.com/microsoft/hlsl-specs/blob/main/proposals/0027-shader-execution-reordering.md DXC SER implementation tracker:: #7214
1 parent 06381f2 commit bddee27

File tree

4 files changed

+1142
-19
lines changed

4 files changed

+1142
-19
lines changed

lib/HLSL/HLOperationLower.cpp

+79-19
Original file line numberDiff line numberDiff line change
@@ -5958,19 +5958,31 @@ Value *TranslateNoArgVectorOperation(CallInst *CI, IntrinsicOp IOP,
59585958
return retVal;
59595959
}
59605960

5961+
template <typename ColElemTy>
5962+
static void GetMatrixIndices(Constant *&Rows, Constant *&Cols, bool Is3x4,
5963+
LLVMContext &Ctx) {
5964+
if (Is3x4) {
5965+
uint32_t RVals[] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2};
5966+
Rows = ConstantDataVector::get(Ctx, RVals);
5967+
ColElemTy CVals[] = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
5968+
Cols = ConstantDataVector::get(Ctx, CVals);
5969+
return;
5970+
}
5971+
uint32_t RVals[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2};
5972+
Rows = ConstantDataVector::get(Ctx, RVals);
5973+
ColElemTy CVals[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3};
5974+
Cols = ConstantDataVector::get(Ctx, CVals);
5975+
}
5976+
59615977
Value *TranslateNoArgMatrix3x4Operation(
59625978
CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
59635979
HLOperationLowerHelper &helper, HLObjectOperationLowerHelper *pObjHelper,
59645980
bool &Translated) {
59655981
hlsl::OP *hlslOP = &helper.hlslOP;
59665982
VectorType *Ty = cast<VectorType>(CI->getType());
5967-
uint32_t rVals[] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2};
5968-
Constant *rows = ConstantDataVector::get(CI->getContext(), rVals);
5969-
uint8_t cVals[] = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
5970-
Constant *cols = ConstantDataVector::get(CI->getContext(), cVals);
5971-
Value *retVal =
5972-
TrivialDxilOperation(opcode, {nullptr, rows, cols}, Ty, CI, hlslOP);
5973-
return retVal;
5983+
Constant *Rows, *Cols;
5984+
GetMatrixIndices<uint8_t>(Rows, Cols, true, CI->getContext());
5985+
return TrivialDxilOperation(opcode, {nullptr, Rows, Cols}, Ty, CI, hlslOP);
59745986
}
59755987

59765988
Value *TranslateNoArgTransposedMatrix3x4Operation(
@@ -5979,13 +5991,9 @@ Value *TranslateNoArgTransposedMatrix3x4Operation(
59795991
bool &Translated) {
59805992
hlsl::OP *hlslOP = &helper.hlslOP;
59815993
VectorType *Ty = cast<VectorType>(CI->getType());
5982-
uint32_t rVals[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2};
5983-
Constant *rows = ConstantDataVector::get(CI->getContext(), rVals);
5984-
uint8_t cVals[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3};
5985-
Constant *cols = ConstantDataVector::get(CI->getContext(), cVals);
5986-
Value *retVal =
5987-
TrivialDxilOperation(opcode, {nullptr, rows, cols}, Ty, CI, hlslOP);
5988-
return retVal;
5994+
Constant *Rows, *Cols;
5995+
GetMatrixIndices<uint8_t>(Rows, Cols, false, CI->getContext());
5996+
return TrivialDxilOperation(opcode, {nullptr, Rows, Cols}, Ty, CI, hlslOP);
59895997
}
59905998

59915999
/*
@@ -6375,37 +6383,89 @@ Value *TranslateHitObjectScalarGetter(CallInst *CI, IntrinsicOp IOP,
63756383
HLOperationLowerHelper &Helper,
63766384
HLObjectOperationLowerHelper *pObjHelper,
63776385
bool &Translated) {
6378-
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
6386+
hlsl::OP *OP = &Helper.hlslOP;
6387+
Value *HitObjectPtr = CI->getArgOperand(1);
6388+
IRBuilder<> Builder(CI);
6389+
Value *HitObject = Builder.CreateLoad(HitObjectPtr);
6390+
return TrivialDxilOperation(OpCode, {nullptr, HitObject}, CI->getType(), CI,
6391+
OP);
63796392
}
63806393

63816394
Value *TranslateHitObjectVectorGetter(CallInst *CI, IntrinsicOp IOP,
63826395
OP::OpCode OpCode,
63836396
HLOperationLowerHelper &Helper,
63846397
HLObjectOperationLowerHelper *pObjHelper,
63856398
bool &Translated) {
6386-
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
6399+
hlsl::OP *OP = &Helper.hlslOP;
6400+
Value *HitObjectPtr = CI->getArgOperand(1);
6401+
IRBuilder<> Builder(CI);
6402+
Value *HitObject = Builder.CreateLoad(HitObjectPtr);
6403+
VectorType *Ty = cast<VectorType>(CI->getType());
6404+
uint32_t Vals[] = {0, 1, 2, 3};
6405+
Constant *Src = ConstantDataVector::get(CI->getContext(), Vals);
6406+
return TrivialDxilOperation(OpCode, {nullptr, HitObject, Src}, Ty, CI, OP);
6407+
}
6408+
6409+
static bool IsHitObject3x4Getter(IntrinsicOp IOP) {
6410+
switch (IOP) {
6411+
default:
6412+
return false;
6413+
case IntrinsicOp::MOP_DxHitObject_GetObjectToWorld3x4:
6414+
case IntrinsicOp::MOP_DxHitObject_GetWorldToObject3x4:
6415+
return true;
6416+
}
63876417
}
63886418

63896419
Value *TranslateHitObjectMatrixGetter(CallInst *CI, IntrinsicOp IOP,
63906420
OP::OpCode OpCode,
63916421
HLOperationLowerHelper &Helper,
63926422
HLObjectOperationLowerHelper *pObjHelper,
63936423
bool &Translated) {
6394-
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
6424+
hlsl::OP *OP = &Helper.hlslOP;
6425+
Value *HitObjectPtr = CI->getArgOperand(1);
6426+
IRBuilder<> Builder(CI);
6427+
Value *HitObject = Builder.CreateLoad(HitObjectPtr);
6428+
6429+
// Create 3x4 matrix indices
6430+
bool Is3x4 = IsHitObject3x4Getter(IOP);
6431+
Constant *Rows, *Cols;
6432+
GetMatrixIndices<uint32_t>(Rows, Cols, Is3x4, CI->getContext());
6433+
6434+
VectorType *Ty = cast<VectorType>(CI->getType());
6435+
return TrivialDxilOperation(OpCode, {nullptr, HitObject, Rows, Cols}, Ty, CI,
6436+
OP);
63956437
}
63966438

63976439
Value *TranslateHitObjectLoadLocalRootTableConstant(
63986440
CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode,
63996441
HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *pObjHelper,
64006442
bool &Translated) {
6401-
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
6443+
hlsl::OP *OP = &Helper.hlslOP;
6444+
IRBuilder<> Builder(CI);
6445+
6446+
Value *HitObjectPtr = CI->getArgOperand(1);
6447+
Value *Offset = CI->getArgOperand(2);
6448+
6449+
Value *HitObject = Builder.CreateLoad(HitObjectPtr);
6450+
return TrivialDxilOperation(OpCode, {nullptr, HitObject, Offset},
6451+
Helper.voidTy, CI, OP);
64026452
}
64036453

64046454
Value *TranslateHitObjectSetShaderTableIndex(
64056455
CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode,
64066456
HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *pObjHelper,
64076457
bool &Translated) {
6408-
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
6458+
hlsl::OP *OP = &Helper.hlslOP;
6459+
IRBuilder<> Builder(CI);
6460+
6461+
Value *HitObjectPtr = CI->getArgOperand(1);
6462+
Value *ShaderTableIndex = CI->getArgOperand(2);
6463+
6464+
Value *InHitObject = Builder.CreateLoad(HitObjectPtr);
6465+
Value *OutHitObject = TrivialDxilOperation(
6466+
OpCode, {nullptr, InHitObject, ShaderTableIndex}, Helper.voidTy, CI, OP);
6467+
Builder.CreateStore(OutHitObject, HitObjectPtr);
6468+
return nullptr;
64096469
}
64106470

64116471
} // namespace
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// REQUIRES: dxil-1-9
2+
// RUN: %dxc -T lib_6_9 -E main %s | FileCheck %s --check-prefix DXIL
3+
4+
// DXIL: %dx.types.HitObject = type { i8* }
5+
6+
// DXIL: %[[NOP:[^ ]+]] = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
7+
// DXIL: %[[HIT:[^ ]+]] = call %dx.types.HitObject @dx.op.hitObject_SetShaderTableIndex(i32 287, %dx.types.HitObject %[[NOP]], i32 1) ; HitObject_SetShaderTableIndex(hitObject,shaderTableIndex)
8+
// DXIL-DAG: %{{[^ ]+}} = call i1 @dx.op.hitObject_StateScalar.i1(i32 270, %dx.types.HitObject %[[HIT]]) ; HitObject_IsHit(hitObject)
9+
// DXIL-DAG: %{{[^ ]+}} = call i1 @dx.op.hitObject_StateScalar.i1(i32 269, %dx.types.HitObject %[[HIT]]) ; HitObject_IsMiss(hitObject)
10+
// DXIL-DAG: %{{[^ ]+}} = call i1 @dx.op.hitObject_StateScalar.i1(i32 271, %dx.types.HitObject %[[HIT]]) ; HitObject_IsNop(hitObject)
11+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 281, %dx.types.HitObject %[[HIT]]) ; HitObject_GeometryIndex(hitObject)
12+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 285, %dx.types.HitObject %[[HIT]]) ; HitObject_HitKind(hitObject)
13+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 282, %dx.types.HitObject %[[HIT]]) ; HitObject_InstanceIndex(hitObject)
14+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 283, %dx.types.HitObject %[[HIT]]) ; HitObject_InstanceID(hitObject)
15+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 284, %dx.types.HitObject %[[HIT]]) ; HitObject_PrimitiveIndex(hitObject)
16+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_StateScalar.i32(i32 286, %dx.types.HitObject %[[HIT]]) ; HitObject_ShaderTableIndex(hitObject)
17+
// DXIL-DAG: %{{[^ ]+}} = call i32 @dx.op.hitObject_LoadLocalRootTableConstant(i32 288, %dx.types.HitObject %[[HIT]], i32 42) ; HitObject_LoadLocalRootTableConstant(hitObject,offset)
18+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %[[HIT]], i32 0) ; HitObject_ObjectRayOrigin(hitObject,component)
19+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %[[HIT]], i32 1) ; HitObject_ObjectRayOrigin(hitObject,component)
20+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 277, %dx.types.HitObject %[[HIT]], i32 2) ; HitObject_ObjectRayOrigin(hitObject,component)
21+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %[[HIT]], i32 0) ; HitObject_ObjectRayDirection(hitObject,component)
22+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %[[HIT]], i32 1) ; HitObject_ObjectRayDirection(hitObject,component)
23+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 278, %dx.types.HitObject %[[HIT]], i32 2) ; HitObject_ObjectRayDirection(hitObject,component)
24+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %[[HIT]], i32 0) ; HitObject_WorldRayOrigin(hitObject,component)
25+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %[[HIT]], i32 1) ; HitObject_WorldRayOrigin(hitObject,component)
26+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 275, %dx.types.HitObject %[[HIT]], i32 2) ; HitObject_WorldRayOrigin(hitObject,component)
27+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %[[HIT]], i32 0) ; HitObject_WorldRayDirection(hitObject,component)
28+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %[[HIT]], i32 1) ; HitObject_WorldRayDirection(hitObject,component)
29+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateVector.f32(i32 276, %dx.types.HitObject %[[HIT]], i32 2) ; HitObject_WorldRayDirection(hitObject,component)
30+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 0, i32 0) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
31+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 0, i32 1) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
32+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 0, i32 2) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
33+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 0, i32 3) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
34+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 1, i32 0) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
35+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 1, i32 1) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
36+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 1, i32 2) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
37+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 1, i32 3) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
38+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 2, i32 0) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
39+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 2, i32 1) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
40+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 2, i32 2) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
41+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 279, %dx.types.HitObject %[[HIT]], i32 2, i32 3) ; HitObject_ObjectToWorld3x4(hitObject,row,col)
42+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 0, i32 0) ; HitObject_WorldToObject3x4(hitObject,row,col)
43+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 0, i32 1) ; HitObject_WorldToObject3x4(hitObject,row,col)
44+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 0, i32 2) ; HitObject_WorldToObject3x4(hitObject,row,col)
45+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 0, i32 3) ; HitObject_WorldToObject3x4(hitObject,row,col)
46+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 1, i32 0) ; HitObject_WorldToObject3x4(hitObject,row,col)
47+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 1, i32 1) ; HitObject_WorldToObject3x4(hitObject,row,col)
48+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 1, i32 2) ; HitObject_WorldToObject3x4(hitObject,row,col)
49+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 1, i32 3) ; HitObject_WorldToObject3x4(hitObject,row,col)
50+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 2, i32 0) ; HitObject_WorldToObject3x4(hitObject,row,col)
51+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 2, i32 1) ; HitObject_WorldToObject3x4(hitObject,row,col)
52+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 2, i32 2) ; HitObject_WorldToObject3x4(hitObject,row,col)
53+
// DXIL-DAG: %{{[^ ]+}} = call float @dx.op.hitObject_StateMatrix.f32(i32 280, %dx.types.HitObject %[[HIT]], i32 2, i32 3) ; HitObject_WorldToObject3x4(hitObject,row,col)
54+
// DXIL: ret void
55+
56+
RWByteAddressBuffer outbuf;
57+
58+
template <int M, int N>
59+
float hashM(in matrix<float, M, N> mat) {
60+
float h = 0.f;
61+
for (int i = 0; i < M; ++i)
62+
for (int j = 0; j < N; ++j)
63+
h += mat[i][j];
64+
return h;
65+
}
66+
67+
[shader("raygeneration")]
68+
void main() {
69+
dx::HitObject hit;
70+
int isum = 0;
71+
float fsum = 0.0f;
72+
vector<float, 3> vsum = 0;
73+
74+
///// Setters
75+
hit.SetShaderTableIndex(1);
76+
77+
///// Getters
78+
79+
// i1 accessors
80+
isum += hit.IsHit();
81+
isum += hit.IsMiss();
82+
isum += hit.IsNop();
83+
84+
// i32 accessors
85+
isum += hit.GetGeometryIndex();
86+
isum += hit.GetHitKind();
87+
isum += hit.GetInstanceIndex();
88+
isum += hit.GetInstanceID();
89+
isum += hit.GetPrimitiveIndex();
90+
isum += hit.GetShaderTableIndex();
91+
isum += hit.LoadLocalRootTableConstant(42);
92+
93+
// float3 accessors
94+
vsum += hit.GetWorldRayOrigin();
95+
vsum += hit.GetWorldRayDirection();
96+
vsum += hit.GetObjectRayOrigin();
97+
vsum += hit.GetObjectRayDirection();
98+
fsum += vsum[0] + vsum[1] + vsum[2];
99+
100+
// matrix accessors
101+
fsum += hashM<3, 4>(hit.GetObjectToWorld3x4());
102+
fsum += hashM<4, 3>(hit.GetObjectToWorld4x3());
103+
fsum += hashM<3, 4>(hit.GetWorldToObject3x4());
104+
fsum += hashM<4, 3>(hit.GetWorldToObject4x3());
105+
106+
// f32 accessors
107+
isum += hit.GetRayFlags();
108+
fsum += hit.GetRayTMin();
109+
fsum += hit.GetRayTCurrent();
110+
111+
outbuf.Store(0, fsum);
112+
outbuf.Store(4, isum);
113+
}

0 commit comments

Comments
 (0)