diff --git a/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp index ef234e5bc..d387c5589 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list1_wrap.cpp @@ -543,14 +543,19 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetViewInstanceMask(SerialiserT m_Cmd->m_LastCmdListID = GetResourceManager()->GetOriginalID(GetResID(pCommandList)); + bool stateUpdate = false; + if(IsActiveReplaying(m_State)) { if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID)) { Unwrap1(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID))->SetViewInstanceMask(Mask); - if(m_Cmd->IsPartialCmdList(m_Cmd->m_LastCmdListID)) - m_Cmd->m_RenderState.viewInstMask = Mask; + stateUpdate = true; + } + else if(!m_Cmd->IsPartialCmdList(m_Cmd->m_LastCmdListID)) + { + stateUpdate = true; } } else @@ -558,8 +563,11 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetViewInstanceMask(SerialiserT Unwrap1(pCommandList)->SetViewInstanceMask(Mask); GetCrackedList1()->SetViewInstanceMask(Mask); - m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state.viewInstMask = Mask; + stateUpdate = true; } + + if(stateUpdate) + m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state.viewInstMask = Mask; } return true; diff --git a/renderdoc/driver/d3d12/d3d12_commands.h b/renderdoc/driver/d3d12/d3d12_commands.h index 10ef51107..2c7f6094b 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.h +++ b/renderdoc/driver/d3d12/d3d12_commands.h @@ -241,6 +241,11 @@ struct D3D12CommandData D3D12RenderState m_RenderState; + D3D12RenderState &GetCurRenderState() + { + return m_LastCmdListID == ResourceId() ? m_RenderState + : m_BakedCmdListInfo[m_LastCmdListID].state; + } enum PartialReplayIndex { Primary, diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 4d30183b9..2b7621496 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -3470,6 +3470,12 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, cmd.m_RenderState.m_ResourceManager = GetResourceManager(); cmd.m_RenderState.m_DebugManager = m_Replay->GetDebugManager(); } + else + { + // Copy the state in case m_RenderState was modified externally for the partial replay. + cmd.m_BakedCmdListInfo[cmd.m_Partial[D3D12CommandData::Primary].partialParent].state = + cmd.m_RenderState; + } // we'll need our own command list if we're replaying just a subsection // of events within a single command list record - always if it's only @@ -3506,9 +3512,8 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, cmd.m_OutsideCmdList = NULL; } - if(!partial) - cmd.m_RenderState = - cmd.m_BakedCmdListInfo[cmd.m_Partial[D3D12CommandData::Primary].partialParent].state; + cmd.m_RenderState = + cmd.m_BakedCmdListInfo[cmd.m_Partial[D3D12CommandData::Primary].partialParent].state; #if ENABLED(SINGLE_FLUSH_VALIDATE) FlushLists(true); diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index ad2139f96..9c009432e 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -66,7 +66,7 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback // and substitute our quad calculation fragment shader that writes to a storage image // that is bound in a new root signature element. - D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; + D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->GetCurRenderState(); m_PrevState = rs; // check cache first @@ -181,10 +181,10 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback return false; // restore the render state and go ahead with the real draw - m_pDevice->GetQueue()->GetCommandData()->m_RenderState = m_PrevState; + m_pDevice->GetQueue()->GetCommandData()->GetCurRenderState() = m_PrevState; RDCASSERT(cmd); - m_pDevice->GetQueue()->GetCommandData()->m_RenderState.ApplyState(m_pDevice, cmd); + m_pDevice->GetQueue()->GetCommandData()->GetCurRenderState().ApplyState(m_pDevice, cmd); return true; } diff --git a/renderdoc/driver/d3d12/d3d12_postvs.cpp b/renderdoc/driver/d3d12/d3d12_postvs.cpp index 10262f719..7fdf4d1f6 100644 --- a/renderdoc/driver/d3d12/d3d12_postvs.cpp +++ b/renderdoc/driver/d3d12/d3d12_postvs.cpp @@ -173,7 +173,7 @@ void D3D12Replay::InitPostVSBuffers(uint32_t eventId) D3D12MarkerRegion postvs(m_pDevice->GetQueue(), StringFormat::Fmt("PostVS for %u", eventId)); D3D12CommandData *cmd = m_pDevice->GetQueue()->GetCommandData(); - const D3D12RenderState &rs = cmd->m_RenderState; + const D3D12RenderState &rs = cmd->GetCurRenderState(); if(rs.pipe == ResourceId()) return; diff --git a/util/test/rdtest/shared/Overlay_Test.py b/util/test/rdtest/shared/Overlay_Test.py index 817ffc464..de5e4df72 100644 --- a/util/test/rdtest/shared/Overlay_Test.py +++ b/util/test/rdtest/shared/Overlay_Test.py @@ -362,6 +362,8 @@ class Overlay_Test(rdtest.TestCase): rdtest.log.success("Picked pixels are as expected for {}".format(str(overlay))) + rdtest.log.success("All normal overlays are as expected") + # Now check clear-before-X by hand, for colour and for depth depth_tex: rd.ResourceId = pipe.GetDepthTarget().resourceId @@ -387,6 +389,8 @@ class Overlay_Test(rdtest.TestCase): self.check_pixel_value(depth_tex, 250, 250, [0.95, 0.0/255.0, 0.0, 1.0], eps=eps) self.check_pixel_value(depth_tex, 50, 50, [1.0, 0.0/255.0, 0.0, 1.0], eps=eps) + rdtest.log.success("Colour and depth at end are correct") + # Check clear before pass tex.resourceId = col_tex tex.overlay = rd.DebugOverlay.ClearBeforePass