Skip to content

Commit 0a11435

Browse files
[OMM] Add AllocateRayQuery2 DXIL Op, add validation (microsoft#7124)
This PR adds AllocateRayQuery2 as a new DXIL Op, which is intended to be the DXIL Op that any rayquery object initialized with the 2nd optional template argument will be lowered to. Additionally, according to the spec here: https://github.com/microsoft/hlsl-specs/blob/main/proposals/0024-opacity-micromaps.md there are new validation rules that should be run against the allocateRayQuery* DXIL Ops. This PR implements these validation rules, and tests them. Fixes microsoft#7113 --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 32e7c00 commit 0a11435

File tree

8 files changed

+345
-68
lines changed

8 files changed

+345
-68
lines changed

include/dxc/DXIL/DxilConstants.h

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -475,63 +475,62 @@ inline bool IsFeedbackTexture(DXIL::ResourceKind ResourceKind) {
475475
// Enumeration for operations specified by DXIL
476476
enum class OpCode : unsigned {
477477
//
478-
AllocateRayQuery2 = 258, // reserved
479-
Reserved0 = 226, // Reserved
480-
Reserved1 = 227, // Reserved
481-
Reserved10 = 236, // Reserved
482-
Reserved11 = 237, // Reserved
483-
Reserved2 = 228, // Reserved
484-
Reserved3 = 229, // Reserved
485-
Reserved4 = 230, // Reserved
486-
Reserved5 = 231, // Reserved
487-
Reserved6 = 232, // Reserved
488-
Reserved7 = 233, // Reserved
489-
Reserved8 = 234, // Reserved
490-
Reserved9 = 235, // Reserved
491-
ReservedA0 = 259, // reserved
492-
ReservedA1 = 260, // reserved
493-
ReservedA2 = 261, // reserved
494-
ReservedB0 = 262, // reserved
495-
ReservedB1 = 263, // reserved
496-
ReservedB10 = 272, // reserved
497-
ReservedB11 = 273, // reserved
498-
ReservedB12 = 274, // reserved
499-
ReservedB13 = 275, // reserved
500-
ReservedB14 = 276, // reserved
501-
ReservedB15 = 277, // reserved
502-
ReservedB16 = 278, // reserved
503-
ReservedB17 = 279, // reserved
504-
ReservedB18 = 280, // reserved
505-
ReservedB19 = 281, // reserved
506-
ReservedB2 = 264, // reserved
507-
ReservedB20 = 282, // reserved
508-
ReservedB21 = 283, // reserved
509-
ReservedB22 = 284, // reserved
510-
ReservedB23 = 285, // reserved
511-
ReservedB24 = 286, // reserved
512-
ReservedB25 = 287, // reserved
513-
ReservedB26 = 288, // reserved
514-
ReservedB27 = 289, // reserved
515-
ReservedB28 = 290, // reserved
516-
ReservedB29 = 291, // reserved
517-
ReservedB3 = 265, // reserved
518-
ReservedB30 = 292, // reserved
519-
ReservedB4 = 266, // reserved
520-
ReservedB5 = 267, // reserved
521-
ReservedB6 = 268, // reserved
522-
ReservedB7 = 269, // reserved
523-
ReservedB8 = 270, // reserved
524-
ReservedB9 = 271, // reserved
525-
ReservedC0 = 293, // reserved
526-
ReservedC1 = 294, // reserved
527-
ReservedC2 = 295, // reserved
528-
ReservedC3 = 296, // reserved
529-
ReservedC4 = 297, // reserved
530-
ReservedC5 = 298, // reserved
531-
ReservedC6 = 299, // reserved
532-
ReservedC7 = 300, // reserved
533-
ReservedC8 = 301, // reserved
534-
ReservedC9 = 302, // reserved
478+
Reserved0 = 226, // Reserved
479+
Reserved1 = 227, // Reserved
480+
Reserved10 = 236, // Reserved
481+
Reserved11 = 237, // Reserved
482+
Reserved2 = 228, // Reserved
483+
Reserved3 = 229, // Reserved
484+
Reserved4 = 230, // Reserved
485+
Reserved5 = 231, // Reserved
486+
Reserved6 = 232, // Reserved
487+
Reserved7 = 233, // Reserved
488+
Reserved8 = 234, // Reserved
489+
Reserved9 = 235, // Reserved
490+
ReservedA0 = 259, // reserved
491+
ReservedA1 = 260, // reserved
492+
ReservedA2 = 261, // reserved
493+
ReservedB0 = 262, // reserved
494+
ReservedB1 = 263, // reserved
495+
ReservedB10 = 272, // reserved
496+
ReservedB11 = 273, // reserved
497+
ReservedB12 = 274, // reserved
498+
ReservedB13 = 275, // reserved
499+
ReservedB14 = 276, // reserved
500+
ReservedB15 = 277, // reserved
501+
ReservedB16 = 278, // reserved
502+
ReservedB17 = 279, // reserved
503+
ReservedB18 = 280, // reserved
504+
ReservedB19 = 281, // reserved
505+
ReservedB2 = 264, // reserved
506+
ReservedB20 = 282, // reserved
507+
ReservedB21 = 283, // reserved
508+
ReservedB22 = 284, // reserved
509+
ReservedB23 = 285, // reserved
510+
ReservedB24 = 286, // reserved
511+
ReservedB25 = 287, // reserved
512+
ReservedB26 = 288, // reserved
513+
ReservedB27 = 289, // reserved
514+
ReservedB28 = 290, // reserved
515+
ReservedB29 = 291, // reserved
516+
ReservedB3 = 265, // reserved
517+
ReservedB30 = 292, // reserved
518+
ReservedB4 = 266, // reserved
519+
ReservedB5 = 267, // reserved
520+
ReservedB6 = 268, // reserved
521+
ReservedB7 = 269, // reserved
522+
ReservedB8 = 270, // reserved
523+
ReservedB9 = 271, // reserved
524+
ReservedC0 = 293, // reserved
525+
ReservedC1 = 294, // reserved
526+
ReservedC2 = 295, // reserved
527+
ReservedC3 = 296, // reserved
528+
ReservedC4 = 297, // reserved
529+
ReservedC5 = 298, // reserved
530+
ReservedC6 = 299, // reserved
531+
ReservedC7 = 300, // reserved
532+
ReservedC8 = 301, // reserved
533+
ReservedC9 = 302, // reserved
535534

536535
// Amplification shader instructions
537536
DispatchMesh = 173, // Amplification shader intrinsic DispatchMesh
@@ -680,8 +679,9 @@ enum class OpCode : unsigned {
680679
TraceRay = 157, // initiates raytrace
681680

682681
// Inline Ray Query
683-
AllocateRayQuery = 178, // allocates space for RayQuery and return handle
684-
RayQuery_Abort = 181, // aborts a ray query
682+
AllocateRayQuery = 178, // allocates space for RayQuery and return handle
683+
AllocateRayQuery2 = 258, // allocates space for RayQuery and return handle
684+
RayQuery_Abort = 181, // aborts a ray query
685685
RayQuery_CandidateGeometryIndex = 203, // returns candidate hit geometry index
686686
RayQuery_CandidateInstanceContributionToHitGroupIndex =
687687
214, // returns candidate hit InstanceContributionToHitGroupIndex
@@ -1151,6 +1151,7 @@ enum class OpCodeClass : unsigned {
11511151

11521152
// Inline Ray Query
11531153
AllocateRayQuery,
1154+
AllocateRayQuery2,
11541155
RayQuery_Abort,
11551156
RayQuery_CommitNonOpaqueTriangleHit,
11561157
RayQuery_CommitProceduralPrimitiveHit,
@@ -1337,7 +1338,7 @@ enum class OpCodeClass : unsigned {
13371338
NumOpClasses_Dxil_1_7 = 153,
13381339
NumOpClasses_Dxil_1_8 = 174,
13391340

1340-
NumOpClasses = 174 // exclusive last value of enumeration
1341+
NumOpClasses = 175 // exclusive last value of enumeration
13411342
};
13421343
// OPCODECLASS-ENUM:END
13431344

@@ -1819,8 +1820,12 @@ enum class RayFlag : uint32_t {
18191820
CullNonOpaque = 0x80,
18201821
SkipTriangles = 0x100,
18211822
SkipProceduralPrimitives = 0x200,
1823+
ForceOMM2State = 0x400, // Force 2-state in Opacity Micromaps
18221824
};
18231825

1826+
// Corresponds to RAYQUERY_FLAG_* in HLSL
1827+
enum class RayQueryFlag : uint32_t { None = 0, AllowOpacityMicromaps = 1 };
1828+
18241829
// Packing/unpacking intrinsics
18251830
enum class UnpackMode : uint8_t {
18261831
Unsigned = 0, // not sign extended
@@ -2002,7 +2007,9 @@ enum class RaytracingPipelineFlags : uint32_t {
20022007
None = 0x0,
20032008
SkipTriangles = 0x100,
20042009
SkipProceduralPrimitives = 0x200,
2005-
ValidMask = 0x300,
2010+
ValidMask_1_8 = 0x300, // valid mask up through DXIL 1.8
2011+
AllowOpacityMicromaps = 0x400, // Allow Opacity Micromaps to be used
2012+
ValidMask = 0x700, // current valid mask
20062013
};
20072014

20082015
enum class CommittedStatus : uint32_t {

include/dxc/DXIL/DxilInstructions.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8765,5 +8765,53 @@ struct DxilInst_StartInstanceLocation {
87658765
// Metadata
87668766
bool requiresUniformInputs() const { return false; }
87678767
};
8768+
8769+
/// This instruction allocates space for RayQuery and return handle
8770+
struct DxilInst_AllocateRayQuery2 {
8771+
llvm::Instruction *Instr;
8772+
// Construction and identification
8773+
DxilInst_AllocateRayQuery2(llvm::Instruction *pInstr) : Instr(pInstr) {}
8774+
operator bool() const {
8775+
return hlsl::OP::IsDxilOpFuncCallInst(Instr,
8776+
hlsl::OP::OpCode::AllocateRayQuery2);
8777+
}
8778+
// Validation support
8779+
bool isAllowed() const { return true; }
8780+
bool isArgumentListValid() const {
8781+
if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
8782+
return false;
8783+
return true;
8784+
}
8785+
// Metadata
8786+
bool requiresUniformInputs() const { return false; }
8787+
// Operand indexes
8788+
enum OperandIdx {
8789+
arg_constRayFlags = 1,
8790+
arg_constRayQueryFlags = 2,
8791+
};
8792+
// Accessors
8793+
llvm::Value *get_constRayFlags() const { return Instr->getOperand(1); }
8794+
void set_constRayFlags(llvm::Value *val) { Instr->setOperand(1, val); }
8795+
uint32_t get_constRayFlags_val() const {
8796+
return (uint32_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(1))
8797+
->getZExtValue());
8798+
}
8799+
void set_constRayFlags_val(uint32_t val) {
8800+
Instr->setOperand(1, llvm::Constant::getIntegerValue(
8801+
llvm::IntegerType::get(Instr->getContext(), 32),
8802+
llvm::APInt(32, (uint64_t)val)));
8803+
}
8804+
llvm::Value *get_constRayQueryFlags() const { return Instr->getOperand(2); }
8805+
void set_constRayQueryFlags(llvm::Value *val) { Instr->setOperand(2, val); }
8806+
uint32_t get_constRayQueryFlags_val() const {
8807+
return (uint32_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(2))
8808+
->getZExtValue());
8809+
}
8810+
void set_constRayQueryFlags_val(uint32_t val) {
8811+
Instr->setOperand(2, llvm::Constant::getIntegerValue(
8812+
llvm::IntegerType::get(Instr->getContext(), 32),
8813+
llvm::APInt(32, (uint64_t)val)));
8814+
}
8815+
};
87688816
// INSTR-HELPER:END
87698817
} // namespace hlsl

include/dxc/DxilContainer/RDAT_SubobjectTypes.inl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ RDAT_DXIL_ENUM_START(hlsl::DXIL::RaytracingPipelineFlags, uint32_t)
6969
RDAT_ENUM_VALUE_NODEF(SkipProceduralPrimitives)
7070
// No need to define mask here
7171
// RDAT_ENUM_VALUE_NODEF(ValidMask)
72+
RDAT_ENUM_VALUE_NODEF(AllowOpacityMicromaps)
7273
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
7374
static_assert((unsigned)hlsl::DXIL::RaytracingPipelineFlags::ValidMask ==
74-
0x300,
75+
0x700,
7576
"otherwise, RDAT_DXIL_ENUM definition needs updating");
7677
#endif
7778
RDAT_ENUM_END()

lib/DXIL/DxilOperations.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,16 +2603,19 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
26032603
Attribute::ReadNone,
26042604
},
26052605

2606-
// void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
2606+
// Inline Ray Query void, h, f, d, i1, i8, i16, i32,
2607+
// i64, udt, obj , function attribute
26072608
{
26082609
OC::AllocateRayQuery2,
26092610
"AllocateRayQuery2",
2610-
OCC::Reserved,
2611-
"reserved",
2611+
OCC::AllocateRayQuery2,
2612+
"allocateRayQuery2",
26122613
{true, false, false, false, false, false, false, false, false, false,
26132614
false},
26142615
Attribute::None,
26152616
},
2617+
2618+
// void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute
26162619
{
26172620
OC::ReservedA0,
26182621
"ReservedA0",
@@ -3741,6 +3744,12 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
37413744
}
37423745
return;
37433746
}
3747+
// Instructions: AllocateRayQuery2=258
3748+
if (op == 258) {
3749+
major = 6;
3750+
minor = 9;
3751+
return;
3752+
}
37443753
// OPCODE-SMMASK:END
37453754
}
37463755

@@ -5829,11 +5838,15 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
58295838
A(pI32);
58305839
break;
58315840

5832-
//
5841+
// Inline Ray Query
58335842
case OpCode::AllocateRayQuery2:
5834-
A(pV);
5843+
A(pI32);
5844+
A(pI32);
5845+
A(pI32);
58355846
A(pI32);
58365847
break;
5848+
5849+
//
58375850
case OpCode::ReservedA0:
58385851
A(pV);
58395852
A(pI32);

lib/DxilValidation/DxilValidation.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,41 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
17081708
ValidateSignatureDxilOp(CI, opcode, ValCtx);
17091709
break;
17101710
// Special.
1711+
case DXIL::OpCode::AllocateRayQuery: {
1712+
// validate flags are immediate and compatible
1713+
llvm::Value *constRayFlag = CI->getOperand(1);
1714+
if (!llvm::isa<llvm::Constant>(constRayFlag)) {
1715+
ValCtx.EmitInstrError(CI,
1716+
ValidationRule::DeclAllocateRayQueryFlagsAreConst);
1717+
}
1718+
break;
1719+
}
1720+
case DXIL::OpCode::AllocateRayQuery2: {
1721+
// validate flags are immediate and compatible
1722+
llvm::Value *constRayFlag = CI->getOperand(1);
1723+
llvm::Value *RayQueryFlag = CI->getOperand(2);
1724+
if (!llvm::isa<llvm::Constant>(constRayFlag) ||
1725+
!llvm::isa<llvm::Constant>(RayQueryFlag)) {
1726+
ValCtx.EmitInstrError(CI,
1727+
ValidationRule::DeclAllocateRayQuery2FlagsAreConst);
1728+
break;
1729+
}
1730+
// When the ForceOMM2State ConstRayFlag is given as an argument to
1731+
// a RayQuery object, AllowOpacityMicromaps is expected
1732+
// as a RayQueryFlag argument
1733+
llvm::ConstantInt *Arg1 = llvm::cast<llvm::ConstantInt>(constRayFlag);
1734+
llvm::ConstantInt *Arg2 = llvm::cast<llvm::ConstantInt>(RayQueryFlag);
1735+
if ((Arg1->getValue().getSExtValue() &
1736+
(unsigned)DXIL::RayFlag::ForceOMM2State) &&
1737+
(Arg2->getValue().getSExtValue() &
1738+
(unsigned)DXIL::RayQueryFlag::AllowOpacityMicromaps) == 0) {
1739+
ValCtx.EmitInstrError(
1740+
CI,
1741+
ValidationRule::DeclAllowOpacityMicromapsExpectedGivenForceOMM2State);
1742+
}
1743+
break;
1744+
}
1745+
17111746
case DXIL::OpCode::BufferUpdateCounter: {
17121747
DxilInst_BufferUpdateCounter updateCounter(CI);
17131748
Value *handle = updateCounter.get_uav();
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
; RUN: not %dxv %s 2>&1 | FileCheck %s
2+
3+
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"
4+
target triple = "dxil-ms-dx"
5+
6+
%dx.types.Handle = type { i8* }
7+
%dx.types.ResBind = type { i32, i32, i32, i8 }
8+
%dx.types.ResourceProperties = type { i32, i32 }
9+
%struct.RaytracingAccelerationStructure = type { i32 }
10+
@nonconstVal = global i32 5
11+
12+
define void @main() {
13+
%ptr = getelementptr i32, i32* @nonconstVal, i32 0 ; Get the pointer to the global variable
14+
%val = load i32, i32* %ptr ; Dereference the pointer to load the value
15+
16+
; test that allocateRayQuery requires constant args
17+
; CHECK: error: constRayFlags argument of AllocateRayQuery must be constant
18+
; CHECK: note: at '%1 = call i32 @dx.op.allocateRayQuery(i32 178, i32 %val)' in block '#0' of function 'main'.
19+
%1 = call i32 @dx.op.allocateRayQuery(i32 178, i32 %val) ; AllocateRayQuery(constRayFlags)
20+
21+
ret void
22+
}
23+
24+
; Function Attrs: nounwind
25+
declare i32 @dx.op.allocateRayQuery(i32, i32) #1
26+
27+
attributes #0 = { nounwind readnone }
28+
attributes #1 = { nounwind }
29+
30+
!llvm.ident = !{!0}
31+
!dx.version = !{!1}
32+
!dx.valver = !{!1}
33+
!dx.shaderModel = !{!2}
34+
!dx.resources = !{!3}
35+
!dx.viewIdState = !{!7}
36+
!dx.entryPoints = !{!8}
37+
38+
!0 = !{!"dxc(private) 1.8.0.4793 (OMM00, ef1472a14a0d-dirty)"}
39+
!1 = !{i32 1, i32 9}
40+
!2 = !{!"vs", i32 6, i32 9}
41+
!3 = !{!4, null, null, null}
42+
!4 = !{!5}
43+
!5 = !{i32 0, %struct.RaytracingAccelerationStructure* undef, !"", i32 0, i32 0, i32 1, i32 16, i32 0, !6}
44+
!6 = !{i32 0, i32 4}
45+
!7 = !{[2 x i32] [i32 17, i32 0]}
46+
!8 = !{void ()* @main, !"main", !9, !3, !22}
47+
!9 = !{!10, null, null}
48+
!10 = !{!11, !13, !15, !18, !20}
49+
!11 = !{i32 0, !"IDX", i8 5, i8 0, !12, i8 0, i32 1, i8 1, i32 0, i8 0, null}
50+
!12 = !{i32 0}
51+
!13 = !{i32 1, !"RAYDESC", i8 9, i8 0, !12, i8 0, i32 1, i8 3, i32 1, i8 0, !14}
52+
!14 = !{i32 3, i32 7}
53+
!15 = !{i32 2, !"RAYDESC", i8 9, i8 0, !16, i8 0, i32 1, i8 1, i32 2, i8 0, !17}
54+
!16 = !{i32 1}
55+
!17 = !{i32 3, i32 1}
56+
!18 = !{i32 3, !"RAYDESC", i8 9, i8 0, !19, i8 0, i32 1, i8 3, i32 3, i8 0, !14}
57+
!19 = !{i32 2}
58+
!20 = !{i32 4, !"RAYDESC", i8 9, i8 0, !21, i8 0, i32 1, i8 1, i32 4, i8 0, !17}
59+
!21 = !{i32 3}
60+
!22 = !{i32 0, i64 33554432}

0 commit comments

Comments
 (0)