d3d12: Use placed resource for mrt readback

Should be slightly faster (no allocation)
This commit is contained in:
vlj 2015-05-30 23:46:52 +02:00 committed by Vincent Lejeune
parent 28c125618a
commit 2636fb457e
2 changed files with 31 additions and 23 deletions

View File

@ -1267,20 +1267,28 @@ void D3D12GSRender::WriteDepthBuffer()
{ {
} }
static ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12GraphicsCommandList * cmdlist)
ID3D12Resource *writeColorBuffer(ID3D12Device *device, ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist, size_t rowPitch, size_t width, size_t height)
{ {
ID3D12Resource *Result; ID3D12Resource *Result;
size_t rowPitch = RSXThread::m_width * 4;
rowPitch = (rowPitch + 255) & ~255;
D3D12_HEAP_PROPERTIES heapProp = {}; D3D12_HEAP_PROPERTIES heapProp = {};
heapProp.Type = D3D12_HEAP_TYPE_READBACK; heapProp.Type = D3D12_HEAP_TYPE_READBACK;
D3D12_RESOURCE_DESC resdesc = getBufferResourceDesc(rowPitch * height); D3D12_RESOURCE_DESC resdesc = getBufferResourceDesc(rowPitch * RSXThread::m_height);
size_t heapOffset = powerOf2Align(m_readbackResources.m_putPos.load(), 65536);
size_t sizeInByte = rowPitch * RSXThread::m_height;
if (heapOffset + sizeInByte >= 1024 * 1024 * 128) // If it will be stored past heap size
heapOffset = 0;
resdesc = getBufferResourceDesc(sizeInByte);
check( check(
device->CreateCommittedResource( m_device->CreatePlacedResource(
&heapProp, m_readbackResources.m_heap,
D3D12_HEAP_FLAG_NONE, heapOffset,
&resdesc, &resdesc,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, nullptr,
@ -1298,8 +1306,8 @@ ID3D12Resource *writeColorBuffer(ID3D12Device *device, ID3D12Resource *RTT, ID3D
dst.PlacedFootprint.Offset = 0; dst.PlacedFootprint.Offset = 0;
dst.PlacedFootprint.Footprint.Depth = 1; dst.PlacedFootprint.Footprint.Depth = 1;
dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dst.PlacedFootprint.Footprint.Height = (UINT)height; dst.PlacedFootprint.Footprint.Height = (UINT)RSXThread::m_height;
dst.PlacedFootprint.Footprint.Width = (UINT)width; dst.PlacedFootprint.Footprint.Width = (UINT)RSXThread::m_width;
dst.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch; dst.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch;
cmdlist->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); cmdlist->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
cmdlist->ResourceBarrier(1, &getResourceBarrierTransition(RTT, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET)); cmdlist->ResourceBarrier(1, &getResourceBarrierTransition(RTT, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));
@ -1368,8 +1376,6 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
if (heapOffset + sizeInByte >= 1024 * 1024 * 128) // If it will be stored past heap size if (heapOffset + sizeInByte >= 1024 * 1024 * 128) // If it will be stored past heap size
heapOffset = 0; heapOffset = 0;
heapProp = {};
heapProp.Type = D3D12_HEAP_TYPE_READBACK;
resdesc = getBufferResourceDesc(sizeInByte); resdesc = getBufferResourceDesc(sizeInByte);
check( check(
@ -1472,8 +1478,6 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
downloadCommandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); downloadCommandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
} }
size_t colorRowPitch = RSXThread::m_width * 4;
colorRowPitch = (colorRowPitch + 255) & ~255;
ID3D12Resource *rtt0, *rtt1, *rtt2, *rtt3; ID3D12Resource *rtt0, *rtt1, *rtt2, *rtt3;
switch (m_surface_color_target) switch (m_surface_color_target)
{ {
@ -1481,29 +1485,29 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
break; break;
case CELL_GCM_SURFACE_TARGET_0: case CELL_GCM_SURFACE_TARGET_0:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(0), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_1: case CELL_GCM_SURFACE_TARGET_1:
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT1: case CELL_GCM_SURFACE_TARGET_MRT1:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(0), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList);
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT2: case CELL_GCM_SURFACE_TARGET_MRT2:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(0), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList);
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList);
if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(2), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList);
break; break;
case CELL_GCM_SURFACE_TARGET_MRT3: case CELL_GCM_SURFACE_TARGET_MRT3:
if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(0), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList);
if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList);
if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(2), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList);
if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(3), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_fbo->getRenderTargetTexture(3), downloadCommandList);
break; break;
} }
if (needTransfer) if (needTransfer)
@ -1545,6 +1549,9 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
convertCommandList->Release(); convertCommandList->Release();
} }
size_t colorRowPitch = RSXThread::m_width * 4;
colorRowPitch = (colorRowPitch + 255) & ~255;
switch (m_surface_color_target) switch (m_surface_color_target)
{ {
case CELL_GCM_SURFACE_TARGET_NONE: case CELL_GCM_SURFACE_TARGET_NONE:

View File

@ -136,6 +136,7 @@ public:
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override;
private: private:
ID3D12Resource *writeColorBuffer(ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist);
virtual void Close() override; virtual void Close() override;
bool LoadProgram(); bool LoadProgram();