Skip to content

Commit 474f9d2

Browse files
simolltex3dgithub-actions[bot]
authored
[SER] Validate 'reordercoherent' resource property (#7429)
Validates: All resources All instructions using resources Rules: 'reordercoherent' may only be used in SM6.9+ in resource handles and resource declarations. Increment/DecrementCounter unsupported on 'reordercoherent' resources. Create a new DXIL 1.9 variant of the 'CompileWhenOkThenCheckRDAT' container test and restore the old one without 'reordercoherent' (pre-#7250). The validator now rejects 'reordercoherent' in DXIL 1.3 and accepts from DXIL 1.9+. SER implementation tracker: #7214 --------- Co-authored-by: Tex Riddell <[email protected]> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 422604b commit 474f9d2

File tree

7 files changed

+345
-13
lines changed

7 files changed

+345
-13
lines changed

docs/DXIL.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -3175,6 +3175,7 @@ INSTR.OPCONSTRANGE Constant values must be in
31753175
INSTR.OPERANDRANGE DXIL intrinsic operand must be within defined range
31763176
INSTR.PARAMMULTIPLE Parameter must be a valid multiple
31773177
INSTR.PTRBITCAST Pointer type bitcast must be have same size.
3178+
INSTR.REORDERCOHERENTREQUIRESSM69 reordercoherent requires SM 6.9 or later.
31783179
INSTR.RESOURCECLASSFORLOAD load can only run on UAV/SRV resource.
31793180
INSTR.RESOURCECLASSFORSAMPLERGATHER sample, lod and gather should be on srv resource.
31803181
INSTR.RESOURCECLASSFORUAVSTORE store should be on uav resource.
@@ -3216,14 +3217,14 @@ META.BARYCENTRICSTWOPERSPECTIVES There can only be up to tw
32163217
META.BRANCHFLATTEN Can't use branch and flatten attributes together.
32173218
META.CLIPCULLMAXCOMPONENTS Combined elements of SV_ClipDistance and SV_CullDistance must fit in 8 components
32183219
META.CLIPCULLMAXROWS Combined elements of SV_ClipDistance and SV_CullDistance must fit in two rows.
3220+
META.COHERENCENOTONAPPENDCONSUME globally/reorder coherent incompatible with append/consume/counter buffers
32193221
META.COMPUTEWITHNODE Compute entry must not have node metadata
32203222
META.CONTROLFLOWHINTNOTONCONTROLFLOW Control flow hint only works on control flow inst.
32213223
META.DENSERESIDS Resource identifiers must be zero-based and dense.
32223224
META.DUPLICATESYSVALUE System value may only appear once in signature
32233225
META.ENTRYFUNCTION entrypoint not found.
32243226
META.FLAGSUSAGE Flags must match usage.
32253227
META.FORCECASEONSWITCH Attribute forcecase only works for switch.
3226-
META.GLCNOTONAPPENDCONSUME globallycoherent cannot be used with append/consume buffers: '%0'.
32273228
META.INTEGERINTERPMODE Interpolation mode on integer must be Constant
32283229
META.INTERPMODEINONEROW Interpolation mode must be identical for all elements packed into the same row.
32293230
META.INTERPMODEVALID Interpolation mode must be valid

lib/DxilValidation/DxilValidation.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ ValidateSignatureAccess(Instruction *I, DxilSignature &Sig, Value *SigId,
165165

166166
static DxilResourceProperties GetResourceFromHandle(Value *Handle,
167167
ValidationContext &ValCtx) {
168-
if (!isa<CallInst>(Handle)) {
168+
CallInst *HandleCall = dyn_cast<CallInst>(Handle);
169+
if (!HandleCall) {
169170
if (Instruction *I = dyn_cast<Instruction>(Handle))
170171
ValCtx.EmitInstrError(I, ValidationRule::InstrHandleNotFromCreateHandle);
171172
else
@@ -175,10 +176,13 @@ static DxilResourceProperties GetResourceFromHandle(Value *Handle,
175176
}
176177

177178
DxilResourceProperties RP = ValCtx.GetResourceFromVal(Handle);
178-
if (RP.getResourceClass() == DXIL::ResourceClass::Invalid) {
179+
if (RP.getResourceClass() == DXIL::ResourceClass::Invalid)
179180
ValCtx.EmitInstrError(cast<CallInst>(Handle),
180181
ValidationRule::InstrHandleNotFromCreateHandle);
181-
}
182+
if (RP.Basic.IsReorderCoherent &&
183+
!ValCtx.DxilMod.GetShaderModel()->IsSM69Plus())
184+
ValCtx.EmitInstrError(HandleCall,
185+
ValidationRule::InstrReorderCoherentRequiresSM69);
182186

183187
return RP;
184188
}
@@ -4182,6 +4186,9 @@ static void ValidateResourceOverlap(
41824186

41834187
static void ValidateResource(hlsl::DxilResource &Res,
41844188
ValidationContext &ValCtx) {
4189+
if (Res.IsReorderCoherent() && !ValCtx.DxilMod.GetShaderModel()->IsSM69Plus())
4190+
ValCtx.EmitResourceError(&Res,
4191+
ValidationRule::InstrReorderCoherentRequiresSM69);
41854192
switch (Res.GetKind()) {
41864193
case DXIL::ResourceKind::RawBuffer:
41874194
case DXIL::ResourceKind::TypedBuffer:
@@ -4413,10 +4420,13 @@ static void ValidateResources(ValidationContext &ValCtx) {
44134420
ValCtx.EmitResourceError(Uav.get(),
44144421
ValidationRule::SmCounterOnlyOnStructBuf);
44154422
}
4416-
if (Uav->HasCounter() && Uav->IsGloballyCoherent())
4417-
ValCtx.EmitResourceFormatError(Uav.get(),
4418-
ValidationRule::MetaGlcNotOnAppendConsume,
4419-
{ValCtx.GetResourceName(Uav.get())});
4423+
const bool UavIsCoherent =
4424+
Uav->IsGloballyCoherent() || Uav->IsReorderCoherent();
4425+
if (Uav->HasCounter() && UavIsCoherent) {
4426+
StringRef Prefix = Uav->IsGloballyCoherent() ? "globally" : "reorder";
4427+
ValCtx.EmitResourceFormatError(
4428+
Uav.get(), ValidationRule::MetaCoherenceNotOnAppendConsume, {Prefix});
4429+
}
44204430

44214431
ValidateResource(*Uav, ValCtx);
44224432
ValidateResourceOverlap(*Uav, UavAllocator, ValCtx);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
; REQUIRES: dxil-1-9
2+
; RUN: not %dxv %s 2>&1 | FileCheck %s
3+
4+
; COM: Original HLSL source:
5+
; COM: reordercoherent RWStructuredBuffer<float> buffer;
6+
; COM:
7+
; COM:
8+
; COM: [Shader("raygeneration")]
9+
; COM: void
10+
; COM: main()
11+
; COM: {
12+
; COM: buffer.IncrementCounter();
13+
; COM: buffer.DecrementCounter();
14+
; COM: }
15+
16+
; CHECK: error: reordercoherent cannot be used on buffer with counter 'buffer'
17+
; CHECK-NEXT: Validation failed.
18+
19+
; shader hash: 638950814a9023bf537d61dbb330a4c8
20+
;
21+
; Buffer Definitions:
22+
;
23+
; Resource bind info for buffer
24+
; {
25+
;
26+
; float $Element; ; Offset: 0 Size: 4
27+
;
28+
; }
29+
;
30+
;
31+
; Resource Bindings:
32+
;
33+
; Name Type Format Dim ID HLSL Bind Count
34+
; ------------------------------ ---------- ------- ----------- ------- -------------- ------
35+
; buffer UAV struct r/w+cnt U0u4294967295,space4294967295 1
36+
;
37+
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"
38+
target triple = "dxil-ms-dx"
39+
40+
%dx.types.Handle = type { i8* }
41+
%dx.types.ResourceProperties = type { i32, i32 }
42+
%"class.RWStructuredBuffer<float>" = type { float }
43+
44+
@"\01?buffer@@3V?$RWStructuredBuffer@M@@A" = external constant %dx.types.Handle, align 4
45+
46+
; Function Attrs: nounwind
47+
define void @"\01?main@@YAXXZ"() #0 {
48+
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?buffer@@3V?$RWStructuredBuffer@M@@A", align 4
49+
%2 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
50+
%3 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %2, %dx.types.ResourceProperties { i32 102412, i32 4 }) ; AnnotateHandle(res,props) resource: reordercoherent RWStructuredBuffer<stride=4, counter>
51+
%4 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %3, i8 1) ; BufferUpdateCounter(uav,inc)
52+
%5 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
53+
%6 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %5, %dx.types.ResourceProperties { i32 102412, i32 4 }) ; AnnotateHandle(res,props) resource: reordercoherent RWStructuredBuffer<stride=4, counter>
54+
%7 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %6, i8 -1) ; BufferUpdateCounter(uav,inc)
55+
ret void
56+
}
57+
58+
; Function Attrs: nounwind
59+
declare i32 @dx.op.bufferUpdateCounter(i32, %dx.types.Handle, i8) #0
60+
61+
; Function Attrs: nounwind readnone
62+
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
63+
64+
; Function Attrs: nounwind readonly
65+
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #2
66+
67+
attributes #0 = { nounwind }
68+
attributes #1 = { nounwind readnone }
69+
attributes #2 = { nounwind readonly }
70+
71+
!dx.version = !{!0}
72+
!dx.valver = !{!0}
73+
!dx.shaderModel = !{!1}
74+
!dx.resources = !{!2}
75+
!dx.typeAnnotations = !{!6}
76+
!dx.entryPoints = !{!10, !12}
77+
78+
!0 = !{i32 1, i32 9}
79+
!1 = !{!"lib", i32 6, i32 9}
80+
!2 = !{null, !3, null, null}
81+
!3 = !{!4}
82+
!4 = !{i32 0, %"class.RWStructuredBuffer<float>"* bitcast (%dx.types.Handle* @"\01?buffer@@3V?$RWStructuredBuffer@M@@A" to %"class.RWStructuredBuffer<float>"*), !"buffer", i32 -1, i32 -1, i32 1, i32 12, i1 false, i1 true, i1 false, !5}
83+
!5 = !{i32 1, i32 4, i32 4, i1 true}
84+
!6 = !{i32 1, void ()* @"\01?main@@YAXXZ", !7}
85+
!7 = !{!8}
86+
!8 = !{i32 1, !9, !9}
87+
!9 = !{}
88+
!10 = !{null, !"", null, !2, !11}
89+
!11 = !{i32 0, i64 8589934608}
90+
!12 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !13}
91+
!13 = !{i32 8, i32 7, i32 5, !14}
92+
!14 = !{i32 0}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
; REQUIRES: dxil-1-8
2+
; RUN: not %dxv %s 2>&1 | FileCheck %s
3+
4+
5+
; CHECK: error: reordercoherent requires SM 6.9 or later. 'buf'
6+
; CHECK-NEXT: Function: ?main@@YAXXZ: error: reordercoherent requires SM 6.9 or later.
7+
; CHECK-NEXT: note: at '%3 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %2, %dx.types.ResourceProperties { i32 69643, i32 0 })' in block '#0' of function '?main@@YAXXZ'.
8+
; CHECK-NEXT: Function: ?main@@YAXXZ: error: reordercoherent requires SM 6.9 or later.
9+
; CHECK-NEXT: note: at '%3 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %2, %dx.types.ResourceProperties { i32 69643, i32 0 })' in block '#0' of function '?main@@YAXXZ'.
10+
; CHECK-NEXT: Validation failed.
11+
; COM: Original HLSL source:
12+
; COM: reordercoherent RWByteAddressBuffer buf;
13+
; COM:
14+
; COM: [Shader("raygeneration")]
15+
; COM: void main()
16+
; COM: {
17+
; COM: buf.Store(0, 11.f);
18+
; COM: }
19+
20+
; shader hash: f7be6354830d1423764991adcfc26b0b
21+
;
22+
; Buffer Definitions:
23+
;
24+
;
25+
; Resource Bindings:
26+
;
27+
; Name Type Format Dim ID HLSL Bind Count
28+
; ------------------------------ ---------- ------- ----------- ------- -------------- ------
29+
; buf UAV byte r/w U0u4294967295,space4294967295 1
30+
;
31+
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"
32+
target triple = "dxil-ms-dx"
33+
34+
%dx.types.Handle = type { i8* }
35+
%dx.types.ResourceProperties = type { i32, i32 }
36+
%struct.RWByteAddressBuffer = type { i32 }
37+
38+
@"\01?buf@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
39+
40+
; Function Attrs: nounwind
41+
define void @"\01?main@@YAXXZ"() #0 {
42+
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?buf@@3URWByteAddressBuffer@@A", align 4
43+
%2 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
44+
%3 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %2, %dx.types.ResourceProperties { i32 69643, i32 0 }) ; AnnotateHandle(res,props) resource: reordercoherent RWByteAddressBuffer
45+
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %3, i32 0, i32 undef, float 1.100000e+01, float undef, float undef, float undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
46+
ret void
47+
}
48+
49+
; Function Attrs: nounwind
50+
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #0
51+
52+
; Function Attrs: nounwind readnone
53+
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
54+
55+
; Function Attrs: nounwind readonly
56+
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #2
57+
58+
attributes #0 = { nounwind }
59+
attributes #1 = { nounwind readnone }
60+
attributes #2 = { nounwind readonly }
61+
62+
!dx.version = !{!0}
63+
!dx.valver = !{!0}
64+
!dx.shaderModel = !{!1}
65+
!dx.resources = !{!2}
66+
!dx.typeAnnotations = !{!3}
67+
!dx.entryPoints = !{!4, !5}
68+
69+
!0 = !{i32 1, i32 8}
70+
!1 = !{!"lib", i32 6, i32 8}
71+
!2 = !{null, !6, null, null}
72+
!3 = !{i32 1, void ()* @"\01?main@@YAXXZ", !7}
73+
!4 = !{null, !"", null, !2, !8}
74+
!5 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !9}
75+
!6 = !{!10}
76+
!7 = !{!11}
77+
!8 = !{i32 0, i64 8589934608}
78+
!9 = !{i32 8, i32 7, i32 5, !12}
79+
!10 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?buf@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"buf", i32 -1, i32 -1, i32 1, i32 11, i1 false, i1 false, i1 false, !13}
80+
!11 = !{i32 1, !14, !14}
81+
!12 = !{i32 0}
82+
!13 = !{i32 4, i1 true}
83+
!14 = !{}

0 commit comments

Comments
 (0)