From 89d44a5f60773d83d4ecb92572bcc0722efb96ad Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Fri, 20 May 2022 16:31:54 +0100 Subject: [PATCH] GS: Offset interlace when upscaling --- bin/resources/shaders/dx11/interlace.fx | 7 ++++--- bin/resources/shaders/opengl/interlace.glsl | 5 ++--- bin/resources/shaders/vulkan/interlace.glsl | 5 ++--- pcsx2/GS/Renderers/Common/GSDevice.cpp | 3 ++- pcsx2/GS/Renderers/Common/GSDevice.h | 3 +-- pcsx2/GS/Renderers/Common/GSRenderer.cpp | 7 +++++-- pcsx2/GS/Renderers/DX11/GSDevice11.cpp | 1 - pcsx2/GS/Renderers/DX12/GSDevice12.cpp | 1 - pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp | 2 -- pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp | 1 - 10 files changed, 16 insertions(+), 19 deletions(-) diff --git a/bin/resources/shaders/dx11/interlace.fx b/bin/resources/shaders/dx11/interlace.fx index f74892c371..825751b659 100644 --- a/bin/resources/shaders/dx11/interlace.fx +++ b/bin/resources/shaders/dx11/interlace.fx @@ -6,7 +6,6 @@ SamplerState Sampler; cbuffer cb0 { float2 ZrH; - float hH; }; struct PS_INPUT @@ -17,14 +16,16 @@ struct PS_INPUT float4 ps_main0(PS_INPUT input) : SV_Target0 { - clip(frac(input.t.y * hH) - 0.5); + if ((int(input.p.y) & 1) == 0) + discard; return Texture.Sample(Sampler, input.t); } float4 ps_main1(PS_INPUT input) : SV_Target0 { - clip(0.5 - frac(input.t.y * hH)); + if ((int(input.p.y) & 1) != 0) + discard; return Texture.Sample(Sampler, input.t); } diff --git a/bin/resources/shaders/opengl/interlace.glsl b/bin/resources/shaders/opengl/interlace.glsl index d69c3077e2..46682ff7b7 100644 --- a/bin/resources/shaders/opengl/interlace.glsl +++ b/bin/resources/shaders/opengl/interlace.glsl @@ -7,14 +7,13 @@ in vec2 PSin_t; in vec4 PSin_c; uniform vec2 ZrH; -uniform float hH; layout(location = 0) out vec4 SV_Target0; // TODO ensure that clip (discard) is < 0 and not <= 0 ??? void ps_main0() { - if (fract(PSin_t.y * hH) - 0.5 < 0.0) + if ((int(gl_FragCoord.y) & 1) == 0) discard; // I'm not sure it impact us but be safe to lookup texture before conditional if // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control @@ -25,7 +24,7 @@ void ps_main0() void ps_main1() { - if (0.5 - fract(PSin_t.y * hH) < 0.0) + if ((int(gl_FragCoord.y) & 1) != 0) discard; // I'm not sure it impact us but be safe to lookup texture before conditional if // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control diff --git a/bin/resources/shaders/vulkan/interlace.glsl b/bin/resources/shaders/vulkan/interlace.glsl index d44cf021b4..1f024eb24f 100644 --- a/bin/resources/shaders/vulkan/interlace.glsl +++ b/bin/resources/shaders/vulkan/interlace.glsl @@ -21,7 +21,6 @@ layout(location = 0) out vec4 o_col0; layout(push_constant) uniform cb0 { vec2 ZrH; - float hH; }; layout(set = 0, binding = 0) uniform sampler2D samp0; @@ -30,7 +29,7 @@ layout(set = 0, binding = 0) uniform sampler2D samp0; void ps_main0() { o_col0 = texture(samp0, v_tex); - if (fract(v_tex.y * hH) - 0.5 < 0.0) + if ((int(gl_FragCoord.y) & 1) == 0) discard; } #endif @@ -39,7 +38,7 @@ void ps_main0() void ps_main1() { o_col0 = texture(samp0, v_tex); - if (0.5 - fract(v_tex.y * hH) < 0.0) + if ((int(gl_FragCoord.y) & 1) != 0) discard; } #endif diff --git a/pcsx2/GS/Renderers/Common/GSDevice.cpp b/pcsx2/GS/Renderers/Common/GSDevice.cpp index 76d0323c68..5380c55c25 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.cpp +++ b/pcsx2/GS/Renderers/Common/GSDevice.cpp @@ -358,8 +358,9 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse if (mode == 0 || mode == 2) // weave or blend { // weave first + const int offset = static_cast(yoffset) * (1 - field); - DoInterlace(m_merge, m_weavebob, field, false, 0); + DoInterlace(m_merge, m_weavebob, field, false, offset); if (mode == 2) { diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index 156272eb28..76a53749c5 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -85,8 +85,7 @@ class InterlaceConstantBuffer { public: GSVector2 ZrH; - float hH; - float _pad[1]; + float _pad[2]; InterlaceConstantBuffer() { memset(this, 0, sizeof(*this)); } }; diff --git a/pcsx2/GS/Renderers/Common/GSRenderer.cpp b/pcsx2/GS/Renderers/Common/GSRenderer.cpp index 68d8cc7f48..cc5fe60f75 100644 --- a/pcsx2/GS/Renderers/Common/GSRenderer.cpp +++ b/pcsx2/GS/Renderers/Common/GSRenderer.cpp @@ -315,6 +315,9 @@ bool GSRenderer::Merge(int field) g_gs_device->Merge(tex, src_gs_read, dst, fs, m_regs->PMODE, m_regs->EXTBUF, c); + // Offset is not compatible with scanmsk, as scanmsk renders every other line, but at x7 the interlace offset will be 7 lines + const int offset = m_scanmask_used ? 0 : (int)(tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y); + if (m_regs->SMODE2.INT && GSConfig.InterlaceMode != GSInterlaceMode::Off) { const bool scanmask = m_scanmask_used && scanmask_frame && GSConfig.InterlaceMode == GSInterlaceMode::Automatic; @@ -323,12 +326,12 @@ bool GSRenderer::Merge(int field) { constexpr int field2 = 1; constexpr int mode = 2; - g_gs_device->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y); + + g_gs_device->Interlace(ds, field ^ field2, mode, offset); } else { const int field2 = scanmask ? 0 : 1 - ((static_cast(GSConfig.InterlaceMode) - 1) & 1); - const int offset = tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y; const int mode = scanmask ? 2 : ((static_cast(GSConfig.InterlaceMode) - 1) >> 1); g_gs_device->Interlace(ds, field ^ field2, mode, offset); diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index 2c24bf95af..b6a2a41506 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -725,7 +725,6 @@ void GSDevice11::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool InterlaceConstantBuffer cb; cb.ZrH = GSVector2(0, 1.0f / s.y); - cb.hH = s.y / 2; m_ctx->UpdateSubresource(m_interlace.cb.get(), 0, nullptr, &cb, 0, 0); diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp index ad3c1558e4..7a2324563d 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp @@ -720,7 +720,6 @@ void GSDevice12::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool InterlaceConstantBuffer cb; cb.ZrH = GSVector2(0, 1.0f / s.y); - cb.hH = s.y / 2; GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", size.x, size.y, shader, linear); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index ca0a07ff40..83a02a74eb 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -436,7 +436,6 @@ bool GSDeviceOGL::Create(HostDisplay* display) return false; m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i); m_interlace.ps[i].RegisterUniform("ZrH"); - m_interlace.ps[i].RegisterUniform("hH"); } } @@ -1382,7 +1381,6 @@ void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool m_interlace.ps[shader].Bind(); m_interlace.ps[shader].Uniform2f(0, 0, 1.0f / s.y); - m_interlace.ps[shader].Uniform1f(1, s.y / 2); StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear); } diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index baf423e346..135397bf26 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -834,7 +834,6 @@ void GSDeviceVK::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool InterlaceConstantBuffer cb; cb.ZrH = GSVector2(0, 1.0f / s.y); - cb.hH = s.y / 2; GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", size.x, size.y, shader, linear);