Skip to content

Commit fa3fe95

Browse files
alsepkowgithub-actions[bot]damyanp
authored
Execution Tests: Fix bugs in LoadAndStoreOps (#7856)
This PR fixes three issues in the LoadAndStoreOp tests: Buffer sizing for odd-sized vectors: Previously, stride and resource width calculations could misalign, causing runtime errors. Descriptor correctness for StructuredBuffers: Formats, flags, and the StructuredByteStride were not consistently set. WARP tolerated this but some IHVs reported issues as their drivers are stricter about this. Some of the StructuredBuffer tests were hitting the runtime size limit of 2048 bytes for StructuredBuffers. I updated the logic around InputVectorSizes to account for this. These changes ensure proper alignment, descriptor initialization, and resource sizing across all of the test cases. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Damyan Pepper <[email protected]>
1 parent bb0b3d6 commit fa3fe95

File tree

2 files changed

+86
-74
lines changed

2 files changed

+86
-74
lines changed

tools/clang/unittests/HLSLExec/LongVectors.cpp

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ static const std::unordered_set<OpType> LoadAndStoreOpTypes = {
118118
OpType::LoadAndStore_RD_SB_UAV, OpType::LoadAndStore_RD_SB_SRV,
119119
};
120120

121+
static bool IsStructuredBufferLoadAndStoreOp(OpType Op) {
122+
switch (Op) {
123+
case OpType::LoadAndStore_RDH_SB_UAV:
124+
case OpType::LoadAndStore_RDH_SB_SRV:
125+
case OpType::LoadAndStore_DT_SB_UAV:
126+
case OpType::LoadAndStore_DT_SB_SRV:
127+
case OpType::LoadAndStore_RD_SB_UAV:
128+
case OpType::LoadAndStore_RD_SB_SRV:
129+
return true;
130+
default:
131+
return false;
132+
}
133+
}
134+
121135
// Helper to fill the test data from the shader buffer based on type.
122136
// Convenient to be used when copying HLSL*_t types so we can use the
123137
// underlying type.
@@ -459,8 +473,9 @@ runTest(ID3D12Device *D3DDevice, bool VerboseLogging,
459473
return OutData;
460474
}
461475

462-
// LoadAndStore operations dynamically configure sizes on the underlying
463-
// resources based on the vector size and data type size.
476+
// LoadAndStore operations dynamically configure the UAV/SRV formats and sizes
477+
// based on the vector size and data type. We also adjust the format and flags
478+
// based on whether we're using raw buffers or structured buffers.
464479
void configureLoadAndStoreShaderOp(const Operation &Operation,
465480
const DataType &OpDataType,
466481
size_t VectorSize, size_t ElementSize,
@@ -471,49 +486,51 @@ void configureLoadAndStoreShaderOp(const Operation &Operation,
471486
st::ShaderOp *ShaderOp = ShaderOpSet->GetShaderOp(Operation.ShaderName);
472487
DXASSERT(ShaderOp, "Invalid ShaderOp name");
473488

474-
// When using DXGI_FORMAT_R32_TYPELESS, we need to compute the number of
475-
// 32-bit elements required to hold the vector.
489+
// When using DXGI_FORMAT_R32_TYPELESS (raw buffer cases) we need to compute
490+
// the number of 32-bit elements required to hold the vector.
476491
const UINT Num32BitElements =
477492
static_cast<UINT>((VectorSize * OpDataType.HLSLSizeInBytes + 3) / 4);
478493

479-
auto ComputeNumElements = [&](DXGI_FORMAT Format) -> UINT {
480-
switch (Format) {
481-
case DXGI_FORMAT_R32_TYPELESS:
482-
return Num32BitElements;
483-
case DXGI_FORMAT_UNKNOWN:
484-
return static_cast<UINT>(VectorSize);
485-
default:
486-
// Unexpected. LoadAndStore ops should only be using these two formats.
487-
DXASSERT_NOMSG(false);
488-
return 0;
489-
}
490-
};
491-
492-
auto ComputeWidth = [&](DXGI_FORMAT Format) -> UINT {
493-
switch (Format) {
494-
case DXGI_FORMAT_R32_TYPELESS:
495-
return Num32BitElements * 4;
496-
case DXGI_FORMAT_UNKNOWN:
497-
return static_cast<UINT>(VectorSize * ElementSize);
498-
default:
499-
// Unexpected. LoadAndStore ops should only be using these two formats.
500-
DXASSERT_NOMSG(false);
501-
return 0;
502-
}
503-
};
494+
const UINT StructureByteStride = static_cast<UINT>(ElementSize * VectorSize);
504495

496+
const bool IsSB = IsStructuredBufferLoadAndStoreOp(Operation.Type);
505497
if (!ShaderOp->DescriptorHeaps.empty()) {
506-
DXASSERT_NOMSG(ShaderOp->DescriptorHeaps.size() == 1);
498+
DXASSERT(ShaderOp->DescriptorHeaps.size() == 1,
499+
"Programmer error: Expecting a single descriptor heap for "
500+
"LoadAndStore tests");
501+
507502
for (auto &D : ShaderOp->DescriptorHeaps[0].Descriptors) {
508-
if (_stricmp(D.Kind, "UAV") == 0)
509-
D.UavDesc.Buffer.NumElements = ComputeNumElements(D.UavDesc.Format);
510-
else if (_stricmp(D.Kind, "SRV") == 0)
511-
D.SrvDesc.Buffer.NumElements = ComputeNumElements(D.SrvDesc.Format);
503+
const bool IsUAV = (_stricmp(D.Kind, "UAV") == 0);
504+
DXASSERT(IsUAV || (_stricmp(D.Kind, "SRV") == 0),
505+
"Programmer error: Expecting UAV or SRV descriptors only");
506+
507+
if (IsSB) {
508+
if (IsUAV) {
509+
D.UavDesc.Format = DXGI_FORMAT_UNKNOWN;
510+
D.UavDesc.Buffer.NumElements = 1; // One StructuredBuffer
511+
D.UavDesc.Buffer.StructureByteStride = StructureByteStride;
512+
} else {
513+
D.SrvDesc.Format = DXGI_FORMAT_UNKNOWN;
514+
D.SrvDesc.Buffer.NumElements = 1; // One StructuredBuffer
515+
D.SrvDesc.Buffer.StructureByteStride = StructureByteStride;
516+
}
517+
} else { // Raw buffer
518+
if (IsUAV) {
519+
D.UavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
520+
D.UavDesc.Buffer.NumElements = Num32BitElements;
521+
D.UavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
522+
} else {
523+
D.SrvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
524+
D.SrvDesc.Buffer.NumElements = Num32BitElements;
525+
D.SrvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
526+
}
527+
}
512528
}
513529
}
514530

531+
const UINT BufferWidth = IsSB ? StructureByteStride : (Num32BitElements * 4);
515532
for (auto &R : ShaderOp->Resources)
516-
R.Desc.Width = ComputeWidth(R.Desc.Format);
533+
R.Desc.Width = BufferWidth;
517534
}
518535

519536
template <typename T>
@@ -1283,10 +1300,24 @@ template <typename T, OpType OP>
12831300
void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging,
12841301
size_t OverrideInputSize) {
12851302
std::vector<size_t> InputVectorSizes;
1303+
const std::array<size_t, 8> DefaultInputSizes = {3, 5, 16, 17,
1304+
35, 100, 256, 1024};
1305+
12861306
if (OverrideInputSize)
12871307
InputVectorSizes.push_back(OverrideInputSize);
1288-
else
1289-
InputVectorSizes = {3, 5, 16, 17, 35, 100, 256, 1024};
1308+
else {
1309+
// StructuredBuffers have a max size of 2048 bytes.
1310+
const size_t MaxInputSize =
1311+
IsStructuredBufferLoadAndStoreOp(OP) ? 2048 / sizeof(T) : 1024;
1312+
1313+
for (size_t Size : DefaultInputSizes) {
1314+
if (Size <= MaxInputSize)
1315+
InputVectorSizes.push_back(Size);
1316+
}
1317+
1318+
if (InputVectorSizes.empty() || MaxInputSize != InputVectorSizes.back())
1319+
InputVectorSizes.push_back(MaxInputSize);
1320+
}
12901321

12911322
constexpr const Operation &Operation = getOperation(OP);
12921323

tools/clang/unittests/HLSLExec/ShaderOpArith.xml

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,13 +3721,9 @@ void MSMain(uint GID : SV_GroupIndex,
37213721
<RootSignature>UAV(u0), UAV(u1)</RootSignature>
37223722
<!-- Note: Width is set dynamically (via c++ test code) based on the input vector size and element type -->
37233723
<Resource Name="InputVector1" Dimension="BUFFER" Init="ByName"
3724-
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
3725-
TransitionTo="UNORDERED_ACCESS">
3726-
</Resource>
3724+
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
37273725
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
3728-
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
3729-
TransitionTo="UNORDERED_ACCESS">
3730-
</Resource>
3726+
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
37313727

37323728
<RootValues>
37333729
<RootValue Index="0" ResName="InputVector1" />
@@ -3766,8 +3762,7 @@ void MSMain(uint GID : SV_GroupIndex,
37663762
<Resource Name="InputVector1" Dimension="BUFFER" Init="ByName"/>
37673763
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
37683764
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
3769-
TransitionTo="UNORDERED_ACCESS">
3770-
</Resource>
3765+
TransitionTo="UNORDERED_ACCESS"/>
37713766

37723767
<RootValues>
37733768
<RootValue Index="0" ResName="InputVector1" />
@@ -3804,23 +3799,20 @@ void MSMain(uint GID : SV_GroupIndex,
38043799
<RootSignature>DescriptorTable(UAV(u0, numDescriptors=2))</RootSignature>
38053800
<!-- Note: Width is set dynamically (via c++ test code) based on the input vector size and element type -->
38063801
<Resource Name="InputVector1" Dimension="BUFFER" Width="0" Init="ByName"
3807-
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
3808-
TransitionTo="UNORDERED_ACCESS">
3809-
</Resource>
3802+
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
38103803
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
38113804
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
3812-
TransitionTo="UNORDERED_ACCESS">
3813-
</Resource>
3805+
TransitionTo="UNORDERED_ACCESS"/>
38143806

38153807
<!-- Note: NumElements is set dynamically (via c++ test code) based on the
38163808
input vector size and element type -->
38173809
<RootValues>
38183810
<RootValue HeapName="DescriptorTable" Index="0" />
38193811
</RootValues>
38203812
<DescriptorHeap Name="DescriptorTable" Type="CBV_SRV_UAV">
3821-
<Descriptor Name="InputVector1" Kind="UAV" ResName="InputVector1" NumElements="0" Format="R32_Typeless" Flags="RAW"/>
3813+
<Descriptor Name="InputVector1" Kind="UAV" ResName="InputVector1" NumElements="0"/>
38223814
<Descriptor Name="OutputVector" Kind="UAV" ResName="OutputVector"
3823-
NumElements="0" Format="R32_Typeless" Flags="RAW"/>
3815+
NumElements="0"/>
38243816
</DescriptorHeap>
38253817

38263818
<Shader Name="CS" Target="cs_6_9" EntryPoint="main">
@@ -3859,18 +3851,17 @@ void MSMain(uint GID : SV_GroupIndex,
38593851
<Resource Name="InputVector1" Dimension="BUFFER" Width="0" Init="ByName"/>
38603852
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
38613853
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
3862-
TransitionTo="UNORDERED_ACCESS">
3863-
</Resource>
3854+
TransitionTo="UNORDERED_ACCESS"/>
38643855

38653856
<!-- Note: NumElements is set dynamically (via c++ test code) based on the
38663857
input vector size and element type -->
38673858
<RootValues>
38683859
<RootValue HeapName="DescriptorTable" Index="0" />
38693860
</RootValues>
38703861
<DescriptorHeap Name="DescriptorTable" Type="CBV_SRV_UAV">
3871-
<Descriptor Name="InputVector1" Kind="SRV" ResName="InputVector1" NumElements="0" Format="R32_Typeless" Flags="RAW"/>
3862+
<Descriptor Name="InputVector1" Kind="SRV" ResName="InputVector1" NumElements="0"/>
38723863
<Descriptor Name="OutputVector" Kind="UAV" ResName="OutputVector"
3873-
NumElements="0" Format="R32_Typeless" Flags="RAW"/>
3864+
NumElements="0"/>
38743865
</DescriptorHeap>
38753866

38763867
<Shader Name="CS" Target="cs_6_9" EntryPoint="main">
@@ -3904,20 +3895,16 @@ void MSMain(uint GID : SV_GroupIndex,
39043895

39053896
<!-- Note: Width is set dynamically (via c++ test code) based on the input vector size and element type -->
39063897
<Resource Name="InputVector1" Dimension="BUFFER" Width="0"
3907-
InitialResourceState="COPY_DEST" Init="ByName">
3908-
</Resource>
3898+
InitialResourceState="COPY_DEST" Init="ByName"/>
39093899
<Resource Name="OutputVector" Dimension="BUFFER" Width="0"
39103900
InitialResourceState="COPY_DEST" Init="ByName" ReadBack="true"
3911-
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
3912-
</Resource>
3901+
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
39133902

39143903
<!-- Note: NumElements is set dynamically (via c++ test code) based on the
39153904
input vector size and element type -->
39163905
<DescriptorHeap Name="ResourceDescriptorHeap" Type="CBV_SRV_UAV">
3917-
<Descriptor Name="InputVector1" Kind="SRV" Flags='RAW' NumElements="0"
3918-
Format="R32_Typeless"/>
3919-
<Descriptor Name="OutputVector" Kind="UAV" Flags='RAW' NumElements="0"
3920-
Format="R32_Typeless"/>
3906+
<Descriptor Name="InputVector1" Kind="SRV" NumElements="0"/>
3907+
<Descriptor Name="OutputVector" Kind="UAV" NumElements="0"/>
39213908
</DescriptorHeap>
39223909

39233910
<Shader Name="CS" Target="cs_6_9" EntryPoint="main">
@@ -3953,21 +3940,15 @@ void MSMain(uint GID : SV_GroupIndex,
39533940

39543941
<!-- Note: Width is set dynamically (via c++ test code) based on the input vector size and element type -->
39553942
<Resource Name="InputVector1" Dimension="BUFFER" Width="0"
3956-
InitialResourceState="COPY_DEST" Init="ByName" ReadBack="true"
3957-
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
3958-
</Resource>
3943+
Init="ByName" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
39593944
<Resource Name="OutputVector" Dimension="BUFFER" Width="0"
3960-
InitialResourceState="COPY_DEST" Init="ByName" ReadBack="true"
3961-
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS">
3962-
</Resource>
3945+
Init="ByName" ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
39633946

39643947
<!-- Note: NumElements is set dynamically (via c++ test code) based on the
39653948
input vector size and element type -->
39663949
<DescriptorHeap Name="ResourceDescriptorHeap" Type="CBV_SRV_UAV">
3967-
<Descriptor Name="InputVector1" Kind="UAV" Flags='RAW' NumElements="0"
3968-
Format="R32_Typeless"/>
3969-
<Descriptor Name="OutputVector" Kind="UAV" Flags='RAW' NumElements="0"
3970-
Format="R32_Typeless"/>
3950+
<Descriptor Name="InputVector1" Kind="UAV" NumElements="0"/>
3951+
<Descriptor Name="OutputVector" Kind="UAV" NumElements="0"/>
39713952
</DescriptorHeap>
39723953

39733954
<Shader Name="CS" Target="cs_6_9" EntryPoint="main">

0 commit comments

Comments
 (0)