From 085699f9de0f393194d10c3cdf74d60d440ed697 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 31 Mar 2024 17:31:58 +1000 Subject: [PATCH] GS/Vulkan: Fix incorrect clear colour for fast colclip --- pcsx2/GS/Renderers/DX12/GSDevice12.cpp | 29 +++++++++++++++--------- pcsx2/GS/Renderers/DX12/GSDevice12.h | 2 +- pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp | 14 +++++++++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp index d32f13c9312c4..7355aa1694738 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp @@ -1600,14 +1600,14 @@ void GSDevice12::BeginRenderPassForStretchRect( BeginRenderPass(load_op, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - dTex->GetClearColor()); + dTex->GetUNormClearColor()); } else { BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, load_op, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - 0, dTex->GetClearDepth()); + GSVector4::zero(), dTex->GetClearDepth()); } } @@ -1724,7 +1724,7 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, - D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, c); + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, GSVector4::unorm8(c)); SetUtilityRootSignature(); SetPipeline(m_convert[static_cast(ShaderConvert::COPY)].get()); DrawStretchRect(sRect[1], PMODE.SLBG ? dRect[2] : dRect[1], dsize); @@ -1766,7 +1766,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, OMSetRenderTargets(dTex, nullptr, darea); BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, c); + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, + GSVector4::unorm8(c)); dTex->SetState(GSTexture::State::Dirty); } else if (!InRenderPass()) @@ -3370,7 +3371,7 @@ bool GSDevice12::InRenderPass() void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE color_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE depth_begin, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin, - D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end, u32 clear_color, float clear_depth, u8 clear_stencil) + D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end, GSVector4 clear_color, float clear_depth, u8 clear_stencil) { if (m_in_render_pass) EndRenderPass(); @@ -3389,8 +3390,7 @@ void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_b { LookupNativeFormat(m_current_render_target->GetFormat(), nullptr, &rt.BeginningAccess.Clear.ClearValue.Format, nullptr, nullptr); - GSVector4::store(rt.BeginningAccess.Clear.ClearValue.Color, - GSVector4::unorm8(clear_color)); + GSVector4::store(rt.BeginningAccess.Clear.ClearValue.Color, clear_color); } } @@ -3685,7 +3685,8 @@ void GSDevice12::SetupDATE(GSTexture* rt, GSTexture* ds, SetDATM datm, const GSV SetStencilRef(1); BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, - D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, 0, 0.0f, 0); + D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, + GSVector4::zero(), 0.0f, 0); if (ApplyUtilityState()) DrawPrimitive(); @@ -3720,7 +3721,7 @@ GSTexture12* GSDevice12::SetupPrimitiveTrackingDATE(GSHWDrawConfig& config, Pipe D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, config.ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - 0, config.ds ? config.ds->GetClearDepth() : 0.0f); + GSVector4::zero(), config.ds ? config.ds->GetClearDepth() : 0.0f); // draw the quad to prefill the image const GSVector4 src = GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(); @@ -3902,6 +3903,12 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) // Begin render pass if new target or out of the area. if (!m_in_render_pass) { + GSVector4 clear_color = draw_rt ? draw_rt->GetUNormClearColor() : GSVector4::zero(); + if (pipe.ps.hdr) + { + // Denormalize clear color for HDR. + clear_color *= GSVector4::cxpr(255.0f / 65535.0f, 255.0f / 65535.0f, 255.0f / 65535.0f, 1.0f); + } BeginRenderPass(GetLoadOpForTexture(draw_rt), draw_rt ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, GetLoadOpForTexture(draw_ds), @@ -3910,7 +3917,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, stencil_DATE ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - draw_rt ? draw_rt->GetClearColor() : 0, draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1); + clear_color, draw_ds ? draw_ds->GetClearDepth() : 0.0f, 1); } // rt -> hdr blit if enabled @@ -3975,7 +3982,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) GetLoadOpForTexture(draw_ds), draw_ds ? D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE : D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - draw_rt->GetClearColor(), 0.0f, 0); + draw_rt->GetUNormClearColor(), 0.0f, 0); const GSVector4 sRect(GSVector4(render_area) / GSVector4(rtsize.x, rtsize.y).xyxy()); SetPipeline(m_hdr_finish_pipelines[pipe.ds].get()); diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.h b/pcsx2/GS/Renderers/DX12/GSDevice12.h index ce21b8df1f11b..49abdf47b06f3 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.h +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.h @@ -510,7 +510,7 @@ class GSDevice12 final : public GSDevice D3D12_RENDER_PASS_ENDING_ACCESS_TYPE depth_end = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE stencil_begin = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE stencil_end = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS, - const u32 clear_color = 0, float clear_depth = 0.0f, u8 clear_stencil = 0); + GSVector4 clear_color = GSVector4::zero(), float clear_depth = 0.0f, u8 clear_stencil = 0); void EndRenderPass(); void SetViewport(const D3D12_VIEWPORT& viewport); diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index 617dd345f1900..80a69379f894c 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -5793,7 +5793,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil, pipe.IsRTFeedbackLoop(), pipe.IsTestingAndSamplingDepth(), rt_op, ds_op); const bool is_clearing_rt = (rt_op == VK_ATTACHMENT_LOAD_OP_CLEAR || ds_op == VK_ATTACHMENT_LOAD_OP_CLEAR); - const GSVector4i render_area = GSVector4i::loadh(rtsize); + const GSVector4i render_area = pipe.ps.hdr ? config.drawarea : GSVector4i::loadh(rtsize); if (is_clearing_rt) { @@ -5801,7 +5801,15 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) alignas(16) VkClearValue cvs[2]; u32 cv_count = 0; if (draw_rt) - GSVector4::store(&cvs[cv_count++].color, draw_rt->GetUNormClearColor()); + { + GSVector4 clear_color = draw_rt->GetUNormClearColor(); + if (pipe.ps.hdr) + { + // Denormalize clear color for HDR. + clear_color *= GSVector4::cxpr(255.0f / 65535.0f, 255.0f / 65535.0f, 255.0f / 65535.0f, 1.0f); + } + GSVector4::store(&cvs[cv_count++].color, clear_color); + } if (draw_ds) cvs[cv_count++].depthStencil = {draw_ds->GetClearDepth(), 0}; @@ -5871,7 +5879,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) // now blit the hdr texture back to the original target if (hdr_rt) { - GL_INS("Blit HDR back to RT"); + GL_PUSH("Blit HDR back to RT"); EndRenderPass(); hdr_rt->TransitionToLayout(GSTextureVK::Layout::ShaderReadOnly);