diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index d661ed0b9..52d6ca342 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -752,8 +752,6 @@ void TextureViewer::RT_FetchCurrentPixel(IReplayController *r, uint32_t x, uint3 if(overlayResId != ResourceId()) { id = overlayResId; - sub.sample = 0; - sub.slice = 0; typeCast = CompType::Typeless; } } diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 27770ceec..09c5372de 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -235,8 +235,8 @@ public: RDCEraseEl(ret); return ret; } - ResourceId RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, + ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) { return ResourceId(); diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 25cb02b2b..027cabb5e 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1054,9 +1054,10 @@ MeshFormat ReplayProxy::GetPostVSBuffers(uint32_t eventId, uint32_t instID, uint template ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnSerialiser &retser, - ResourceId texid, CompType typeCast, - FloatVector clearCol, DebugOverlay overlay, - uint32_t eventId, const rdcarray &passEvents) + ResourceId texid, const Subresource &sub, + CompType typeCast, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const rdcarray &passEvents) { const ReplayProxyPacket expectedPacket = eReplayProxy_RenderOverlay; ReplayProxyPacket packet = eReplayProxy_RenderOverlay; @@ -1065,6 +1066,7 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnS { BEGIN_PARAMS(); SERIALISE_ELEMENT(texid); + SERIALISE_ELEMENT(sub); SERIALISE_ELEMENT(typeCast); SERIALISE_ELEMENT(overlay); SERIALISE_ELEMENT(clearCol); @@ -1076,7 +1078,7 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnS { REMOTE_EXECUTION(); if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) - ret = m_Remote->RenderOverlay(texid, typeCast, clearCol, overlay, eventId, passEvents); + ret = m_Remote->RenderOverlay(texid, sub, typeCast, clearCol, overlay, eventId, passEvents); } SERIALISE_RETURN(ret); @@ -1084,11 +1086,11 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnS return ret; } -ResourceId ReplayProxy::RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, +ResourceId ReplayProxy::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) { - PROXY_FUNCTION(RenderOverlay, texid, typeCast, clearCol, overlay, eventId, passEvents); + PROXY_FUNCTION(RenderOverlay, texid, sub, typeCast, clearCol, overlay, eventId, passEvents); } template @@ -2786,8 +2788,8 @@ bool ReplayProxy::Tick(int type) } case eReplayProxy_ContinueDebug: ContinueDebug(NULL); break; case eReplayProxy_RenderOverlay: - RenderOverlay(ResourceId(), CompType::Typeless, FloatVector(), DebugOverlay::NoOverlay, 0, - rdcarray()); + RenderOverlay(ResourceId(), Subresource(), CompType::Typeless, FloatVector(), + DebugOverlay::NoOverlay, 0, rdcarray()); break; case eReplayProxy_PixelHistory: PixelHistory(rdcarray(), ResourceId(), 0, 0, Subresource(), CompType::Typeless); diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 5ac547402..5a8e34413 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -505,9 +505,9 @@ public: IMPLEMENT_FUNCTION_PROXIED(MeshFormat, GetPostVSBuffers, uint32_t eventId, uint32_t instID, uint32_t viewID, MeshDataStage stage); - IMPLEMENT_FUNCTION_PROXIED(ResourceId, RenderOverlay, ResourceId texid, CompType typeCast, - FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, - const rdcarray &passEvents); + IMPLEMENT_FUNCTION_PROXIED(ResourceId, RenderOverlay, ResourceId texid, const Subresource &sub, + CompType typeCast, FloatVector clearCol, DebugOverlay overlay, + uint32_t eventId, const rdcarray &passEvents); IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetShaderEntryPoints, ResourceId shader); IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId pipeline, ResourceId, diff --git a/renderdoc/driver/d3d11/d3d11_overlay.cpp b/renderdoc/driver/d3d11/d3d11_overlay.cpp index a38825af0..8f34bd620 100644 --- a/renderdoc/driver/d3d11/d3d11_overlay.cpp +++ b/renderdoc/driver/d3d11/d3d11_overlay.cpp @@ -38,8 +38,8 @@ #include "data/hlsl/hlsl_cbuffers.h" -ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, +ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) { TextureShaderDetails details = GetDebugManager()->GetShaderDetails(texid, typeCast, false); @@ -53,7 +53,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float realTexDesc.Usage = D3D11_USAGE_DEFAULT; realTexDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; realTexDesc.ArraySize = 1; - realTexDesc.MipLevels = 1; + realTexDesc.MipLevels = details.texMips; realTexDesc.CPUAccessFlags = 0; realTexDesc.MiscFlags = 0; realTexDesc.SampleDesc.Count = 1; @@ -79,7 +79,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float // need to recreate backing custom render tex if(realTexDesc.Width != customTexDesc.Width || realTexDesc.Height != customTexDesc.Height || - realTexDesc.Format != customTexDesc.Format || + realTexDesc.Format != customTexDesc.Format || realTexDesc.MipLevels != customTexDesc.MipLevels || realTexDesc.SampleDesc.Count != customTexDesc.SampleDesc.Count || realTexDesc.SampleDesc.Quality != customTexDesc.SampleDesc.Quality) { @@ -147,7 +147,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float D3D11_RENDER_TARGET_VIEW_DESC rtDesc; rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; - rtDesc.Texture2D.MipSlice = 0; + rtDesc.Texture2D.MipSlice = sub.mip; if(realTexDesc.SampleDesc.Count > 1 || realTexDesc.SampleDesc.Quality > 0) { @@ -326,7 +326,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float } } - float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f}; + float clearColour[] = {0.0f, 1.0f, 0.0f, 0.0f}; m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); float overlayConsts[] = {1.0f, 0.0f, 0.0f, 1.0f}; @@ -545,6 +545,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float SAFE_RELEASE(rs); rdesc.FillMode = D3D11_FILL_WIREFRAME; + rdesc.DepthClipEnable = FALSE; rdesc.CullMode = D3D11_CULL_NONE; hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); @@ -630,14 +631,15 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float desc.DepthFunc == D3D11_COMPARISON_LESS_EQUAL; float depthClear = depthFuncLess ? 1.0f : 0.0f; - m_pImmediateContext->ClearDepthStencilView(state.OM.DepthView, D3D11_CLEAR_DEPTH, - depthClear, 0); + m_pImmediateContext->ClearDepthStencilView( + state.OM.DepthView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, depthClear, 0); } } else { // Without a depth stencil state set, the comparison func is D3D11_COMPARISON_LESS - m_pImmediateContext->ClearDepthStencilView(state.OM.DepthView, D3D11_CLEAR_DEPTH, 1.0f, 0); + m_pImmediateContext->ClearDepthStencilView( + state.OM.DepthView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); } } @@ -1114,6 +1116,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float if(rs) { rs->GetDesc(&rdesc); + SAFE_RELEASE(rs); } else { @@ -1179,6 +1182,9 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); + float clearColour[] = {0.0f, 1.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); + float redConsts[] = {255.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f}; ID3D11Buffer *buf = GetDebugManager()->MakeCBuffer(redConsts, sizeof(redConsts)); @@ -1221,8 +1227,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float m_pImmediateContext->OMSetDepthStencilState(os, stencilRef); - float greenConsts[] = {0.0f / 255.0f, 255.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f}; - + float greenConsts[] = {0.0f, 1.0f, 0.0f, 1.0f}; buf = GetDebugManager()->MakeCBuffer(greenConsts, sizeof(greenConsts)); m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); @@ -1258,20 +1263,33 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); + ID3D11RasterizerState *prevrs = NULL; + m_pImmediateContext->RSGetState(&prevrs); + ID3D11RasterizerState *rs = NULL; { D3D11_RASTERIZER_DESC rdesc; - rdesc.FillMode = D3D11_FILL_SOLID; + if(prevrs) + { + prevrs->GetDesc(&rdesc); + } + else + { + rdesc.FillMode = D3D11_FILL_SOLID; + rdesc.CullMode = D3D11_CULL_BACK; + rdesc.FrontCounterClockwise = FALSE; + rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + rdesc.DepthClipEnable = TRUE; + rdesc.ScissorEnable = FALSE; + rdesc.MultisampleEnable = FALSE; + rdesc.AntialiasedLineEnable = FALSE; + } + rdesc.CullMode = D3D11_CULL_NONE; - rdesc.FrontCounterClockwise = FALSE; - rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; - rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; - rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; rdesc.DepthClipEnable = FALSE; - rdesc.ScissorEnable = FALSE; - rdesc.MultisampleEnable = FALSE; - rdesc.AntialiasedLineEnable = FALSE; hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); if(FAILED(hr)) @@ -1284,8 +1302,8 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float float clearColour[] = {0.0f, 1.0f, 0.0f, 0.0f}; m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); - float overlayConsts[] = {0.0f, 1.0f, 0.0f, 1.0f}; - ID3D11Buffer *buf = GetDebugManager()->MakeCBuffer(overlayConsts, sizeof(overlayConsts)); + float redConsts[] = {1.0f, 0.0f, 0.0f, 1.0f}; + ID3D11Buffer *buf = GetDebugManager()->MakeCBuffer(redConsts, sizeof(redConsts)); m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); @@ -1293,6 +1311,15 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw); + float greenConsts[] = {0.0f, 1.0f, 0.0f, 1.0f}; + buf = GetDebugManager()->MakeCBuffer(greenConsts, sizeof(greenConsts)); + + m_pImmediateContext->RSSetState(prevrs); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); + + m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw); + SAFE_RELEASE(os); SAFE_RELEASE(rs); } diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index ea562825e..f79d5c14f 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -241,8 +241,8 @@ public: uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, + ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents); void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index a37ff1671..8c507b319 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -200,8 +200,8 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback D3D12RenderState m_PrevState; }; -ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, +ResourceId D3D12Replay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) { ID3D12Resource *resource = m_pDevice->GetResourceList()[texid]; @@ -226,7 +226,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float overlayTexDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; overlayTexDesc.Height = resourceDesc.Height; overlayTexDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - overlayTexDesc.MipLevels = 1; + overlayTexDesc.MipLevels = resourceDesc.MipLevels; overlayTexDesc.SampleDesc = resourceDesc.SampleDesc; overlayTexDesc.Width = resourceDesc.Width; @@ -248,6 +248,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float if(overlayTexDesc.Width != currentOverlayDesc.Width || overlayTexDesc.Height != currentOverlayDesc.Height || overlayTexDesc.Format != currentOverlayDesc.Format || + overlayTexDesc.MipLevels != currentOverlayDesc.MipLevels || overlayTexDesc.SampleDesc.Count != currentOverlayDesc.SampleDesc.Count || overlayTexDesc.SampleDesc.Quality != currentOverlayDesc.SampleDesc.Quality) { @@ -355,7 +356,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float D3D12_RENDER_TARGET_VIEW_DESC rtDesc = {}; rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rtDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; - rtDesc.Texture2D.MipSlice = 0; + rtDesc.Texture2D.MipSlice = sub.mip; rtDesc.Texture2D.PlaneSlice = 0; if(overlayTexDesc.SampleDesc.Count > 1 || overlayTexDesc.SampleDesc.Quality > 0) @@ -520,6 +521,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float psoDesc.PS.pShaderBytecode = red->GetBufferPointer(); psoDesc.PS.BytecodeLength = red->GetBufferSize(); + float clearColour[] = {0.0f, 1.0f, 0.0f, 0.0f}; + list->ClearRenderTargetView(rtv, clearColour, 0, NULL); + list->Close(); list = NULL; @@ -698,7 +702,8 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float float depthClear = depthFuncLess ? 1.0f : 0.0f; Unwrap(list)->ClearDepthStencilView(Unwrap(GetDebugManager()->GetTempDescriptor(rs.dsv)), - D3D12_CLEAR_FLAG_DEPTH, depthClear, 0, 0, NULL); + D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, + depthClear, 0, 0, NULL); } } } @@ -878,6 +883,10 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float D3D12_CPU_DESCRIPTOR_HANDLE tmpdsv = GetDebugManager()->GetTempDescriptor(rs.dsv); list->OMSetRenderTargets(1, &rtv, TRUE, &tmpdsv); } + else + { + list->OMSetRenderTargets(1, &rtv, TRUE, NULL); + } list->RSSetViewports(1, &rs.views[0]); @@ -999,8 +1008,8 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float list = m_pDevice->GetNewList(); } - uint32_t width = uint32_t(resourceDesc.Width >> 1); - uint32_t height = resourceDesc.Height >> 1; + uint32_t width = uint32_t(RDCMAX(1ULL, overlayTexDesc.Width >> (sub.mip + 1))); + uint32_t height = RDCMAX(1U, overlayTexDesc.Height >> (sub.mip + 1)); width = RDCMAX(1U, width); height = RDCMAX(1U, height); @@ -1174,6 +1183,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeCast, Float psoDesc.PS.pShaderBytecode = green->GetBufferPointer(); psoDesc.PS.BytecodeLength = green->GetBufferSize(); + float clearColour[] = {0.0f, 1.0f, 0.0f, 0.0f}; + list->ClearRenderTargetView(rtv, clearColour, 0, NULL); + list->Close(); list = NULL; diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 698c51191..073bdc1f5 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -196,8 +196,8 @@ public: uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, + ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents); void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry, diff --git a/renderdoc/driver/gl/gl_overlay.cpp b/renderdoc/driver/gl/gl_overlay.cpp index c30e18305..76cb3f9c4 100644 --- a/renderdoc/driver/gl/gl_overlay.cpp +++ b/renderdoc/driver/gl/gl_overlay.cpp @@ -227,8 +227,8 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag return HasSPIRVShaders; } -ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, +ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) { WrappedOpenGL &drv = *m_pDriver; @@ -362,10 +362,13 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec texQueryEnum = eGL_TEXTURE_BINDING_2D_MULTISAMPLE; } + GLint texMips = GetNumMips(texDetails.curType, texDetails.resource.name, texDetails.width, + texDetails.height, texDetails.depth); + // resize (or create) the overlay texture and FBO if necessary if(DebugData.overlayTexWidth != texDetails.width || DebugData.overlayTexHeight != texDetails.height || - DebugData.overlayTexSamples != texDetails.samples) + DebugData.overlayTexSamples != texDetails.samples || DebugData.overlayTexMips != texMips) { if(DebugData.overlayFBO) { @@ -385,6 +388,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec DebugData.overlayTexWidth = texDetails.width; DebugData.overlayTexHeight = texDetails.height; DebugData.overlayTexSamples = texDetails.samples; + DebugData.overlayTexMips = texMips; if(DebugData.overlayTexSamples > 1) { @@ -405,18 +409,25 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec drv.glTextureImage2DEXT(DebugData.overlayTex, texBindingEnum, 0, internalFormat, texDetails.width, texDetails.height, 0, format, type, NULL); - drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0); + for(GLint i = 1; i < texMips; i++) + drv.glTextureImage2DEXT(DebugData.overlayTex, texBindingEnum, i, internalFormat, + RDCMAX(1, texDetails.width >> i), RDCMAX(1, texDetails.height >> i), + 0, format, type, NULL); + drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MAX_LEVEL, texMips - 1); drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); } drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum, - DebugData.overlayTex, 0); + DebugData.overlayTex, sub.mip); drv.glBindTexture(texBindingEnum, curTex); } + GLint outWidth = RDCMAX(1, texDetails.width >> sub.mip); + GLint outHeight = RDCMAX(1, texDetails.height >> sub.mip); + drv.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO); // disable several tests/allow rendering - some overlays will override @@ -647,8 +658,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec } else if(overlay == DebugOverlay::Depth || overlay == DebugOverlay::Stencil) { - float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; - drv.glClearBufferfv(eGL_COLOR, 0, black); + float backCol[] = {0.0f, 1.0f, 0.0f, 0.0f}; + drv.glClearBufferfv(eGL_COLOR, 0, backCol); float red[] = {1.0f, 0.0f, 0.0f, 1.0f}; drv.glProgramUniform4fv(DebugData.overlayProg, overlayFixedColLocation, 1, red); @@ -669,9 +680,6 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec GLuint depthCopy = 0, stencilCopy = 0; - GLint mip = 0; - GLint layer = 0; - // create matching depth for existing FBO if(curDepth != 0) { @@ -684,29 +692,12 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec if(type != eGL_RENDERBUFFER) { ResourceId id = m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, curDepth)); - WrappedOpenGL::TextureData &details = m_pDriver->m_Textures[id]; - - fmt = details.internalFormat; - - drv.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); - - if(details.curType == eGL_TEXTURE_CUBE_MAP) - { - GLenum face; - drv.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint *)&face); - - layer = CubeTargetIndex(face); - } + fmt = m_pDriver->m_Textures[id].internalFormat; } else { ResourceId id = m_pDriver->GetResourceManager()->GetID(RenderbufferRes(ctx, curDepth)); - WrappedOpenGL::TextureData &details = m_pDriver->m_Textures[id]; - - fmt = details.internalFormat; + fmt = m_pDriver->m_Textures[id].internalFormat; } if(copyBindingEnum == eGL_TEXTURE_CUBE_MAP) @@ -731,6 +722,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec drv.glTextureImage2DEXT(depthCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth, DebugData.overlayTexHeight, 0, GetBaseFormat(fmt), GetDataType(fmt), NULL); + for(GLint i = 1; i < texMips; i++) + drv.glTextureImage2DEXT(depthCopy, copyBindingEnum, i, fmt, + RDCMAX(1, DebugData.overlayTexWidth >> i), + RDCMAX(1, DebugData.overlayTexHeight >> i), 0, GetBaseFormat(fmt), + GetDataType(fmt), NULL); drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0); drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); @@ -753,26 +749,12 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec if(type != eGL_RENDERBUFFER) { ResourceId id = m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, curDepth)); - WrappedOpenGL::TextureData &details = m_pDriver->m_Textures[id]; - - fmt = details.internalFormat; - - if(details.curType == eGL_TEXTURE_CUBE_MAP) - { - GLenum face; - drv.glGetNamedFramebufferAttachmentParameterivEXT( - rs.DrawFBO.name, eGL_DEPTH_ATTACHMENT, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint *)&face); - - layer = CubeTargetIndex(face); - } + fmt = m_pDriver->m_Textures[id].internalFormat; } else { ResourceId id = m_pDriver->GetResourceManager()->GetID(RenderbufferRes(ctx, curDepth)); - WrappedOpenGL::TextureData &details = m_pDriver->m_Textures[id]; - - fmt = details.internalFormat; + fmt = m_pDriver->m_Textures[id].internalFormat; } GLuint curTex = 0; @@ -791,6 +773,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec drv.glTextureImage2DEXT(stencilCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth, DebugData.overlayTexHeight, 0, GetBaseFormat(fmt), GetDataType(fmt), NULL); + for(GLint i = 1; i < texMips; i++) + drv.glTextureImage2DEXT(stencilCopy, copyBindingEnum, i, fmt, + RDCMAX(1, DebugData.overlayTexWidth >> i), + RDCMAX(1, DebugData.overlayTexHeight >> i), 0, GetBaseFormat(fmt), + GetDataType(fmt), NULL); drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0); drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); @@ -804,30 +791,18 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec // bind depth/stencil to overlay FBO (currently bound to DRAW_FRAMEBUFFER) if(curDepth != 0 && curDepth == curStencil) { - if(layer == 0) - drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, - eGL_TEXTURE_2D, depthCopy, mip); - else - drv.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, depthCopy, - mip, layer); + drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, eGL_TEXTURE_2D, + depthCopy, sub.mip); } else if(curDepth != 0) { - if(layer == 0) - drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_TEXTURE_2D, - depthCopy, mip); - else - drv.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, depthCopy, mip, - layer); + drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_TEXTURE_2D, + depthCopy, sub.mip); } else if(curStencil != 0) { - if(layer == 0) - drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_TEXTURE_2D, - stencilCopy, mip); - else - drv.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, stencilCopy, - mip, layer); + drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_TEXTURE_2D, + stencilCopy, sub.mip); } // bind the 'real' fbo to the read framebuffer, so we can blit from it @@ -865,8 +840,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec drv.glDisable(eGL_DEPTH_CLAMP); // get latest depth/stencil from read FBO (existing FBO) into draw FBO (overlay FBO) - SafeBlitFramebuffer(0, 0, DebugData.overlayTexWidth, DebugData.overlayTexHeight, 0, 0, - DebugData.overlayTexWidth, DebugData.overlayTexHeight, + SafeBlitFramebuffer(0, 0, outWidth, outHeight, 0, 0, outWidth, outHeight, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); ReplayLog(eventId, eReplay_OnlyDraw); @@ -886,10 +860,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec } else if(overlay == DebugOverlay::BackfaceCull) { - float col[] = {0.0f, 0.0f, 0.0f, 0.0f}; + float col[] = {0.0f, 1.0f, 0.0f, 0.0f}; drv.glClearBufferfv(eGL_COLOR, 0, col); col[0] = 1.0f; + col[1] = 0.0f; col[3] = 1.0f; drv.glProgramUniform4fv(DebugData.overlayProg, overlayFixedColLocation, 1, col); @@ -949,7 +924,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec // writes to happen. bool depthFuncLess = rs.DepthFunc == eGL_LESS || rs.DepthFunc == eGL_LEQUAL; float depthClear = depthFuncLess ? 1.0f : 0.0f; - drv.glClearBufferfv(eGL_DEPTH, 0, &depthClear); + drv.glClearBufferfi(eGL_DEPTH_STENCIL, 0, depthClear, 0); } } @@ -1105,7 +1080,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec // bind our FBO drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, overlayFBO); drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum, - DebugData.overlayTex, 0); + DebugData.overlayTex, sub.mip); // now apply the depth texture binding if(depthObj) @@ -1376,8 +1351,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec // image for quad usage drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[2]); drv.glTextureImage3DEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, 0, eGL_R32UI, - RDCMAX(1, texDetails.width >> 1), RDCMAX(1, texDetails.height >> 1), - 4, 0, eGL_RED_INTEGER, eGL_UNSIGNED_INT, NULL); + RDCMAX(1, outWidth >> 1), RDCMAX(1, outHeight >> 1), 4, 0, + eGL_RED_INTEGER, eGL_UNSIGNED_INT, NULL); drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0); // temporarily attach to FBO to clear it @@ -1392,8 +1367,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec drv.glClearBufferiv(eGL_COLOR, 0, zero); drv.glBindTexture(eGL_TEXTURE_2D, quadtexs[0]); - drv.glTextureImage2DEXT(quadtexs[0], eGL_TEXTURE_2D, 0, eGL_RGBA8, texDetails.width, - texDetails.height, 0, eGL_RGBA, eGL_UNSIGNED_BYTE, NULL); + drv.glTextureImage2DEXT(quadtexs[0], eGL_TEXTURE_2D, 0, eGL_RGBA8, outWidth, outHeight, 0, + eGL_RGBA, eGL_UNSIGNED_BYTE, NULL); drv.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 0); drv.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); drv.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); @@ -1434,8 +1409,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec } drv.glBindTexture(eGL_TEXTURE_2D, quadtexs[1]); - drv.glTextureImage2DEXT(quadtexs[1], eGL_TEXTURE_2D, 0, fmt, texDetails.width, - texDetails.height, 0, GetBaseFormat(fmt), GetDataType(fmt), NULL); + drv.glTextureImage2DEXT(quadtexs[1], eGL_TEXTURE_2D, 0, fmt, outWidth, outHeight, 0, + GetBaseFormat(fmt), GetDataType(fmt), NULL); drv.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 0); drv.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); drv.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); @@ -1518,9 +1493,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec } drv.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curdrawfbo); - SafeBlitFramebuffer(0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, - texDetails.height, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, - eGL_NEAREST); + SafeBlitFramebuffer(0, 0, outWidth, outHeight, 0, 0, outWidth, outHeight, + GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw); @@ -1561,7 +1535,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec // modify our fbo to attach the overlay texture instead drv.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum, - DebugData.overlayTex, 0); + DebugData.overlayTex, sub.mip); drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, texBindingEnum, 0, 0); @@ -1575,7 +1549,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVec drv.glDisable(eGL_DEPTH_TEST); drv.glDisable(eGL_STENCIL_TEST); drv.glStencilMask(0); - drv.glViewport(0, 0, texDetails.width, texDetails.height); + drv.glViewport(0, 0, outWidth, outHeight); drv.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 2ec76fdfe..85ac2377c 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -226,8 +226,8 @@ public: uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId id, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, + ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents); ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, const Subresource &sub, CompType typeCast); @@ -384,7 +384,7 @@ private: GLuint overlayTex; GLuint overlayFBO; GLuint overlayProg; - GLint overlayTexWidth, overlayTexHeight, overlayTexSamples; + GLint overlayTexWidth, overlayTexHeight, overlayTexSamples, overlayTexMips; GLuint UBOs[3]; diff --git a/renderdoc/driver/vulkan/vk_overlay.cpp b/renderdoc/driver/vulkan/vk_overlay.cpp index c071a5442..aff252a5d 100644 --- a/renderdoc/driver/vulkan/vk_overlay.cpp +++ b/renderdoc/driver/vulkan/vk_overlay.cpp @@ -396,8 +396,8 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const DrawcallDescription *dr indexCount = (uint32_t)patchedIndices.size(); } -ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, +ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) { const VkDevDispatchTable *vt = ObjDisp(m_Device); @@ -413,7 +413,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa const VulkanCreationInfo::Framebuffer &fb = m_pDriver->m_CreationInfo.m_Framebuffer[m_pDriver->m_RenderState.GetFramebuffer()]; - if(fb.width != iminfo.extent.width || fb.height != iminfo.extent.height) + if(fb.width != RDCMAX(1U, iminfo.extent.width >> sub.mip) || + fb.height != RDCMAX(1U, iminfo.extent.height >> sub.mip)) return GetResID(m_Overlay.Image); } @@ -428,8 +429,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VkMarkerRegion::Begin(StringFormat::Fmt("RenderOverlay %d", overlay), cmd); // if the overlay image is the wrong size, free it - if(m_Overlay.Image != VK_NULL_HANDLE && (iminfo.extent.width != m_Overlay.ImageDim.width || - iminfo.extent.height != m_Overlay.ImageDim.height)) + if(m_Overlay.Image != VK_NULL_HANDLE && + (iminfo.extent.width != m_Overlay.ImageDim.width || + iminfo.extent.height != m_Overlay.ImageDim.height || iminfo.samples != m_Overlay.Samples || + iminfo.mipLevels != m_Overlay.MipLevels)) { m_pDriver->vkDestroyRenderPass(m_Device, m_Overlay.NoDepthRP, NULL); m_pDriver->vkDestroyFramebuffer(m_Device, m_Overlay.NoDepthFB, NULL); @@ -442,6 +445,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa m_Overlay.NoDepthFB = VK_NULL_HANDLE; } + VkImageSubresourceRange subRange = {VK_IMAGE_ASPECT_COLOR_BIT, sub.mip, 1, 0, 1}; + // create the overlay image if we don't have one already // we go through the driver's creation functions so creation info // is saved and the resources are registered as live resources for @@ -450,6 +455,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa { m_Overlay.ImageDim.width = iminfo.extent.width; m_Overlay.ImageDim.height = iminfo.extent.height; + m_Overlay.MipLevels = iminfo.mipLevels; + m_Overlay.Samples = iminfo.samples; VkImageCreateInfo imInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -458,7 +465,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_IMAGE_TYPE_2D, VK_FORMAT_R16G16B16A16_SFLOAT, {m_Overlay.ImageDim.width, m_Overlay.ImageDim.height, 1}, - 1, + (uint32_t)iminfo.mipLevels, 1, iminfo.samples, VK_IMAGE_TILING_OPTIMAL, @@ -508,7 +515,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa imInfo.format, {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, + subRange, }; vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_Overlay.ImageView); @@ -535,7 +542,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkSubpassDescription sub = { + VkSubpassDescription subp = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, NULL, // inputs 1, &colRef, // color @@ -551,7 +558,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa 1, &colDesc, 1, - &sub, + &subp, 0, NULL, // dependencies }; @@ -567,8 +574,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa m_Overlay.NoDepthRP, 1, &m_Overlay.ImageView, - (uint32_t)m_Overlay.ImageDim.width, - (uint32_t)m_Overlay.ImageDim.height, + RDCMAX(1U, m_Overlay.ImageDim.width >> sub.mip), + RDCMAX(1U, m_Overlay.ImageDim.height >> sub.mip), 1, }; @@ -579,8 +586,6 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa // needs to match the depth texture type wherever our draw is. } - VkImageSubresourceRange subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; - const DrawcallDescription *mainDraw = m_pDriver->GetDrawcall(eventId); // Secondary commands can't have render passes @@ -599,12 +604,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)black, 1, &subresourceRange); + (VkClearColorValue *)black, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -625,12 +630,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)black, 1, &subresourceRange); + (VkClearColorValue *)black, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -664,12 +669,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)bgclearCol, 1, &subresourceRange); + (VkClearColorValue *)bgclearCol, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -911,12 +916,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)black, 1, &subresourceRange); + (VkClearColorValue *)black, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -1037,7 +1042,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa } else if(overlay == DebugOverlay::BackfaceCull) { - float highlightCol[] = {0.0f, 0.0f, 0.0f, 0.0f}; + float highlightCol[] = {0.0f, 1.0f, 0.0f, 0.0f}; VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, @@ -1048,12 +1053,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)highlightCol, 1, &subresourceRange); + (VkClearColorValue *)highlightCol, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -1062,6 +1067,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa DoPipelineBarrier(cmd, 1, &barrier); highlightCol[0] = 1.0f; + highlightCol[1] = 0.0f; highlightCol[3] = 1.0f; // backup state @@ -1217,7 +1223,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa } else if(overlay == DebugOverlay::Depth || overlay == DebugOverlay::Stencil) { - float highlightCol[] = {0.0f, 0.0f, 0.0f, 0.0f}; + float highlightCol[] = {0.0f, 1.0f, 0.0f, 0.0f}; VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, @@ -1228,12 +1234,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)highlightCol, 1, &subresourceRange); + (VkClearColorValue *)highlightCol, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -1292,7 +1298,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; VkAttachmentReference dsRef = {1, attDescs[1].initialLayout}; - VkSubpassDescription sub = { + VkSubpassDescription subp = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, NULL, // inputs 1, &colRef, // color @@ -1308,7 +1314,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa 2, attDescs, 1, - &sub, + &subp, 0, NULL, // dependencies }; @@ -1342,6 +1348,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa // bound, so we just render green. highlightCol[0] = 1.0f; + highlightCol[1] = 0.0f; highlightCol[3] = 1.0f; // backup state @@ -1535,12 +1542,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)black, 1, &subresourceRange); + (VkClearColorValue *)black, 1, &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -1635,8 +1642,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa p.depthCompareOp == VK_COMPARE_OP_LESS_OR_EQUAL; float depthClear = depthFuncLess ? 1.0f : 0.0f; - VkClearAttachment clearDepthAtt = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, {}}; + VkClearAttachment clearDepthAtt = { + VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, {}}; clearDepthAtt.clearValue.depthStencil.depth = depthClear; + clearDepthAtt.clearValue.depthStencil.stencil = 0; atts.push_back(clearDepthAtt); } @@ -1686,13 +1695,13 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, - &subresourceRange); + &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -1934,13 +1943,13 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(m_Overlay.Image), - {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + subRange}; DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, - &subresourceRange); + &subRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -2071,7 +2080,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; VkAttachmentReference dsRef = {1, attDescs[1].initialLayout}; - VkSubpassDescription sub = { + VkSubpassDescription subp = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, NULL, // inputs 1, &colRef, // color @@ -2087,7 +2096,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa 2, attDescs, 1, - &sub, + &subp, 0, NULL, // dependencies }; @@ -2108,8 +2117,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa RP, 2, views, - (uint32_t)m_Overlay.ImageDim.width, - (uint32_t)m_Overlay.ImageDim.height, + RDCMAX(1U, m_Overlay.ImageDim.width >> sub.mip), + RDCMAX(1U, m_Overlay.ImageDim.height >> sub.mip), 1, }; @@ -2215,9 +2224,12 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeCast, Floa }; vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = { - 0.0f, 0.0f, (float)m_Overlay.ImageDim.width, (float)m_Overlay.ImageDim.height, - 0.0f, 1.0f}; + VkViewport viewport = {0.0f, + 0.0f, + (float)RDCMAX(1U, m_Overlay.ImageDim.width >> sub.mip), + (float)RDCMAX(1U, m_Overlay.ImageDim.height >> sub.mip), + 0.0f, + 1.0f}; vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); for(size_t i = 0; i < events.size(); i++) diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 7f24a1a25..87ba8cdae 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -379,8 +379,8 @@ public: uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId cfg, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, + ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents); ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, const Subresource &sub, CompType typeCast); @@ -580,6 +580,8 @@ private: VkDeviceSize ImageMemSize = 0; VkImage Image = VK_NULL_HANDLE; VkExtent2D ImageDim = {0, 0}; + int32_t MipLevels = 0; + VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT; VkImageView ImageView = VK_NULL_HANDLE; VkFramebuffer NoDepthFB = VK_NULL_HANDLE; VkRenderPass NoDepthRP = VK_NULL_HANDLE; diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 54a5a85ff..3435cbe20 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -187,8 +187,8 @@ public: const uint32_t threadid[3]) = 0; virtual rdcarray ContinueDebug(ShaderDebugger *debugger) = 0; - virtual ResourceId RenderOverlay(ResourceId texid, CompType typeCast, FloatVector clearCol, - DebugOverlay overlay, uint32_t eventId, + virtual ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const rdcarray &passEvents) = 0; virtual bool IsRenderOutput(ResourceId id) = 0; diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index 757089803..40a097fa4 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -274,8 +274,9 @@ void ReplayOutput::RefreshOverlay() f.z = ConvertLinearToSRGB(f.z); m_OverlayResourceId = m_pDevice->RenderOverlay( - m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId), m_RenderData.texDisplay.typeCast, - f, m_RenderData.texDisplay.overlay, m_EventID, passEvents); + m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId), + m_RenderData.texDisplay.subresource, m_RenderData.texDisplay.typeCast, f, + m_RenderData.texDisplay.overlay, m_EventID, passEvents); m_OverlayDirty = false; } else