Hello,
I'm working on a system based on Structured Buffers, the idea is that they can be used in the GPU as UAV/SRV and then the data can be read back in the CPU. This system is used to do some queries in my application.
First I have two main resources:
+ Default Resource: This will be the resource used by the GPU.
+ Upload Resource: In case I want to upload data from the CPU I'll use this as an intermediate
+ Double Buffered ReadBack Resources: I have two Read Back buffers to copy data from the GPU to the CPU.
Let me show some code:
const void* OpenReadBuffer()
{
HRESULT res = S_FALSE;
if (mFirstUse)
mFirstUse = false;
else
mCbFence.WaitUntilCompleted(renderPlatform);
// Map from the last frame
const CD3DX12_RANGE readRange(0, 0);
res = mBufferReadFront->Map(0, &readRange, reinterpret_cast<void**>(&mReadSrc));
return mReadSrc;
}
void CloseReadBuffer()
{
const CD3DX12_RANGE readRange(0, 0);
mBufferReadFront->Unmap(0, &readRange);
}
void CopyToReadBuffer()
{
// Schedule a copy for the next frame
commandList->CopyResource(mBufferReadBack, mBufferDefault);
mCbFence.Signal(renderPlatform);
// Swap it!
std::swap(mBufferReadBack, mBufferReadFront);
}
This is how I create the different resources:
// Default
D3D12_RESOURCE_FLAGS bufferFlags = computable ? D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS : D3D12_RESOURCE_FLAG_NONE;
res = device->CreateCommittedResource
(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(mTotalSize,bufferFlags),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&mBufferDefault)
);
// Upload
res = device->CreateCommittedResource
(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(mTotalSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&mBufferUpload)
);
// Read Back
res = device->CreateCommittedResource
(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(mTotalSize),
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&mBufferReadBack)
);
I'm using a Fence to be 100% sure that it is synchronised, I could have more that 2 buffers but at the moment I would like to keep it simple.
The values that I get from OpenReadBuffer() are all 0.
If I debug it, it looks like the Read Back Buffers have some valid data.
What could be the issue?
Thanks!
↧