Skip to content

Commit b602097

Browse files
Validate no gaps in UAV store writemask (#4495)
* Adding validation for uav continuous store * Updated message text * Add comment * Updating text and adding tests
1 parent 19fb6ef commit b602097

4 files changed

Lines changed: 40 additions & 0 deletions

File tree

docs/DXIL.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,7 @@ INSTR.TGSMRACECOND Race condition writing to shared memor
30793079
INSTR.UNDEFINEDVALUEFORUAVSTORE Assignment of undefined values to UAV.
30803080
INSTR.UNDEFRESULTFORGETDIMENSION GetDimensions used undef dimension %0 on %1.
30813081
INSTR.WRITEMASKFORTYPEDUAVSTORE store on typed uav must write to all four components of the UAV.
3082+
INSTR.WRITEMASKGAPFORUAV UAV write mask must be contiguous, starting at x: .x, .xy, .xyz, or .xyzw.
30823083
INSTR.WRITEMASKMATCHVALUEFORUAVSTORE uav store write mask must match store value mask, write mask is %0 and store value mask is %1.
30833084
META.BARYCENTRICSFLOAT3 only 'float3' type is allowed for SV_Barycentrics.
30843085
META.BARYCENTRICSINTERPOLATION SV_Barycentrics cannot be used with 'nointerpolation' type.

lib/HLSL/DxilValidation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,11 @@ static bool ValidateStorageMasks(Instruction *I, DXIL::OpCode opcode, ConstantIn
14661466
ValCtx.EmitInstrError(I, ValidationRule::InstrWriteMaskForTypedUAVStore);
14671467
}
14681468

1469+
// write mask must be contiguous (.x .xy .xyz or .xyzw)
1470+
if (!((uMask == 0xf) || (uMask == 0x7) || (uMask == 0x3) || (uMask == 0x1))) {
1471+
ValCtx.EmitInstrError(I, ValidationRule::InstrWriteMaskGapForUAV);
1472+
}
1473+
14691474
// If a bit is set in the uMask (expected values) that isn't set in stValMask (user provided values)
14701475
// then the user failed to define some of the output values.
14711476
if (uMask & ~stValMask)

tools/clang/unittests/HLSL/ValidationTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ class ValidationTest : public ::testing::Test {
7272
TEST_METHOD(TypedUAVStoreFullMask0)
7373
TEST_METHOD(TypedUAVStoreFullMask1)
7474
TEST_METHOD(UAVStoreMaskMatch)
75+
TEST_METHOD(UAVStoreMaskGap)
76+
TEST_METHOD(UAVStoreMaskGap2)
77+
TEST_METHOD(UAVStoreMaskGap3)
7578
TEST_METHOD(Recursive)
7679
TEST_METHOD(Recursive2)
7780
TEST_METHOD(Recursive3)
@@ -1197,6 +1200,36 @@ TEST_F(ValidationTest, UAVStoreMaskMatch) {
11971200
"uav store write mask must match store value mask, write mask is 7 and store value mask is 15.");
11981201
}
11991202

1203+
TEST_F(ValidationTest, UAVStoreMaskGap) {
1204+
if (m_ver.SkipDxilVersion(1, 6))
1205+
return;
1206+
RewriteAssemblyCheckMsg(
1207+
L"..\\CodeGenHLSL\\uav_store.hlsl", "ps_6_0",
1208+
"i32 2, i32 2, i32 2, i32 2, i8 15)",
1209+
"i32 undef, i32 2, i32 undef, i32 2, i8 10)",
1210+
"UAV write mask must be contiguous, starting at x: .x, .xy, .xyz, or .xyzw.");
1211+
}
1212+
1213+
TEST_F(ValidationTest, UAVStoreMaskGap2) {
1214+
if (m_ver.SkipDxilVersion(1, 6))
1215+
return;
1216+
RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\uav_store.hlsl", "ps_6_0",
1217+
"i32 2, i32 2, i32 2, i32 2, i8 15)",
1218+
"i32 undef, i32 2, i32 2, i32 2, i8 14)",
1219+
"UAV write mask must be contiguous, starting at x: "
1220+
".x, .xy, .xyz, or .xyzw.");
1221+
}
1222+
1223+
TEST_F(ValidationTest, UAVStoreMaskGap3) {
1224+
if (m_ver.SkipDxilVersion(1, 6))
1225+
return;
1226+
RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\uav_store.hlsl", "ps_6_0",
1227+
"i32 2, i32 2, i32 2, i32 2, i8 15)",
1228+
"i32 undef, i32 undef, i32 undef, i32 2, i8 8)",
1229+
"UAV write mask must be contiguous, starting at x: "
1230+
".x, .xy, .xyz, or .xyzw.");
1231+
}
1232+
12001233
TEST_F(ValidationTest, Recursive) {
12011234
// Includes coverage for user-defined functions.
12021235
TestCheck(L"..\\CodeGenHLSL\\recursive.ll");

utils/hct/hctdb.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,6 +2582,7 @@ def build_valrules(self):
25822582
self.add_valrule("Instr.BarrierModeNoMemory", "sync must include some form of memory barrier - _u (UAV) and/or _g (Thread Group Shared Memory). Only _t (thread group sync) is optional.")
25832583
self.add_valrule("Instr.BarrierModeForNonCS", "sync in a non-Compute/Amplification/Mesh Shader must only sync UAV (sync_uglobal).")
25842584
self.add_valrule("Instr.WriteMaskForTypedUAVStore", "store on typed uav must write to all four components of the UAV.")
2585+
self.add_valrule("Instr.WriteMaskGapForUAV", "UAV write mask must be contiguous, starting at x: .x, .xy, .xyz, or .xyzw.")
25852586
self.add_valrule("Instr.ResourceKindForCalcLOD","lod requires resource declared as texture1D/2D/3D/Cube/CubeArray/1DArray/2DArray.")
25862587
self.add_valrule("Instr.ResourceKindForSample", "sample/_l/_d requires resource declared as texture1D/2D/3D/Cube/1DArray/2DArray/CubeArray.")
25872588
self.add_valrule("Instr.ResourceKindForSampleC", "samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray.")

0 commit comments

Comments
 (0)