From 449c41aca2b840439c58b70f4e44e556a381be3b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 30 Oct 2015 18:12:05 +0100 Subject: [PATCH] d3d12: Support size changing depth buffer --- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 55 ++++++++++++------- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h | 6 +- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index f65013fc32..4e9345c9ef 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -160,7 +160,10 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis } } - ID3D12Resource *ds = m_rtts.bindAddressAsDepthStencil(m_device.Get(), copycmdlist, address_z, clip_width, clip_height, m_surface.depth_format, 1., 0); + ComPtr oldDS; + ID3D12Resource *ds = m_rtts.bindAddressAsDepthStencil(m_device.Get(), copycmdlist, address_z, clip_width, clip_height, m_surface.depth_format, 1., 0, oldDS); + if (oldDS) + getCurrentResourceStorage().dirty_textures.push_back(oldDS); D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {}; depthStencilViewDesc.Format = get_depth_stencil_surface_format(m_surface.depth_format); @@ -205,41 +208,51 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, return rtt; } -ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device, ID3D12GraphicsCommandList * cmdList, u32 address, size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear) +ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device, ID3D12GraphicsCommandList * cmdList, u32 address, size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear, ComPtr &dirtyDS) { - ID3D12Resource* ds; + auto It = m_depthStencil.find(address); - // TODO: Check if sizes and surface depth format match + m_currentlyBoundDepthStencilAddress = address; + + // TODO: Check if surface depth format match if (It != m_depthStencil.end()) { - ds = It->second; - cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE)); + ComPtr ds = It->second; + if (ds->GetDesc().Width == width && ds->GetDesc().Height == height) + { + // set the resource as depth write + cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds.Get(), D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE)); + m_currentlyBoundDepthStencil = ds.Get(); + return ds.Get(); + } + // If size doesn't match, remove ds from cache + m_depthStencil.erase(address); + dirtyDS = ds; } - else - { - D3D12_CLEAR_VALUE clearDepthValue = {}; - clearDepthValue.DepthStencil.Depth = depthClear; - D3D12_HEAP_PROPERTIES heapProp = {}; - heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; + D3D12_CLEAR_VALUE clearDepthValue = {}; + clearDepthValue.DepthStencil.Depth = depthClear; - DXGI_FORMAT dxgiFormat = get_depth_typeless_surface_format(surfaceDepthFormat); - clearDepthValue.Format = get_depth_stencil_surface_clear_format(surfaceDepthFormat); + D3D12_HEAP_PROPERTIES heapProp = {}; + heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - device->CreateCommittedResource( + DXGI_FORMAT dxgiFormat = get_depth_typeless_surface_format(surfaceDepthFormat); + clearDepthValue.Format = get_depth_stencil_surface_clear_format(surfaceDepthFormat); + + ComPtr newds; + device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(dxgiFormat, (UINT)width, (UINT)height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL), D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearDepthValue, - IID_PPV_ARGS(&ds) + IID_PPV_ARGS(newds.GetAddressOf()) ); - m_depthStencil[address] = ds; - } - m_currentlyBoundDepthStencil = ds; - m_currentlyBoundDepthStencilAddress = address; - return ds; + m_depthStencil[address] = newds; + m_currentlyBoundDepthStencil = newds.Get(); + + return newds.Get(); } void RenderTargets::Init(ID3D12Device *device)//, u8 surfaceDepthFormat, size_t width, size_t height, float clearColor[4], float clearDepth) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h index 0cf1a58d45..0392ed8d69 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h @@ -4,10 +4,10 @@ struct RenderTargets { - std::unordered_map m_renderTargets; + std::unordered_map m_renderTargets; ID3D12Resource *m_currentlyBoundRenderTargets[4]; u32 m_currentlyBoundRenderTargetsAddress[4]; - std::unordered_map m_depthStencil; + std::unordered_map > m_depthStencil; ID3D12Resource *m_currentlyBoundDepthStencil; u32 m_currentlyBoundDepthStencilAddress; ID3D12DescriptorHeap *m_renderTargetsDescriptorsHeap; @@ -22,7 +22,7 @@ struct RenderTargets size_t width, size_t height, u8 surfaceColorFormat, const std::array &clearColor); ID3D12Resource *bindAddressAsDepthStencil(ID3D12Device *device, ID3D12GraphicsCommandList *cmdList, u32 address, - size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear); + size_t width, size_t height, u8 surfaceDepthFormat, float depthClear, u8 stencilClear, ComPtr &dirtyDS); void Init(ID3D12Device *device); void Release();