diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index f81f352395..56c1325eac 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -1267,20 +1267,28 @@ void D3D12GSRender::WriteDepthBuffer() { } -static -ID3D12Resource *writeColorBuffer(ID3D12Device *device, ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist, size_t rowPitch, size_t width, size_t height) +ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12GraphicsCommandList * cmdlist) { ID3D12Resource *Result; + size_t rowPitch = RSXThread::m_width * 4; + rowPitch = (rowPitch + 255) & ~255; D3D12_HEAP_PROPERTIES heapProp = {}; 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( - device->CreateCommittedResource( - &heapProp, - D3D12_HEAP_FLAG_NONE, + m_device->CreatePlacedResource( + m_readbackResources.m_heap, + heapOffset, &resdesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, @@ -1298,8 +1306,8 @@ ID3D12Resource *writeColorBuffer(ID3D12Device *device, ID3D12Resource *RTT, ID3D dst.PlacedFootprint.Offset = 0; dst.PlacedFootprint.Footprint.Depth = 1; dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - dst.PlacedFootprint.Footprint.Height = (UINT)height; - dst.PlacedFootprint.Footprint.Width = (UINT)width; + dst.PlacedFootprint.Footprint.Height = (UINT)RSXThread::m_height; + dst.PlacedFootprint.Footprint.Width = (UINT)RSXThread::m_width; dst.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch; cmdlist->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); 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 heapOffset = 0; - heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_READBACK; resdesc = getBufferResourceDesc(sizeInByte); check( @@ -1472,8 +1478,6 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) downloadCommandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); } - size_t colorRowPitch = RSXThread::m_width * 4; - colorRowPitch = (colorRowPitch + 255) & ~255; ID3D12Resource *rtt0, *rtt1, *rtt2, *rtt3; switch (m_surface_color_target) { @@ -1481,29 +1485,29 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) break; 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; 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; 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_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), 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_fbo->getRenderTargetTexture(1), downloadCommandList); break; 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_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); - 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_a) rtt0 = writeColorBuffer(m_fbo->getRenderTargetTexture(0), downloadCommandList); + if (m_context_dma_color_b) rtt1 = writeColorBuffer(m_fbo->getRenderTargetTexture(1), downloadCommandList); + if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList); break; 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_b) rtt1 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(1), downloadCommandList, colorRowPitch, RSXThread::m_width, RSXThread::m_height); - 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) rtt3 = writeColorBuffer(m_device, m_fbo->getRenderTargetTexture(3), 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_fbo->getRenderTargetTexture(1), downloadCommandList); + if (m_context_dma_color_b) rtt2 = writeColorBuffer(m_fbo->getRenderTargetTexture(2), downloadCommandList); + if (m_context_dma_color_b) rtt3 = writeColorBuffer(m_fbo->getRenderTargetTexture(3), downloadCommandList); break; } if (needTransfer) @@ -1545,6 +1549,9 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) convertCommandList->Release(); } + size_t colorRowPitch = RSXThread::m_width * 4; + colorRowPitch = (colorRowPitch + 255) & ~255; + switch (m_surface_color_target) { case CELL_GCM_SURFACE_TARGET_NONE: diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 237042263b..12d3d891dd 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -136,6 +136,7 @@ public: virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; private: + ID3D12Resource *writeColorBuffer(ID3D12Resource *RTT, ID3D12GraphicsCommandList *cmdlist); virtual void Close() override; bool LoadProgram();