Skip to content

Commit 19360a8

Browse files
authored
Validate CBuffer size to max of 65536 bytes (#3507)
1 parent a7770e6 commit 19360a8

10 files changed

Lines changed: 92 additions & 0 deletions

File tree

docs/DXIL.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3126,6 +3126,7 @@ SM.APPENDANDCONSUMEONSAMEUAV BufferUpdateCounter inc and dec on a g
31263126
SM.CBUFFERARRAYOFFSETALIGNMENT CBuffer array offset must be aligned to 16-bytes
31273127
SM.CBUFFERELEMENTOVERFLOW CBuffer elements must not overflow
31283128
SM.CBUFFEROFFSETOVERLAP CBuffer offsets must not overlap
3129+
SM.CBUFFERSIZE CBuffer size must not exceed 65536 bytes
31293130
SM.CBUFFERTEMPLATETYPEMUSTBESTRUCT D3D12 constant/texture buffer template element can only be a struct.
31303131
SM.COMPLETEPOSITION Not all elements of SV_Position were written.
31313132
SM.CONSTANTINTERPMODE Interpolation mode must be constant for MS primitive output.

include/dxc/HLSL/DxilValidation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ enum class ValidationRule : unsigned {
202202
SmCBufferArrayOffsetAlignment, // CBuffer array offset must be aligned to 16-bytes
203203
SmCBufferElementOverflow, // CBuffer elements must not overflow
204204
SmCBufferOffsetOverlap, // CBuffer offsets must not overlap
205+
SmCBufferSize, // CBuffer size must not exceed 65536 bytes
205206
SmCBufferTemplateTypeMustBeStruct, // D3D12 constant/texture buffer template element can only be a struct.
206207
SmCSNoSignatures, // Compute shaders must not have shader signatures.
207208
SmCompletePosition, // Not all elements of SV_Position were written.

lib/HLSL/DxilValidation.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
261261
case hlsl::ValidationRule::SmCSNoSignatures: return "Compute shaders must not have shader signatures.";
262262
case hlsl::ValidationRule::SmCBufferTemplateTypeMustBeStruct: return "D3D12 constant/texture buffer template element can only be a struct.";
263263
case hlsl::ValidationRule::SmResourceRangeOverlap: return "Resource %0 with base %1 size %2 overlap with other resource with base %3 size %4 in space %5.";
264+
case hlsl::ValidationRule::SmCBufferSize: return "CBuffer size is %0 bytes, exceeding maximum of 65536 bytes.";
264265
case hlsl::ValidationRule::SmCBufferOffsetOverlap: return "CBuffer %0 has offset overlaps at %1.";
265266
case hlsl::ValidationRule::SmCBufferElementOverflow: return "CBuffer %0 size insufficient for element at offset %1.";
266267
case hlsl::ValidationRule::SmCBufferArrayOffsetAlignment: return "CBuffer %0 has unaligned array offset at %1.";
@@ -4176,6 +4177,12 @@ static void ValidateCBuffer(DxilCBuffer &cb, ValidationContext &ValCtx) {
41764177
ValidationRule::SmCBufferTemplateTypeMustBeStruct);
41774178
return;
41784179
}
4180+
if (cb.GetSize() > (DXIL::kMaxCBufferSize << 4)) {
4181+
ValCtx.EmitResourceFormatError(&cb,
4182+
ValidationRule::SmCBufferSize,
4183+
{std::to_string(cb.GetSize())});
4184+
return;
4185+
}
41794186
StructType *ST = cast<StructType>(Ty);
41804187
DxilTypeSystem &typeSys = ValCtx.DxilMod.GetTypeSystem();
41814188
DxilStructAnnotation *annotation = typeSys.GetStructAnnotation(ST);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// CHECK: error: CBuffer size is 65552 bytes, exceeding maximum of 65536 bytes.
4+
5+
cbuffer Foo1 : register(b5)
6+
{
7+
float4 g1 : packoffset(c4096);
8+
float4 g2 : packoffset(c0);
9+
}
10+
11+
float4 main() : SV_TARGET
12+
{
13+
return g2+g1;
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// CHECK: call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %{{.*}}, i32 4095)
4+
5+
cbuffer Foo1 : register(b5)
6+
{
7+
float arr[4096];
8+
}
9+
10+
float4 main() : SV_TARGET
11+
{
12+
return arr[4095];
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
4+
5+
cbuffer Foo1 : register(b5)
6+
{
7+
float arr[4097];
8+
}
9+
10+
float4 main() : SV_TARGET
11+
{
12+
return arr[4096];
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// CHECK: call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %{{.*}}, i32 4095)
4+
5+
cbuffer Foo1 : register(b5)
6+
{
7+
float arr[4096];
8+
float3 after_array;
9+
}
10+
11+
float4 main() : SV_TARGET
12+
{
13+
return float4(arr[4095], after_array);
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
4+
5+
cbuffer Foo1 : register(b5)
6+
{
7+
float arr[4096];
8+
float3 after_array;
9+
float overflow;
10+
}
11+
12+
float4 main() : SV_TARGET
13+
{
14+
return float4(arr[4095] + overflow, after_array);
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
2+
3+
// CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
4+
5+
cbuffer Foo1 : register(b5)
6+
{
7+
float arr[4096] : packoffset(c1);
8+
}
9+
10+
float4 main() : SV_TARGET
11+
{
12+
return arr[4095];
13+
}

utils/hct/hctdb.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,6 +2624,7 @@ def build_valrules(self):
26242624
self.add_valrule("Sm.CSNoSignatures", "Compute shaders must not have shader signatures.")
26252625
self.add_valrule("Sm.CBufferTemplateTypeMustBeStruct", "D3D12 constant/texture buffer template element can only be a struct.")
26262626
self.add_valrule_msg("Sm.ResourceRangeOverlap", "Resource ranges must not overlap", "Resource %0 with base %1 size %2 overlap with other resource with base %3 size %4 in space %5.")
2627+
self.add_valrule_msg("Sm.CBufferSize", "CBuffer size must not exceed 65536 bytes", "CBuffer size is %0 bytes, exceeding maximum of 65536 bytes.")
26272628
self.add_valrule_msg("Sm.CBufferOffsetOverlap", "CBuffer offsets must not overlap", "CBuffer %0 has offset overlaps at %1.")
26282629
self.add_valrule_msg("Sm.CBufferElementOverflow", "CBuffer elements must not overflow", "CBuffer %0 size insufficient for element at offset %1.")
26292630
self.add_valrule_msg("Sm.CBufferArrayOffsetAlignment", "CBuffer array offset must be aligned to 16-bytes", "CBuffer %0 has unaligned array offset at %1.")

0 commit comments

Comments
 (0)