I want to copy a small two-dimensional output from a compute shader into a one-dimensional readback buffer. However, when I run it, the program crashes.
D3D12_COMMAND_QUEUE_DESC cqDesc = {};
cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
cqDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue));
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(&commandAllocator));
device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COMPUTE, commandAllocator, NULL, IID_PPV_ARGS(&commandList));
D3D12_COMMAND_QUEUE_DESC c2qDesc = {};
c2qDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
c2qDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY;
device->CreateCommandQueue(&c2qDesc, IID_PPV_ARGS(©CmdQueue));
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(©CmdAllocator));
device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyCmdAllocator, NULL, IID_PPV_ARGS(©CmdList));
I'm using graphics, compute, copy queues and 2 fences. compute, copy queues are sharing 1 fence and graphics is separated.
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex3D(DXGI_FORMAT_R32_FLOAT, w, h, d);
D3D12_UAV_DIMENSION UavDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
if (d == 0) {
desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT, w, h);
UavDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
if (h == 0) {
desc = CD3DX12_RESOURCE_DESC::Tex1D(DXGI_FORMAT_R32_FLOAT, w);
UavDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
}
}
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&desc,
D3D12_RESOURCE_STATE_COMMON,
nullptr,
IID_PPV_ARGS(&buf));
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(buf, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_UNORDERED_ACCESS));
This is part of initialize function for every compute buffer. Copy source is 4X2size DXGI_FORMAT_R32_FLOAT format 2D buffer.
D3D12_RESOURCE_DESC AboutSrc = SrcBuf->GetDesc();
size_t w = AboutSrc.Width;
size_t h = AboutSrc.Height;
size_t d = AboutSrc.DepthOrArraySize;
device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(w * h * d * sizeof(float)),
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&UplBuf));
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(SrcBuf, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
WaitForPreviousCompute();
//copyCmdList->CopyResource(UplBuf, SrcBuf);
//copyCmdList->CopyBufferRegion(UplBuf, 0, SrcBuf, 0, 16);
D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint = {};
PlacedFootprint.Offset = 0;
PlacedFootprint.Footprint.Format = DXGI_FORMAT_UNKNOWN;
PlacedFootprint.Footprint.Width = w * h * d * sizeof(float);
PlacedFootprint.Footprint.Height = 1;
PlacedFootprint.Footprint.Depth = 1;
PlacedFootprint.Footprint.RowPitch = 256;
D3D12_TEXTURE_COPY_LOCATION dst = { UplBuf, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, PlacedFootprint };
D3D12_TEXTURE_COPY_LOCATION src = { SrcBuf, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, 0 };
copyCmdList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
WaitForPreviousCopy();
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(SrcBuf, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS));
WaitForPreviousCompute();
WaitForPreviousCompute and WaitForPreviousCopy include executing command List.
I haven't been able to pinpoint the exact point of the problem yet, so where is the problem?