Skip to content

Commit 2583aad

Browse files
committed
Written test that crashes on AMD
1 parent cea8c63 commit 2583aad

4 files changed

Lines changed: 230 additions & 1 deletion

File tree

src/Shaders/CompileSpecialCS.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"c:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\dxc.exe" -T cs_6_0 -E mainCS -Fo SpecialCS.dxil SpecialCS.hlsl

src/Shaders/SpecialCS.dxil

3.27 KB
Binary file not shown.

src/Shaders/SpecialCS.hlsl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#define ROOT_SIG "RootFlags(0), CBV(b0), UAV(u0)"
2+
3+
cbuffer Params : register(b0)
4+
{
5+
uint LoadOffset;
6+
};
7+
8+
RWByteAddressBuffer my_buffer : register(u0);
9+
10+
[RootSignature(ROOT_SIG)]
11+
[numthreads(1, 1, 1)]
12+
void mainCS(uint3 dtid: SV_DispatchThreadID)
13+
{
14+
if(dtid.x > 0 || dtid.y > 0 || dtid.z > 0)
15+
return;
16+
uint value = my_buffer.Load(LoadOffset);
17+
my_buffer.Store(0, value);
18+
}

src/Tests.cpp

Lines changed: 211 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4726,14 +4726,224 @@ static void TestGroupDefragmentation(const TestContext& ctx)
47264726
TestDefragmentationIncrementalComplex(ctx);
47274727
}
47284728

