From d503363279764f9aed7ae2bacff1fa6888c5e597 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 21 Oct 2020 18:00:32 +0100 Subject: [PATCH] Fix issues with MSAA quad overdraw overlays --- renderdoc/driver/d3d11/d3d11_overlay.cpp | 23 +- renderdoc/driver/d3d12/d3d12_debug.cpp | 36 ++- renderdoc/driver/d3d12/d3d12_debug.h | 9 +- renderdoc/driver/d3d12/d3d12_initstate.cpp | 2 +- .../driver/d3d12/d3d12_msaa_array_conv.cpp | 214 ++++++++++-------- renderdoc/driver/d3d12/d3d12_overlay.cpp | 83 ++++++- renderdoc/driver/d3d12/d3d12_replay.cpp | 2 +- renderdoc/driver/d3d12/d3d12_replay.h | 2 +- renderdoc/driver/gl/gl_overlay.cpp | 115 ++++++---- 9 files changed, 334 insertions(+), 152 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_overlay.cpp b/renderdoc/driver/d3d11/d3d11_overlay.cpp index 4fea4a79b..a22a72c4a 100644 --- a/renderdoc/driver/d3d11/d3d11_overlay.cpp +++ b/renderdoc/driver/d3d11/d3d11_overlay.cpp @@ -938,7 +938,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De uint32_t height = 1080 >> 1; D3D11_TEXTURE2D_DESC overrideDepthDesc = {}; - ID3D11Texture2D *depthTex = NULL; + ID3D11Texture2D *origDepthTex = NULL; { ID3D11Resource *res = NULL; @@ -981,7 +981,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De overrideDepthDesc.ArraySize = texdesc.SampleDesc.Count; overrideDepthDesc.SampleDesc.Count = 1; overrideDepthDesc.SampleDesc.Quality = 0; - depthTex = ((ID3D11Texture2D *)res); + origDepthTex = ((ID3D11Texture2D *)res); D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; state->OM.DepthView->GetDesc(&dsvDesc); @@ -1007,22 +1007,24 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De } ID3D11DepthStencilView *depthOverride = NULL; + ID3D11Texture2D *depthOverrideTex = NULL; if(overrideDepthDesc.Width > 0) { - ID3D11Texture2D *tex = NULL; - m_pDevice->CreateTexture2D(&overrideDepthDesc, NULL, &tex); + m_pDevice->CreateTexture2D(&overrideDepthDesc, NULL, &depthOverrideTex); D3D11_DEPTH_STENCIL_VIEW_DESC viewDesc = {}; viewDesc.Format = overrideDepthDesc.Format; viewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; viewDesc.Texture2DArray.ArraySize = 1; - m_pDevice->GetDebugManager()->CopyTex2DMSToArray(UNWRAP(WrappedID3D11Texture2D1, tex), - UNWRAP(WrappedID3D11Texture2D1, depthTex)); + if(overlay != DebugOverlay::QuadOverdrawPass) + m_pDevice->GetDebugManager()->CopyTex2DMSToArray( + UNWRAP(WrappedID3D11Texture2D1, depthOverrideTex), + UNWRAP(WrappedID3D11Texture2D1, origDepthTex)); - m_pDevice->CreateDepthStencilView(tex, &viewDesc, &depthOverride); - SAFE_RELEASE(tex); + m_pDevice->CreateDepthStencilView(depthOverrideTex, &viewDesc, &depthOverride); + depthOverrideTex->Release(); } D3D11_TEXTURE2D_DESC uavTexDesc = { @@ -1119,6 +1121,11 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De m_pImmediateContext->PSSetShader(m_Overlay.QuadOverdrawPS, NULL, 0); + if(overlay == DebugOverlay::QuadOverdrawPass && depthOverrideTex) + m_pDevice->GetDebugManager()->CopyTex2DMSToArray( + UNWRAP(WrappedID3D11Texture2D1, depthOverrideTex), + UNWRAP(WrappedID3D11Texture2D1, origDepthTex)); + m_pDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); oldstate.ApplyState(m_pImmediateContext); diff --git a/renderdoc/driver/d3d12/d3d12_debug.cpp b/renderdoc/driver/d3d12/d3d12_debug.cpp index 60c35042b..7fb959b2a 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.cpp +++ b/renderdoc/driver/d3d12/d3d12_debug.cpp @@ -352,6 +352,11 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper) rm->SetInternalResource(m_DebugAlloc); + m_pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void **)&m_DebugFence); + m_pDevice->InternalRef(); + + rm->SetInternalResource(m_DebugFence); + ID3D12GraphicsCommandList *list = NULL; hr = m_pDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_DebugAlloc, NULL, @@ -402,6 +407,12 @@ D3D12DebugManager::~D3D12DebugManager() for(size_t p = 0; p < MeshDisplayPipelines::ePipe_Count; p++) SAFE_RELEASE(it->second.pipes[p]); + for(auto it = m_MS2ArrayPSOCache.begin(); it != m_MS2ArrayPSOCache.end(); ++it) + { + SAFE_RELEASE(it->second.first); + SAFE_RELEASE(it->second.second); + } + SAFE_RELEASE(dsvHeap); SAFE_RELEASE(rtvHeap); SAFE_RELEASE(cbvsrvuavHeap); @@ -440,6 +451,7 @@ D3D12DebugManager::~D3D12DebugManager() SAFE_RELEASE(m_DebugAlloc); SAFE_RELEASE(m_DebugList); + SAFE_RELEASE(m_DebugFence); for(auto it = m_DiscardPipes.begin(); it != m_DiscardPipes.end(); it++) if(it->second) @@ -1769,12 +1781,23 @@ void D3D12Replay::OverlayRendering::Init(WrappedID3D12Device *device, D3D12Debug pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - hr = device->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState), - (void **)&QuadResolvePipe); - - if(FAILED(hr)) + for(size_t i = 0; i < ARRAY_COUNT(QuadResolvePipe); i++) { - RDCERR("Couldn't create m_QuadResolvePipe! HRESULT: %s", ToStr(hr).c_str()); + pipeDesc.SampleDesc.Count = UINT(1 << i); + + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS check = {}; + check.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; + check.SampleCount = pipeDesc.SampleDesc.Count; + device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &check, sizeof(check)); + + if(check.NumQualityLevels == 0) + continue; + + hr = device->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState), + (void **)&QuadResolvePipe[i]); + + if(FAILED(hr)) + RDCERR("Couldn't create QuadResolvePipe[%zu]! HRESULT: %s", i, ToStr(hr).c_str()); } SAFE_RELEASE(FullscreenVS); @@ -1792,7 +1815,8 @@ void D3D12Replay::OverlayRendering::Release() SAFE_RELEASE(QuadOverdrawWritePS); SAFE_RELEASE(QuadOverdrawWriteDXILPS); SAFE_RELEASE(QuadResolveRootSig); - SAFE_RELEASE(QuadResolvePipe); + for(size_t i = 0; i < ARRAY_COUNT(QuadResolvePipe); i++) + SAFE_RELEASE(QuadResolvePipe[i]); SAFE_RELEASE(Texture); } diff --git a/renderdoc/driver/d3d12/d3d12_debug.h b/renderdoc/driver/d3d12/d3d12_debug.h index 1f4738f10..91f9fd057 100644 --- a/renderdoc/driver/d3d12/d3d12_debug.h +++ b/renderdoc/driver/d3d12/d3d12_debug.h @@ -167,12 +167,18 @@ public: MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary); - void CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Resource *srcMS); + void CopyTex2DMSToArray(ID3D12GraphicsCommandList *list, ID3D12Resource *destArray, + ID3D12Resource *srcMS); void CopyArrayToTex2DMS(ID3D12Resource *destMS, ID3D12Resource *srcArray, UINT selectedSlice); private: bool CreateMathIntrinsicsResources(); + rdcpair D3D12DebugManager::GetMSToArrayPSOs( + DXGI_FORMAT format); + + std::map> m_MS2ArrayPSOCache; + WrappedID3D12Device *m_pDevice = NULL; // heaps @@ -221,6 +227,7 @@ private: // Debug lists ID3D12GraphicsCommandListX *m_DebugList = NULL; ID3D12CommandAllocator *m_DebugAlloc = NULL; + ID3D12Fence *m_DebugFence = NULL; // Discard pattern rendering ID3DBlob *m_DiscardPS = NULL; diff --git a/renderdoc/driver/d3d12/d3d12_initstate.cpp b/renderdoc/driver/d3d12/d3d12_initstate.cpp index 633190e24..3d790c25c 100644 --- a/renderdoc/driver/d3d12/d3d12_initstate.cpp +++ b/renderdoc/driver/d3d12/d3d12_initstate.cpp @@ -254,7 +254,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) m_Device->FlushLists(); // expand multisamples out to array - m_Device->GetDebugManager()->CopyTex2DMSToArray(arrayTexture, r->GetReal()); + m_Device->GetDebugManager()->CopyTex2DMSToArray(NULL, arrayTexture, r->GetReal()); // open the initial state list again for the remainder of the work list = Unwrap(m_Device->GetInitialStateList()); diff --git a/renderdoc/driver/d3d12/d3d12_msaa_array_conv.cpp b/renderdoc/driver/d3d12/d3d12_msaa_array_conv.cpp index 81397474b..76fae0603 100644 --- a/renderdoc/driver/d3d12/d3d12_msaa_array_conv.cpp +++ b/renderdoc/driver/d3d12/d3d12_msaa_array_conv.cpp @@ -30,11 +30,109 @@ #include "driver/dx/official/d3dcompiler.h" -void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Resource *srcMS) +rdcpair D3D12DebugManager::GetMSToArrayPSOs( + DXGI_FORMAT format) +{ + rdcpair &cache = m_MS2ArrayPSOCache[format]; + + if(cache.first == NULL) + { + const bool stencil = IsDepthAndStencilFormat(format); + + D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {}; + + pipeDesc.pRootSignature = Unwrap(m_ArrayMSAARootSig); + pipeDesc.VS.BytecodeLength = m_FullscreenVS->GetBufferSize(); + pipeDesc.VS.pShaderBytecode = m_FullscreenVS->GetBufferPointer(); + + pipeDesc.PS.BytecodeLength = m_FloatMS2Array->GetBufferSize(); + pipeDesc.PS.pShaderBytecode = m_FloatMS2Array->GetBufferPointer(); + + if(IsDepthFormat(format)) + { + pipeDesc.PS.BytecodeLength = m_DepthMS2Array->GetBufferSize(); + pipeDesc.PS.pShaderBytecode = m_DepthMS2Array->GetBufferPointer(); + pipeDesc.NumRenderTargets = 0; + pipeDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN; + pipeDesc.DSVFormat = format; + pipeDesc.DepthStencilState.DepthEnable = TRUE; + pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + pipeDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS; + } + else if(IsUIntFormat(format) || IsIntFormat(format)) + { + pipeDesc.NumRenderTargets = 1; + pipeDesc.RTVFormats[0] = format; + pipeDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; + pipeDesc.PS.BytecodeLength = m_IntMS2Array->GetBufferSize(); + pipeDesc.PS.pShaderBytecode = m_IntMS2Array->GetBufferPointer(); + } + + pipeDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + pipeDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + pipeDesc.SampleMask = 0xFFFFFFFF; + pipeDesc.SampleDesc.Count = 1; + pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; + pipeDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + pipeDesc.BlendState.RenderTarget[0].BlendEnable = FALSE; + pipeDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; + pipeDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + pipeDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; + pipeDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA; + pipeDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; + pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; + pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + HRESULT hr = m_pDevice->GetReal()->CreateGraphicsPipelineState( + &pipeDesc, __uuidof(ID3D12PipelineState), (void **)&cache.first); + + if(FAILED(hr)) + { + RDCERR("Couldn't create MSAA conversion pipeline for %s! HRESULT: %s", ToStr(format).c_str(), + ToStr(hr).c_str()); + SAFE_RELEASE(cache.first); + SAFE_RELEASE(cache.second); + return cache; + } + + if(stencil) + { + pipeDesc.DepthStencilState.DepthEnable = FALSE; + pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; + pipeDesc.DepthStencilState.StencilEnable = TRUE; + pipeDesc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + pipeDesc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE; + pipeDesc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_REPLACE; + pipeDesc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_REPLACE; + pipeDesc.DepthStencilState.BackFace = pipeDesc.DepthStencilState.FrontFace; + pipeDesc.DepthStencilState.StencilReadMask = 0xff; + pipeDesc.DepthStencilState.StencilWriteMask = 0xff; + + hr = m_pDevice->GetReal()->CreateGraphicsPipelineState( + &pipeDesc, __uuidof(ID3D12PipelineState), (void **)&cache.second); + if(FAILED(hr)) + { + RDCERR("Couldn't create MSAA stencil conversion pipeline for %s! HRESULT: %s", + ToStr(format).c_str(), ToStr(hr).c_str()); + SAFE_RELEASE(cache.first); + SAFE_RELEASE(cache.second); + return cache; + } + } + } + + return cache; +} + +void D3D12DebugManager::CopyTex2DMSToArray(ID3D12GraphicsCommandList *list, + ID3D12Resource *destArray, ID3D12Resource *srcMS) { // this function operates during capture so we work on unwrapped objects + const bool externalList = list != NULL; - D3D12MarkerRegion renderoverlay(m_pDevice->GetQueue(), "CopyTex2DMSToArray"); + D3D12MarkerRegion renderoverlay = + externalList ? D3D12MarkerRegion(list, "CopyTex2DMSToArray") + : D3D12MarkerRegion(m_pDevice->GetQueue(), "CopyTex2DMSToArray"); D3D12_RESOURCE_DESC descMS = srcMS->GetDesc(); D3D12_RESOURCE_DESC descArr = destArray->GetDesc(); @@ -62,12 +160,12 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso dsvDesc.Texture2DArray.FirstArraySlice = 0; dsvDesc.Texture2DArray.MipSlice = 0; - bool isDepth = IsDepthFormat(rtvDesc.Format) || - (descMS.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0 || - (descArr.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0; - bool intFormat = IsUIntFormat(rtvDesc.Format) || IsIntFormat(rtvDesc.Format); + const bool isDepth = IsDepthFormat(rtvDesc.Format) || + (descMS.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0 || + (descArr.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0; + const bool intFormat = IsUIntFormat(rtvDesc.Format) || IsIntFormat(rtvDesc.Format); - bool stencil = false; + const bool stencil = IsDepthAndStencilFormat(rtvDesc.Format); DXGI_FORMAT stencilFormat = DXGI_FORMAT_UNKNOWN; if(isDepth) @@ -88,7 +186,6 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso dsvDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; stencilFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - stencil = true; break; case DXGI_FORMAT_D24_UNORM_S8_UINT: @@ -98,7 +195,6 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso dsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; stencilFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - stencil = true; break; case DXGI_FORMAT_D16_UNORM: @@ -109,6 +205,12 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso default: break; } + + rtvDesc.Format = dsvDesc.Format; + } + else + { + dsvDesc.Format = DXGI_FORMAT_UNKNOWN; } for(CBVUAVSRVSlot slot : {MSAA_SRV2x, MSAA_SRV4x, MSAA_SRV8x, MSAA_SRV16x, MSAA_SRV32x}) @@ -132,64 +234,16 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso D3D12_CPU_DESCRIPTOR_HANDLE rtv = Unwrap(GetCPUHandle(MSAA_RTV)); D3D12_CPU_DESCRIPTOR_HANDLE dsv = Unwrap(GetCPUHandle(MSAA_DSV)); - D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc = {}; - - pipeDesc.pRootSignature = Unwrap(m_ArrayMSAARootSig); - pipeDesc.VS.BytecodeLength = m_FullscreenVS->GetBufferSize(); - pipeDesc.VS.pShaderBytecode = m_FullscreenVS->GetBufferPointer(); - - pipeDesc.PS.BytecodeLength = m_FloatMS2Array->GetBufferSize(); - pipeDesc.PS.pShaderBytecode = m_FloatMS2Array->GetBufferPointer(); - pipeDesc.NumRenderTargets = 1; - pipeDesc.RTVFormats[0] = rtvDesc.Format; - pipeDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; - - if(isDepth) - { - pipeDesc.PS.BytecodeLength = m_DepthMS2Array->GetBufferSize(); - pipeDesc.PS.pShaderBytecode = m_DepthMS2Array->GetBufferPointer(); - pipeDesc.NumRenderTargets = 0; - pipeDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN; - pipeDesc.DSVFormat = dsvDesc.Format; - pipeDesc.DepthStencilState.DepthEnable = TRUE; - pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; - pipeDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS; - } - else if(intFormat) - { - pipeDesc.PS.BytecodeLength = m_IntMS2Array->GetBufferSize(); - pipeDesc.PS.pShaderBytecode = m_IntMS2Array->GetBufferPointer(); - } - - pipeDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; - pipeDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; - pipeDesc.SampleMask = 0xFFFFFFFF; - pipeDesc.SampleDesc.Count = 1; - pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; - pipeDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - pipeDesc.BlendState.RenderTarget[0].BlendEnable = FALSE; - pipeDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; - pipeDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; - pipeDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - pipeDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA; - pipeDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; - pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - ID3D12PipelineState *pso = NULL, *psoStencil = NULL; - HRESULT hr = m_pDevice->GetReal()->CreateGraphicsPipelineState( - &pipeDesc, __uuidof(ID3D12PipelineState), (void **)&pso); + rdctie(pso, psoStencil) = GetMSToArrayPSOs(rtvDesc.Format); - if(FAILED(hr)) + if(!externalList) { - RDCERR("Couldn't create MSAA conversion pipeline! HRESULT: %s", ToStr(hr).c_str()); - return; + list = Unwrap(m_DebugList); + + list->Reset(Unwrap(m_DebugAlloc), NULL); } - ID3D12GraphicsCommandList *list = Unwrap(m_DebugList); - - list->Reset(Unwrap(m_DebugAlloc), NULL); - D3D12_VIEWPORT viewport = {0, 0, (float)descArr.Width, (float)descArr.Height, 0.0f, 1.0f}; D3D12_RECT scissor = {0, 0, (LONG)descArr.Width, (LONG)descArr.Height}; list->RSSetViewports(1, &viewport); @@ -233,21 +287,6 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso if(stencil) { - pipeDesc.DepthStencilState.DepthEnable = FALSE; - pipeDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; - pipeDesc.DepthStencilState.StencilEnable = TRUE; - pipeDesc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; - pipeDesc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE; - pipeDesc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_REPLACE; - pipeDesc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_REPLACE; - pipeDesc.DepthStencilState.BackFace = pipeDesc.DepthStencilState.FrontFace; - pipeDesc.DepthStencilState.StencilReadMask = 0xff; - pipeDesc.DepthStencilState.StencilWriteMask = 0xff; - - hr = m_pDevice->GetReal()->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState), - (void **)&psoStencil); - RDCASSERTEQUAL(hr, S_OK); - list->SetPipelineState(psoStencil); dsvDesc.Flags = D3D12_DSV_FLAG_READ_ONLY_DEPTH; @@ -279,20 +318,15 @@ void D3D12DebugManager::CopyTex2DMSToArray(ID3D12Resource *destArray, ID3D12Reso } } - list->Close(); + if(!externalList) + { + list->Close(); - ID3D12Fence *tmpFence = NULL; - m_pDevice->GetReal()->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), - (void **)&tmpFence); - - ID3D12CommandList *l = list; - m_pDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &l); - m_pDevice->GPUSync(m_pDevice->GetQueue()->GetReal(), tmpFence); - m_DebugAlloc->Reset(); - - SAFE_RELEASE(tmpFence); - SAFE_RELEASE(pso); - SAFE_RELEASE(psoStencil); + ID3D12CommandList *l = list; + m_pDevice->GetQueue()->GetReal()->ExecuteCommandLists(1, &l); + m_pDevice->GPUSync(m_pDevice->GetQueue()->GetReal(), Unwrap(m_DebugFence)); + m_DebugAlloc->Reset(); + } } void D3D12DebugManager::CopyArrayToTex2DMS(ID3D12Resource *destMS, ID3D12Resource *srcArray, diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index 914119f09..d95c4ed80 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -44,11 +44,15 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback { D3D12QuadOverdrawCallback(WrappedID3D12Device *dev, D3D12_SHADER_BYTECODE quadWrite, D3D12_SHADER_BYTECODE quadWriteDXIL, const rdcarray &events, + ID3D12Resource *depth, ID3D12Resource *msdepth, PortableHandle dsv, PortableHandle uav) : m_pDevice(dev), m_QuadWritePS(quadWrite), m_QuadWriteDXILPS(quadWriteDXIL), m_Events(events), + m_Depth(depth), + m_MSDepth(msdepth), + m_DSV(dsv), m_UAV(uav) { m_pDevice->GetQueue()->GetCommandData()->m_DrawcallCallback = this; @@ -136,6 +140,10 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback pipeDesc.DepthStencilState.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; pipeDesc.DepthStencilState.StencilWriteMask = 0; + // disable any multisampling + pipeDesc.SampleDesc.Count = 1; + pipeDesc.SampleDesc.Quality = 0; + bool dxil = DXBC::DXBCContainer::CheckForDXIL(pipeDesc.VS.pShaderBytecode, pipeDesc.VS.BytecodeLength); @@ -166,6 +174,28 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback rs.pipe = GetResID(cache.pipe); rs.graphics.rootsig = GetResID(cache.sig); + rs.rts.clear(); + if(m_Depth) + { + rs.dsv = *DescriptorFromPortableHandle(m_pDevice->GetResourceManager(), m_DSV); + + D3D12_RESOURCE_BARRIER b = {}; + + b.Transition.pResource = m_Depth; + b.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + b.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; + b.Transition.StateAfter = D3D12_RESOURCE_STATE_DEPTH_WRITE; + cmd->ResourceBarrier(1, &b); + + b.Transition.pResource = m_MSDepth; + b.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE; + b.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + cmd->ResourceBarrier(1, &b); + + m_pDevice->GetDebugManager()->CopyTex2DMSToArray(Unwrap(cmd), Unwrap(m_Depth), + Unwrap(m_MSDepth)); + } + AddDebugDescriptorsToRenderState(m_pDevice, rs, {m_UAV}, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cache.sigElem, m_CopiedHeaps); @@ -180,6 +210,22 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback if(!m_Events.contains(eid)) return false; + if(m_Depth) + { + D3D12_RESOURCE_BARRIER b = {}; + + b.Transition.pResource = m_Depth; + b.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + b.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE; + b.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; + cmd->ResourceBarrier(1, &b); + + b.Transition.pResource = m_MSDepth; + b.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + b.Transition.StateAfter = D3D12_RESOURCE_STATE_DEPTH_WRITE; + cmd->ResourceBarrier(1, &b); + } + // restore the render state and go ahead with the real draw m_pDevice->GetQueue()->GetCommandData()->GetCurRenderState() = m_PrevState; @@ -209,6 +255,8 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback D3D12_SHADER_BYTECODE m_QuadWriteDXILPS; const rdcarray &m_Events; PortableHandle m_UAV; + PortableHandle m_DSV; + ID3D12Resource *m_Depth, *m_MSDepth; // cache modified pipelines struct CachedPipeline @@ -1056,7 +1104,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De pipe->Fill(pipeDesc); pipeDesc.pRootSignature = GetDebugManager()->GetMeshRootSig(); pipeDesc.SampleMask = 0xFFFFFFFF; - pipeDesc.SampleDesc.Count = 1; + pipeDesc.SampleDesc = overlayTexDesc.SampleDesc; pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; RDCEraseEl(pipeDesc.RTVFormats.RTFormats); @@ -1314,8 +1362,36 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De quadWriteDXIL.pShaderBytecode = m_Overlay.QuadOverdrawWriteDXILPS->GetBufferPointer(); } + ID3D12Resource *overrideDepth = NULL; + + ResourceId res = rs.GetDSVID(); + + ID3D12Resource *curDepth = m_pDevice->GetResourceManager()->GetCurrentAs(res); + D3D12_RESOURCE_DESC curDepthDesc = curDepth ? curDepth->GetDesc() : D3D12_RESOURCE_DESC(); + if(curDepthDesc.SampleDesc.Count > 1) + { + curDepthDesc.Alignment = 0; + curDepthDesc.DepthOrArraySize *= (UINT16)curDepthDesc.SampleDesc.Count; + curDepthDesc.SampleDesc.Count = 1; + curDepthDesc.SampleDesc.Quality = 0; + + hr = m_pDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &curDepthDesc, + D3D12_RESOURCE_STATE_COMMON, NULL, + __uuidof(ID3D12Resource), (void **)&overrideDepth); + if(FAILED(hr)) + { + RDCERR("Failed to create overrideDepth HRESULT: %s", ToStr(hr).c_str()); + return m_Overlay.resourceId; + } + + dsv = GetDebugManager()->GetCPUHandle(OVERLAY_DSV); + m_pDevice->CreateDepthStencilView(overrideDepth, NULL, dsv); + } + // declare callback struct here - D3D12QuadOverdrawCallback cb(m_pDevice, quadWrite, quadWriteDXIL, events, + D3D12QuadOverdrawCallback cb(m_pDevice, quadWrite, quadWriteDXIL, events, overrideDepth, + overrideDepth ? curDepth : NULL, + overrideDepth ? ToPortableHandle(dsv) : PortableHandle(), ToPortableHandle(GetDebugManager()->GetCPUHandle(OVERDRAW_UAV))); m_pDevice->ReplayLog(events.front(), events.back(), eReplay_Full); @@ -1348,7 +1424,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - list->SetPipelineState(m_Overlay.QuadResolvePipe); + list->SetPipelineState(m_Overlay.QuadResolvePipe[Log2Floor(overlayTexDesc.SampleDesc.Count)]); list->SetGraphicsRootSignature(m_Overlay.QuadResolveRootSig); @@ -1372,6 +1448,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De } SAFE_RELEASE(overdrawTex); + SAFE_RELEASE(overrideDepth); } if(overlay == DebugOverlay::QuadOverdrawPass) diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 539d7ad59..d50ce7b4e 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -3346,7 +3346,7 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub, m_pDevice->FlushLists(); // expand multisamples out to array - GetDebugManager()->CopyTex2DMSToArray(Unwrap(arrayTexture), Unwrap(srcTexture)); + GetDebugManager()->CopyTex2DMSToArray(NULL, Unwrap(arrayTexture), Unwrap(srcTexture)); tmpTexture = srcTexture = arrayTexture; diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index f1cd9a671..dac939b3a 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -368,7 +368,7 @@ private: ID3DBlob *QuadOverdrawWritePS = NULL; ID3DBlob *QuadOverdrawWriteDXILPS = NULL; ID3D12RootSignature *QuadResolveRootSig = NULL; - ID3D12PipelineState *QuadResolvePipe = NULL; + ID3D12PipelineState *QuadResolvePipe[8] = {NULL}; ID3D12Resource *Texture = NULL; ResourceId resourceId; diff --git a/renderdoc/driver/gl/gl_overlay.cpp b/renderdoc/driver/gl/gl_overlay.cpp index 7fb70a22c..28a16c907 100644 --- a/renderdoc/driver/gl/gl_overlay.cpp +++ b/renderdoc/driver/gl/gl_overlay.cpp @@ -1812,28 +1812,29 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug if(!events.empty()) { GLuint replacefbo = 0; - GLuint quadtexs[3] = {0}; + GLuint overridedepth = 0; + GLuint quadtexs[2] = {0}; drv.glGenFramebuffers(1, &replacefbo); drv.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); - drv.glGenTextures(3, quadtexs); + drv.glGenTextures(2, quadtexs); // image for quad usage - drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[2]); - drv.glTextureImage3DEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, 0, eGL_R32UI, + drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[1]); + drv.glTextureImage3DEXT(quadtexs[1], eGL_TEXTURE_2D_ARRAY, 0, eGL_R32UI, RDCMAX(1, outWidth >> 1), RDCMAX(1, outHeight >> 1), 4, 0, eGL_RED_INTEGER, eGL_UNSIGNED_INT, NULL); - drv.glTextureParameteriEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0); + drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0); // temporarily attach to FBO to clear it GLint zero[4] = {0}; - drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 0); + drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 0); drv.glClearBufferiv(eGL_COLOR, 0, zero); - drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 1); + drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 1); drv.glClearBufferiv(eGL_COLOR, 0, zero); - drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 2); + drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 2); drv.glClearBufferiv(eGL_COLOR, 0, zero); - drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 3); + drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[1], 0, 3); drv.glClearBufferiv(eGL_COLOR, 0, zero); drv.glBindTexture(eGL_TEXTURE_2D, quadtexs[0]); @@ -1849,28 +1850,56 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D, quadtexs[0], 0); + GLuint curdrawfbo = 0, curreadfbo = 0; + GLuint curDepth = 0, depthType = 0; + if(overlay == DebugOverlay::QuadOverdrawPass) + ReplayLog(events[0], eReplay_WithoutDraw); + else + rs.ApplyState(m_pDriver); + + drv.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curdrawfbo); + drv.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curreadfbo); + // TODO handle non-2D depth/stencil attachments and fetch slice or cubemap face GLint mip = 0; - drv.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, + drv.glGetNamedFramebufferAttachmentParameterivEXT(curdrawfbo, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curDepth); - drv.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, + drv.glGetNamedFramebufferAttachmentParameterivEXT(curdrawfbo, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&depthType); GLenum fmt = eGL_DEPTH32F_STENCIL8; + GLenum depthEnum = eGL_TEXTURE_2D; + uint32_t depthSlices = 1, depthSamples = 1; + if(curDepth) { if(depthType == eGL_TEXTURE) { - drv.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, - &mip); - drv.glGetTextureLevelParameterivEXT(curDepth, eGL_TEXTURE_2D, mip, + ResourceId id = m_pDriver->GetResourceManager()->GetResID(TextureRes(ctx, curDepth)); + WrappedOpenGL::TextureData &depthdetails = m_pDriver->m_Textures[id]; + + depthSamples = depthdetails.samples; + depthSlices = depthdetails.depth; + + if(depthdetails.samples > 1) + depthEnum = depthdetails.depth > 1 ? eGL_TEXTURE_2D_MULTISAMPLE_ARRAY + : eGL_TEXTURE_2D_MULTISAMPLE; + else + depthEnum = depthdetails.depth > 1 ? eGL_TEXTURE_2D_ARRAY : eGL_TEXTURE_2D; + + if(depthEnum == eGL_TEXTURE_2D_MULTISAMPLE || + depthEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + mip = 0; + else + drv.glGetNamedFramebufferAttachmentParameterivEXT( + curdrawfbo, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); + drv.glGetTextureLevelParameterivEXT(curDepth, depthEnum, mip, eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt); } else @@ -1880,34 +1909,40 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug } } - drv.glBindTexture(eGL_TEXTURE_2D, quadtexs[1]); - drv.glTextureImage2DEXT(quadtexs[1], eGL_TEXTURE_2D, 0, fmt, outWidth, outHeight, 0, - GetBaseFormat(fmt), GetDataType(fmt), NULL); - drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 0); - drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, - eGL_CLAMP_TO_EDGE); - drv.glTextureParameteriEXT(quadtexs[1], eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, - eGL_CLAMP_TO_EDGE); - GLenum dsAttach = eGL_DEPTH_STENCIL_ATTACHMENT; if(GetBaseFormat(fmt) == eGL_DEPTH_COMPONENT) dsAttach = eGL_DEPTH_ATTACHMENT; - drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, dsAttach, eGL_TEXTURE_2D, quadtexs[1], 0); + drv.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); - if(overlay == DebugOverlay::QuadOverdrawPass) - ReplayLog(events[0], eReplay_WithoutDraw); - else - rs.ApplyState(m_pDriver); + drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, dsAttach, depthEnum, curDepth, 0); + + if(depthEnum == eGL_TEXTURE_2D_MULTISAMPLE || depthEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + drv.CopyTex2DMSToArray(overridedepth, curDepth, outWidth, outHeight, depthSlices, + depthSamples, fmt); + + drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0); + drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MIN_FILTER, + eGL_NEAREST); + drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAG_FILTER, + eGL_NEAREST); + drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_WRAP_S, + eGL_CLAMP_TO_EDGE); + drv.glTextureParameteriEXT(overridedepth, eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_WRAP_T, + eGL_CLAMP_TO_EDGE); + + drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, dsAttach, overridedepth, 0, 0); + } + + drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curdrawfbo); + drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curreadfbo); for(size_t i = 0; i < events.size(); i++) { GLint depthwritemask = 1; GLint stencilfmask = 0xff, stencilbmask = 0xff; - GLuint curdrawfbo = 0, curreadfbo = 0; struct { GLuint name; @@ -1943,7 +1978,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug // bind our FBO drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, replacefbo); // bind image - drv.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); + drv.glBindImageTexture(0, quadtexs[1], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); GLuint prog = 0, pipe = 0; drv.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog); @@ -1966,9 +2001,9 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug RDCERR("Couldn't get location of overdrawImage"); } - drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curdrawfbo); - SafeBlitFramebuffer(0, 0, outWidth, outHeight, 0, 0, outWidth, outHeight, - GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); + if(overlay == DebugOverlay::QuadOverdrawPass && overridedepth) + drv.CopyTex2DMSToArray(overridedepth, curDepth, outWidth, outHeight, depthSlices, + depthSamples, fmt); m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw); @@ -2035,7 +2070,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug drv.glStencilMask(0); drv.glViewport(0, 0, outWidth, outHeight); - drv.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); + drv.glBindImageTexture(0, quadtexs[1], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); GLuint emptyVAO = 0; drv.glGenVertexArrays(1, &emptyVAO); @@ -2043,13 +2078,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug drv.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); drv.glBindVertexArray(0); drv.glDeleteVertexArrays(1, &emptyVAO); - - drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D, - quadtexs[0], 0); } drv.glDeleteFramebuffers(1, &replacefbo); - drv.glDeleteTextures(3, quadtexs); + drv.glDeleteTextures(2, quadtexs); + drv.glDeleteTextures(1, &overridedepth); if(overlay == DebugOverlay::QuadOverdrawPass) ReplayLog(eventId, eReplay_WithoutDraw);