Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 68 additions & 37 deletions tools/clang/unittests/HLSLExec/LongVectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ static const std::unordered_set<OpType> LoadAndStoreOpTypes = {
OpType::LoadAndStore_RD_SB_UAV, OpType::LoadAndStore_RD_SB_SRV,
};

static bool IsStructuredBufferLoadAndStoreOp(OpType Op) {
switch (Op) {
case OpType::LoadAndStore_RDH_SB_UAV:
case OpType::LoadAndStore_RDH_SB_SRV:
case OpType::LoadAndStore_DT_SB_UAV:
case OpType::LoadAndStore_DT_SB_SRV:
case OpType::LoadAndStore_RD_SB_UAV:
case OpType::LoadAndStore_RD_SB_SRV:
return true;
default:
return false;
}
}

// Helper to fill the test data from the shader buffer based on type.
// Convenient to be used when copying HLSL*_t types so we can use the
// underlying type.
Expand Down Expand Up @@ -453,8 +467,9 @@ runTest(ID3D12Device *D3DDevice, bool VerboseLogging,
return OutData;
}

// LoadAndStore operations dynamically configure sizes on the underlying
// resources based on the vector size and data type size.
// LoadAndStore operations dynamically configure the UAV/SRV formats and sizes
// based on the vector size and data type. We also adjust the format and flags
// based on whether we're using raw buffers or structured buffers.
void configureLoadAndStoreShaderOp(const Operation &Operation,
const DataType &OpDataType,
size_t VectorSize, size_t ElementSize,
Expand All @@ -465,49 +480,51 @@ void configureLoadAndStoreShaderOp(const Operation &Operation,
st::ShaderOp *ShaderOp = ShaderOpSet->GetShaderOp(Operation.ShaderName);
DXASSERT(ShaderOp, "Invalid ShaderOp name");

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

auto ComputeNumElements = [&](DXGI_FORMAT Format) -> UINT {
switch (Format) {
case DXGI_FORMAT_R32_TYPELESS:
return Num32BitElements;
case DXGI_FORMAT_UNKNOWN:
return static_cast<UINT>(VectorSize);
default:
// Unexpected. LoadAndStore ops should only be using these two formats.
DXASSERT_NOMSG(false);
return 0;
}
};

auto ComputeWidth = [&](DXGI_FORMAT Format) -> UINT {
switch (Format) {
case DXGI_FORMAT_R32_TYPELESS:
return Num32BitElements * 4;
case DXGI_FORMAT_UNKNOWN:
return static_cast<UINT>(VectorSize * ElementSize);
default:
// Unexpected. LoadAndStore ops should only be using these two formats.
DXASSERT_NOMSG(false);
return 0;
}
};
const UINT StructureByteStride = static_cast<UINT>(ElementSize * VectorSize);

const bool IsSB = IsStructuredBufferLoadAndStoreOp(Operation.Type);
if (!ShaderOp->DescriptorHeaps.empty()) {
DXASSERT_NOMSG(ShaderOp->DescriptorHeaps.size() == 1);
DXASSERT(ShaderOp->DescriptorHeaps.size() == 1,
"Programmer error: Expecting a single descriptor heap for "
"LoadAndStore tests");

for (auto &D : ShaderOp->DescriptorHeaps[0].Descriptors) {
if (_stricmp(D.Kind, "UAV") == 0)
D.UavDesc.Buffer.NumElements = ComputeNumElements(D.UavDesc.Format);
else if (_stricmp(D.Kind, "SRV") == 0)
D.SrvDesc.Buffer.NumElements = ComputeNumElements(D.SrvDesc.Format);
const bool IsUAV = (_stricmp(D.Kind, "UAV") == 0);
DXASSERT(IsUAV || (_stricmp(D.Kind, "SRV") == 0),
"Programmer error: Expecting UAV or SRV descriptors only");

if (IsSB) {
if (IsUAV) {
D.UavDesc.Format = DXGI_FORMAT_UNKNOWN;
D.UavDesc.Buffer.NumElements = 1; // One StructuredBuffer
D.UavDesc.Buffer.StructureByteStride = StructureByteStride;
} else {
D.SrvDesc.Format = DXGI_FORMAT_UNKNOWN;
D.SrvDesc.Buffer.NumElements = 1; // One StructuredBuffer
D.SrvDesc.Buffer.StructureByteStride = StructureByteStride;
}
} else { // Raw buffer
if (IsUAV) {
D.UavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
D.UavDesc.Buffer.NumElements = Num32BitElements;
D.UavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
} else {
D.SrvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
D.SrvDesc.Buffer.NumElements = Num32BitElements;
D.SrvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
}
}
}
}

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

template <typename T>
Expand Down Expand Up @@ -1187,10 +1204,24 @@ template <typename T, OpType OP>
void dispatchTest(ID3D12Device *D3DDevice, bool VerboseLogging,
size_t OverrideInputSize) {
std::vector<size_t> InputVectorSizes;
const std::array<size_t, 8> DefaultInputSizes = {3, 5, 16, 17,
35, 100, 256, 1024};

if (OverrideInputSize)
InputVectorSizes.push_back(OverrideInputSize);
else
InputVectorSizes = {3, 5, 16, 17, 35, 100, 256, 1024};
else {
// StructuredBuffers have a max size of 2048 bytes.
const size_t MaxInputSize =
IsStructuredBufferLoadAndStoreOp(OP) ? 2048 / sizeof(T) : 1024;

for (size_t Size : DefaultInputSizes) {
if (Size <= MaxInputSize)
InputVectorSizes.push_back(Size);
}

if (InputVectorSizes.empty() || MaxInputSize != InputVectorSizes.back())
InputVectorSizes.push_back(MaxInputSize);
}

constexpr const Operation &Operation = getOperation(OP);

Expand Down
55 changes: 18 additions & 37 deletions tools/clang/unittests/HLSLExec/ShaderOpArith.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3721,13 +3721,9 @@ void MSMain(uint GID : SV_GroupIndex,
<RootSignature>UAV(u0), UAV(u1)</RootSignature>
<!-- Note: Width is set dynamically (via c++ test code) based on the input vector size and element type -->
<Resource Name="InputVector1" Dimension="BUFFER" Init="ByName"
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
TransitionTo="UNORDERED_ACCESS">
</Resource>
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
TransitionTo="UNORDERED_ACCESS">
</Resource>
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>

<RootValues>
<RootValue Index="0" ResName="InputVector1" />
Expand Down Expand Up @@ -3766,8 +3762,7 @@ void MSMain(uint GID : SV_GroupIndex,
<Resource Name="InputVector1" Dimension="BUFFER" Init="ByName"/>
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
TransitionTo="UNORDERED_ACCESS">
</Resource>
TransitionTo="UNORDERED_ACCESS"/>

<RootValues>
<RootValue Index="0" ResName="InputVector1" />
Expand Down Expand Up @@ -3804,23 +3799,20 @@ void MSMain(uint GID : SV_GroupIndex,
<RootSignature>DescriptorTable(UAV(u0, numDescriptors=2))</RootSignature>
<!-- Note: Width is set dynamically (via c++ test code) based on the input vector size and element type -->
<Resource Name="InputVector1" Dimension="BUFFER" Width="0" Init="ByName"
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
TransitionTo="UNORDERED_ACCESS">
</Resource>
Flags="ALLOW_UNORDERED_ACCESS" TransitionTo="UNORDERED_ACCESS"/>
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
TransitionTo="UNORDERED_ACCESS">
</Resource>
TransitionTo="UNORDERED_ACCESS"/>

<!-- Note: NumElements is set dynamically (via c++ test code) based on the
input vector size and element type -->
<RootValues>
<RootValue HeapName="DescriptorTable" Index="0" />
</RootValues>
<DescriptorHeap Name="DescriptorTable" Type="CBV_SRV_UAV">
<Descriptor Name="InputVector1" Kind="UAV" ResName="InputVector1" NumElements="0" Format="R32_Typeless" Flags="RAW"/>
<Descriptor Name="InputVector1" Kind="UAV" ResName="InputVector1" NumElements="0"/>
<Descriptor Name="OutputVector" Kind="UAV" ResName="OutputVector"
NumElements="0" Format="R32_Typeless" Flags="RAW"/>
NumElements="0"/>
</DescriptorHeap>

<Shader Name="CS" Target="cs_6_9" EntryPoint="main">
Expand Down Expand Up @@ -3859,18 +3851,17 @@ void MSMain(uint GID : SV_GroupIndex,
<Resource Name="InputVector1" Dimension="BUFFER" Width="0" Init="ByName"/>
<Resource Name="OutputVector" Dimension="BUFFER" Width="0" Init="ByName"
ReadBack="true" Flags="ALLOW_UNORDERED_ACCESS"
TransitionTo="UNORDERED_ACCESS">
</Resource>
TransitionTo="UNORDERED_ACCESS"/>

<!-- Note: NumElements is set dynamically (via c++ test code) based on the
input vector size and element type -->
<RootValues>
<RootValue HeapName="DescriptorTable" Index="0" />
</RootValues>
<DescriptorHeap Name="DescriptorTable" Type="CBV_SRV_UAV">
<Descriptor Name="InputVector1" Kind="SRV" ResName="InputVector1" NumElements="0" Format="R32_Typeless" Flags="RAW"/>
<Descriptor Name="InputVector1" Kind="SRV" ResName="InputVector1" NumElements="0"/>
<Descriptor Name="OutputVector" Kind="UAV" ResName="OutputVector"
NumElements="0" Format="R32_Typeless" Flags="RAW"/>
NumElements="0"/>
</DescriptorHeap>

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

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

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

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

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

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

<Shader Name="CS" Target="cs_6_9" EntryPoint="main">
Expand Down