diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index dd3780bbd..e4e408ca0 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -43,6 +43,7 @@ struct FloatVector { return x == o.x && y == o.y && z == o.z && w == o.w; } + bool operator!=(const FloatVector &o) const { return !(*this == o); } bool operator<(const FloatVector &o) const { if(!(x == o.x)) diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index ba56c3c8d..94d1e4b3c 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -228,8 +228,9 @@ public: RDCEraseEl(ret); return ret; } - ResourceId RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) + ResourceId RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) { return ResourceId(); } diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 8bf7247c8..1fb60a479 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1015,7 +1015,8 @@ MeshFormat ReplayProxy::GetPostVSBuffers(uint32_t eventId, uint32_t instID, uint template ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnSerialiser &retser, ResourceId texid, CompType typeHint, - DebugOverlay overlay, uint32_t eventId, + FloatVector clearCol, DebugOverlay overlay, + uint32_t eventId, const std::vector &passEvents) { const ReplayProxyPacket expectedPacket = eReplayProxy_RenderOverlay; @@ -1027,6 +1028,7 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnS SERIALISE_ELEMENT(texid); SERIALISE_ELEMENT(typeHint); SERIALISE_ELEMENT(overlay); + SERIALISE_ELEMENT(clearCol); SERIALISE_ELEMENT(eventId); SERIALISE_ELEMENT(passEvents); END_PARAMS(); @@ -1035,7 +1037,7 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnS { REMOTE_EXECUTION(); if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) - ret = m_Remote->RenderOverlay(texid, typeHint, overlay, eventId, passEvents); + ret = m_Remote->RenderOverlay(texid, typeHint, clearCol, overlay, eventId, passEvents); } SERIALISE_RETURN(ret); @@ -1043,10 +1045,11 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnS return ret; } -ResourceId ReplayProxy::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) +ResourceId ReplayProxy::RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) { - PROXY_FUNCTION(RenderOverlay, texid, typeHint, overlay, eventId, passEvents); + PROXY_FUNCTION(RenderOverlay, texid, typeHint, clearCol, overlay, eventId, passEvents); } template @@ -2633,7 +2636,7 @@ bool ReplayProxy::Tick(int type) break; } case eReplayProxy_RenderOverlay: - RenderOverlay(ResourceId(), CompType::Typeless, DebugOverlay::NoOverlay, 0, + RenderOverlay(ResourceId(), CompType::Typeless, FloatVector(), DebugOverlay::NoOverlay, 0, std::vector()); break; case eReplayProxy_PixelHistory: diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 8fa68aa98..4ff2988f6 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -505,7 +505,7 @@ public: uint32_t viewID, MeshDataStage stage); IMPLEMENT_FUNCTION_PROXIED(ResourceId, RenderOverlay, ResourceId texid, CompType typeHint, - DebugOverlay overlay, uint32_t eventId, + FloatVector clearCol, DebugOverlay overlay, uint32_t eventId, const std::vector &passEvents); IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetShaderEntryPoints, ResourceId shader); diff --git a/renderdoc/driver/d3d11/d3d11_overlay.cpp b/renderdoc/driver/d3d11/d3d11_overlay.cpp index da0159113..4540b8ba0 100644 --- a/renderdoc/driver/d3d11/d3d11_overlay.cpp +++ b/renderdoc/driver/d3d11/d3d11_overlay.cpp @@ -39,8 +39,9 @@ #include "data/hlsl/hlsl_cbuffers.h" -ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) +ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) { TextureShaderDetails details = GetDebugManager()->GetShaderDetails(texid, typeHint, false); @@ -607,7 +608,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug for(size_t i = 0; i < ARRAY_COUNT(state.OM.RenderTargets); i++) if(state.OM.RenderTargets[i]) - m_pImmediateContext->ClearRenderTargetView(state.OM.RenderTargets[i], black); + m_pImmediateContext->ClearRenderTargetView(state.OM.RenderTargets[i], &clearCol.x); for(size_t i = 0; i < events.size(); i++) { diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 19394fea4..dc7794b6b 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -234,8 +234,9 @@ 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 typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents); + ResourceId RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents); void BuildCustomShader(ShaderEncoding sourceEncoding, bytebuf source, const std::string &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index e3a6497d9..bcaa2c2ed 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -267,8 +267,9 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback D3D12RenderState m_PrevState; }; -ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) +ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) { ID3D12Resource *resource = WrappedID3D12Resource1::GetList()[texid]; @@ -738,7 +739,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, CompType typeHint, Debug if(desc.GetResResourceId() != ResourceId()) Unwrap(list)->ClearRenderTargetView(Unwrap(GetDebugManager()->GetTempDescriptor(desc)), - black, 0, NULL); + &clearCol.x, 0, NULL); } list->Close(); diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 2a9a44995..970143c08 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -195,8 +195,9 @@ 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 typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents); + ResourceId RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents); void BuildCustomShader(ShaderEncoding sourceEncoding, bytebuf source, const std::string &entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, diff --git a/renderdoc/driver/gl/gl_overlay.cpp b/renderdoc/driver/gl/gl_overlay.cpp index e2e69ff8b..103446b2f 100644 --- a/renderdoc/driver/gl/gl_overlay.cpp +++ b/renderdoc/driver/gl/gl_overlay.cpp @@ -228,8 +228,9 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag return HasSPIRVShaders; } -ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) +ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) { WrappedOpenGL &drv = *m_pDriver; @@ -933,9 +934,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOve rs.ApplyState(&drv); } - float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; for(int i = 0; i < 8; i++) - drv.glClearBufferfv(eGL_COLOR, i, black); + drv.glClearBufferfv(eGL_COLOR, i, &clearCol.x); for(size_t i = 0; i < events.size(); i++) { diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index cc1e70bb2..bb8180460 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -211,7 +211,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 typeHint, DebugOverlay overlay, uint32_t eventId, + ResourceId RenderOverlay(ResourceId id, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, const std::vector &passEvents); ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, uint32_t arrayIdx, uint32_t sampleIdx, CompType typeHint); diff --git a/renderdoc/driver/vulkan/vk_overlay.cpp b/renderdoc/driver/vulkan/vk_overlay.cpp index c862eb7df..969afb2ba 100644 --- a/renderdoc/driver/vulkan/vk_overlay.cpp +++ b/renderdoc/driver/vulkan/vk_overlay.cpp @@ -391,8 +391,9 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const DrawcallDescription *dr indexCount = (uint32_t)patchedIndices.size(); } -ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) +ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) { const VkDevDispatchTable *vt = ObjDisp(m_Device); @@ -648,7 +649,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Debu else if(overlay == DebugOverlay::Drawcall || overlay == DebugOverlay::Wireframe) { float highlightCol[] = {0.8f, 0.1f, 0.8f, 1.0f}; - float clearCol[] = {0.0f, 0.0f, 0.0f, 0.5f}; + float bgclearCol[] = {0.0f, 0.0f, 0.0f, 0.5f}; if(overlay == DebugOverlay::Wireframe) { @@ -656,10 +657,10 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Debu highlightCol[1] = 1.0f; highlightCol[2] = 0.0f; - clearCol[0] = 200 / 255.0f; - clearCol[1] = 1.0f; - clearCol[2] = 0.0f; - clearCol[3] = 0.0f; + bgclearCol[0] = 200 / 255.0f; + bgclearCol[1] = 1.0f; + bgclearCol[2] = 0.0f; + bgclearCol[3] = 0.0f; } VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -676,7 +677,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Debu DoPipelineBarrier(cmd, 1, &barrier); vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - (VkClearColorValue *)clearCol, 1, &subresourceRange); + (VkClearColorValue *)bgclearCol, 1, &subresourceRange); std::swap(barrier.oldLayout, barrier.newLayout); std::swap(barrier.srcAccessMask, barrier.dstAccessMask); @@ -1589,7 +1590,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Debu m_pDriver->m_RenderState.BeginRenderPassAndApplyState(cmd, VulkanRenderState::BindGraphics); - VkClearAttachment blackclear = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {}}; + VkClearAttachment clearatt = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {}}; + memcpy(clearatt.clearValue.color.float32, &clearCol.x, + sizeof(clearatt.clearValue.color.float32)); std::vector atts; VulkanCreationInfo::Framebuffer &fb = @@ -1600,8 +1603,8 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Debu for(size_t i = 0; i < rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments.size(); i++) { - blackclear.colorAttachment = (uint32_t)i; - atts.push_back(blackclear); + clearatt.colorAttachment = (uint32_t)i; + atts.push_back(clearatt); } VkClearRect rect = { diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index a0fbbac35..7aeecc2cd 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -351,8 +351,9 @@ 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 typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents); + ResourceId RenderOverlay(ResourceId cfg, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents); ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, uint32_t arrayIdx, uint32_t sampleIdx, CompType typeHint); diff --git a/renderdoc/maths/formatpacking.h b/renderdoc/maths/formatpacking.h index 644ad2a58..14fbfb9ba 100644 --- a/renderdoc/maths/formatpacking.h +++ b/renderdoc/maths/formatpacking.h @@ -183,6 +183,19 @@ inline Vec4f ConvertSRGBToLinear(Vec4f srgbF) ConvertSRGBToLinear(srgbF.z), srgbF.w); } +inline float ConvertLinearToSRGB(float linear) +{ + if(linear <= 0.0031308f) + return 12.92f * linear; + + if(linear < 0.0f) + linear = 0.0f; + else if(linear > 1.0f) + linear = 1.0f; + + return 1.055f * powf(linear, 1.0f / 2.4f) - 0.055f; +} + struct ResourceFormat; float ConvertComponent(const ResourceFormat &fmt, const byte *data); diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index d56a9393a..9a0a88233 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -163,8 +163,9 @@ public: virtual ShaderDebugTrace DebugThread(uint32_t eventId, const uint32_t groupid[3], const uint32_t threadid[3]) = 0; - virtual ResourceId RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventId, const std::vector &passEvents) = 0; + virtual ResourceId RenderOverlay(ResourceId texid, CompType typeHint, FloatVector clearCol, + DebugOverlay overlay, uint32_t eventId, + const std::vector &passEvents) = 0; virtual bool IsRenderOutput(ResourceId id) = 0; diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index eb41ffed8..c1a92b4b6 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -24,6 +24,7 @@ ******************************************************************************/ #include "common/common.h" +#include "maths/formatpacking.h" #include "maths/matrix.h" #include "strings/string_utils.h" #include "replay_controller.h" @@ -164,11 +165,13 @@ void ReplayOutput::SetTextureDisplay(const TextureDisplay &o) { CHECK_REPLAY_THREAD(); + bool wasClearBeforeDraw = (m_RenderData.texDisplay.overlay == DebugOverlay::ClearBeforeDraw || + m_RenderData.texDisplay.overlay == DebugOverlay::ClearBeforePass); + if(o.overlay != m_RenderData.texDisplay.overlay || o.typeHint != m_RenderData.texDisplay.typeHint || o.resourceId != m_RenderData.texDisplay.resourceId) { - if(m_RenderData.texDisplay.overlay == DebugOverlay::ClearBeforeDraw || - m_RenderData.texDisplay.overlay == DebugOverlay::ClearBeforePass) + if(wasClearBeforeDraw) { // by necessity these overlays modify the actual texture, not an // independent overlay texture. So if we disable them, we must @@ -177,6 +180,8 @@ void ReplayOutput::SetTextureDisplay(const TextureDisplay &o) } m_OverlayDirty = true; } + if(wasClearBeforeDraw && o.backgroundColor != m_RenderData.texDisplay.backgroundColor) + m_OverlayDirty = true; m_RenderData.texDisplay = o; m_MainOutput.dirty = true; } @@ -252,9 +257,15 @@ void ReplayOutput::RefreshOverlay() { if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.resourceId)) { + FloatVector f = m_RenderData.texDisplay.backgroundColor; + + f.x = ConvertLinearToSRGB(f.x); + f.y = ConvertLinearToSRGB(f.y); + f.z = ConvertLinearToSRGB(f.z); + m_OverlayResourceId = m_pDevice->RenderOverlay( - m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId), - m_RenderData.texDisplay.typeHint, m_RenderData.texDisplay.overlay, m_EventID, passEvents); + m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId), m_RenderData.texDisplay.typeHint, + f, m_RenderData.texDisplay.overlay, m_EventID, passEvents); m_OverlayDirty = false; } else