4729+
void SpecialTest(const TestContext& ctx)
4730+
{
4731+
wprintf(L"SpecialTest\n");
4732+
4733+
constexpr uint32_t BUFFER_SIZE = 1024 * 1024 * 1024; // 1 GB
4734+
constexpr uint32_t LOAD_OFFSET = BUFFER_SIZE + 4096;
4735+
constexpr bool USE_GOOD_DESCRIPTOR = false;
4736+
4737+
using namespace D3D12MA;
4738+
4739+
wprintf(L"BUFFER_SIZE = 0x%08X\n", BUFFER_SIZE);
4740+
wprintf(L"LOAD_OFFSET = 0x%08X\n", LOAD_OFFSET);
4741+
wprintf(L"USE_GOOD_DESCRIPTOR = %d\n", int(USE_GOOD_DESCRIPTOR));
4742+
4743+
std::vector<char> shader_data;
4744+
ReadFile(shader_data, L"../src/Shaders/SpecialCS.dxil");
4745+
assert(!shader_data.empty());
4746+
4747+
// Create a CBV in UPLOAD heap to hold just 1 uint. Use D3D12MA for that.
4748+
ComPtr<Allocation> cbAlloc;
4749+
ComPtr<ID3D12Resource> cbResource;
4750+
{
4751+
const UINT64 cbRawSize = sizeof(UINT);
4752+
const UINT64 cbSize = AlignUp<UINT64>(cbRawSize, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
4753+
4754+
D3D12_RESOURCE_DESC cbDesc = {};
4755+
FillResourceDescForBuffer(cbDesc, cbSize);
4756+
4757+
CALLOCATION_DESC allocDesc = CALLOCATION_DESC{D3D12_HEAP_TYPE_UPLOAD};
4758+
4759+
CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &cbDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
4760+
nullptr, &cbAlloc, IID_PPV_ARGS(&cbResource)));
4761+
4762+
// Map and write uint value
4763+
void* mapped = nullptr;
4764+
D3D12_RANGE readRange = { 0, 0 };
4765+
CHECK_HR(cbResource->Map(0, &readRange, &mapped));
4766+
UINT* p = (UINT*)mapped;
4767+
p[0] = LOAD_OFFSET;
4768+
cbResource->Unmap(0, nullptr);
4769+
}
4770+
4771+
// Create a 1 GB buffer to be used as UAV. Use D3D12MA for that.
4772+
ComPtr<Allocation> uavAlloc;
4773+
ComPtr<ID3D12Resource> uavResource;
4774+
{
4775+
D3D12_RESOURCE_DESC resDesc = {};
4776+
FillResourceDescForBuffer(resDesc, BUFFER_SIZE);
4777+
resDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
4778+
4779+
CALLOCATION_DESC allocDesc = CALLOCATION_DESC{ D3D12_HEAP_TYPE_DEFAULT };
4780+
4781+
CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc,
4782+
D3D12_RESOURCE_STATE_COMMON, nullptr, &uavAlloc, IID_PPV_ARGS(&uavResource)));
4783+
4784+
wprintf(L"Buffer GPU address = 0x%08llX\n", uavResource->GetGPUVirtualAddress());
4785+
wprintf(L"Buffer GPU end address = 0x%08llX\n", uavResource->GetGPUVirtualAddress() + BUFFER_SIZE);
4786+
wprintf(L"Buffer GPU address + load_offset = 0x%08llX\n", uavResource->GetGPUVirtualAddress() + LOAD_OFFSET);
4787+
4788+
}
4789+
4790+
// Create a descriptor heap just for 1 CBV b0 and 1 UAV u0.
4791+
ComPtr<ID3D12DescriptorHeap> descHeap;
4792+
{
4793+
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
4794+
heapDesc.NumDescriptors = 2;
4795+
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
4796+
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
4797+
heapDesc.NodeMask = 0;
4798+
CHECK_HR(ctx.device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descHeap)));
4799+
}
4800+
4801+
4802+
const UINT descriptorSize = ctx.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
4803+
D3D12_CPU_DESCRIPTOR_HANDLE cpuStart = descHeap->GetCPUDescriptorHandleForHeapStart();
4804+
D3D12_GPU_DESCRIPTOR_HANDLE gpuStart = descHeap->GetGPUDescriptorHandleForHeapStart();
4805+
4806+
// Create CBV at descriptor 0
4807+
{
4808+
D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
4809+
cbvDesc.BufferLocation = cbResource->GetGPUVirtualAddress();
4810+
// SizeInBytes must be multiple of 256
4811+
cbvDesc.SizeInBytes = (UINT)AlignUp<UINT64>(sizeof(UINT), D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
4812+
ctx.device->CreateConstantBufferView(&cbvDesc, cpuStart);
4813+
}
4814+
4815+
// Create UAV at descriptor 1
4816+
{
4817+
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
4818+
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
4819+
uavDesc.Buffer.FirstElement = 0;
4820+
uavDesc.Buffer.NumElements = (UINT)( (uavResource->GetDesc().Width) / sizeof(UINT) );
4821+
uavDesc.Buffer.StructureByteStride = 0; // Zero for both raw and typed buffer.
4822+
uavDesc.Buffer.CounterOffsetInBytes = 0;
4823+
4824+
if(USE_GOOD_DESCRIPTOR)
4825+
{
4826+
// Declare proper ByteAdddress (raw) buffer.
4827+
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
4828+
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
4829+
}
4830+
else
4831+
{
4832+
// Declare typed buffer.
4833+
uavDesc.Format = DXGI_FORMAT_R32_UINT;
4834+
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
4835+
}
4836+
4837+
D3D12_CPU_DESCRIPTOR_HANDLE cpuUavHandle = cpuStart;
4838+
cpuUavHandle.ptr += descriptorSize * 1;
4839+
// Create UAV (no counter resource)
4840+
ctx.device->CreateUnorderedAccessView(uavResource.Get(), nullptr, &uavDesc, cpuUavHandle);
4841+
}
4842+
4843+
// Create a compute root signature with:
4844+
// - descriptor table (CBV at b0)
4845+
// - descriptor table (UAV at u0)
4846+
ComPtr<ID3D12RootSignature> rootSignature;
4847+
{
4848+
D3D12_DESCRIPTOR_RANGE cbvRange = {};
4849+
cbvRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
4850+
cbvRange.NumDescriptors = 1;
4851+
cbvRange.BaseShaderRegister = 0;
4852+
cbvRange.RegisterSpace = 0;
4853+
cbvRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
4854+
4855+
D3D12_DESCRIPTOR_RANGE uavRange = {};
4856+
uavRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
4857+
uavRange.NumDescriptors = 1;
4858+
uavRange.BaseShaderRegister = 0;
4859+
uavRange.RegisterSpace = 0;
4860+
uavRange.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
4861+
4862+
D3D12_ROOT_PARAMETER params[2] = {};
4863+
params[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
4864+
params[0].DescriptorTable.NumDescriptorRanges = 1;
4865+
params[0].DescriptorTable.pDescriptorRanges = &cbvRange;
4866+
params[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
4867+
4868+
params[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
4869+
params[1].DescriptorTable.NumDescriptorRanges = 1;
4870+
params[1].DescriptorTable.pDescriptorRanges = &uavRange;
4871+
params[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
4872+
4873+
D3D12_ROOT_SIGNATURE_DESC rsDesc = {};
4874+
rsDesc.NumParameters = _countof(params);
4875+
rsDesc.pParameters = params;
4876+
rsDesc.NumStaticSamplers = 0;
4877+
rsDesc.pStaticSamplers = nullptr;
4878+
rsDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
4879+
4880+
ComPtr<ID3DBlob> sigBlob, errorBlob;
4881+
CHECK_HR(D3D12SerializeRootSignature(&rsDesc, D3D_ROOT_SIGNATURE_VERSION_1, &sigBlob, &errorBlob));
4882+
CHECK_HR(ctx.device->CreateRootSignature(0, sigBlob->GetBufferPointer(), sigBlob->GetBufferSize(), IID_PPV_ARGS(&rootSignature)));
4883+
}
4884+
4885+
// Create a compute pipeline state object using shader_data.
4886+
ComPtr<ID3D12PipelineState> pso;
4887+
{
4888+
D3D12_COMPUTE_PIPELINE_STATE_DESC desc = {};
4889+
desc.pRootSignature = rootSignature.Get();
4890+
desc.CS.pShaderBytecode = shader_data.data();
4891+
desc.CS.BytecodeLength = shader_data.size();
4892+
desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
4893+
CHECK_HR(ctx.device->CreateComputePipelineState(&desc, IID_PPV_ARGS(&pso)));
4894+
}
4895+
4896+
fflush(stdout);
4897+
Sleep(500);
4898+
4899+
// Record commands: set descriptor heap, root signature, descriptor tables, dispatch.
4900+
ID3D12GraphicsCommandList* cmd_list = BeginCommandList();
4901+
4902+
// Transition UAV to UAV state
4903+
{
4904+
D3D12_RESOURCE_BARRIER barrier = {};
4905+
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
4906+
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
4907+
barrier.Transition.pResource = uavResource.Get();
4908+
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
4909+
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON;
4910+
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
4911+
cmd_list->ResourceBarrier(1, &barrier);
4912+
}
4913+
4914+
ID3D12DescriptorHeap* heaps[] = { descHeap.Get() };
4915+
cmd_list->SetDescriptorHeaps(1, heaps);
4916+
4917+
cmd_list->SetComputeRootSignature(rootSignature.Get());
4918+
4919+
// GPU handles: CBV at offset 0, UAV at offset 1
4920+
D3D12_GPU_DESCRIPTOR_HANDLE gpuCbv = gpuStart;
4921+
D3D12_GPU_DESCRIPTOR_HANDLE gpuUav = gpuStart;
4922+
gpuUav.ptr += descriptorSize * 1;
4923+
4924+
// Root parameter 0 -> CBV table, 1 -> UAV table
4925+
cmd_list->SetComputeRootDescriptorTable(0, gpuCbv);
4926+
cmd_list->SetComputeRootDescriptorTable(1, gpuUav);
4927+
4928+
cmd_list->SetPipelineState(pso.Get());
4929+
4930+
// Dispatch a single group
4931+
cmd_list->Dispatch(1, 1, 1);
4932+
4933+
EndCommandList(cmd_list);
4934+
4935+
wprintf(L"SpecialTest done.\n");
4936+
}
4937+
47294938
void Test(const TestContext& ctx)
47304939
{
47314940
wprintf(L"TESTS BEGIN\n");
47324941

4733-
if(false)
4942+
if(true)
47344943
{
47354944
////////////////////////////////////////////////////////////////////////////////
47364945
// Temporarily insert custom tests here:
4946+
SpecialTest(ctx);
47374947
return;
47384948
}
47394949

0 commit comments

Comments
 (0)