GS: Offset interlace when upscaling

This commit is contained in:
refractionpcsx2 2022-05-20 16:31:54 +01:00
parent aa47018197
commit 89d44a5f60
10 changed files with 16 additions and 19 deletions

View File

@ -6,7 +6,6 @@ SamplerState Sampler;
cbuffer cb0 cbuffer cb0
{ {
float2 ZrH; float2 ZrH;
float hH;
}; };
struct PS_INPUT struct PS_INPUT
@ -17,14 +16,16 @@ struct PS_INPUT
float4 ps_main0(PS_INPUT input) : SV_Target0 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); return Texture.Sample(Sampler, input.t);
} }
float4 ps_main1(PS_INPUT input) : SV_Target0 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); return Texture.Sample(Sampler, input.t);
} }

View File

@ -7,14 +7,13 @@ in vec2 PSin_t;
in vec4 PSin_c; in vec4 PSin_c;
uniform vec2 ZrH; uniform vec2 ZrH;
uniform float hH;
layout(location = 0) out vec4 SV_Target0; layout(location = 0) out vec4 SV_Target0;
// TODO ensure that clip (discard) is < 0 and not <= 0 ??? // TODO ensure that clip (discard) is < 0 and not <= 0 ???
void ps_main0() void ps_main0()
{ {
if (fract(PSin_t.y * hH) - 0.5 < 0.0) if ((int(gl_FragCoord.y) & 1) == 0)
discard; discard;
// I'm not sure it impact us but be safe to lookup texture before conditional if // 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 // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control
@ -25,7 +24,7 @@ void ps_main0()
void ps_main1() void ps_main1()
{ {
if (0.5 - fract(PSin_t.y * hH) < 0.0) if ((int(gl_FragCoord.y) & 1) != 0)
discard; discard;
// I'm not sure it impact us but be safe to lookup texture before conditional if // 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 // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control

View File

@ -21,7 +21,6 @@ layout(location = 0) out vec4 o_col0;
layout(push_constant) uniform cb0 layout(push_constant) uniform cb0
{ {
vec2 ZrH; vec2 ZrH;
float hH;
}; };
layout(set = 0, binding = 0) uniform sampler2D samp0; layout(set = 0, binding = 0) uniform sampler2D samp0;
@ -30,7 +29,7 @@ layout(set = 0, binding = 0) uniform sampler2D samp0;
void ps_main0() void ps_main0()
{ {
o_col0 = texture(samp0, v_tex); o_col0 = texture(samp0, v_tex);
if (fract(v_tex.y * hH) - 0.5 < 0.0) if ((int(gl_FragCoord.y) & 1) == 0)
discard; discard;
} }
#endif #endif
@ -39,7 +38,7 @@ void ps_main0()
void ps_main1() void ps_main1()
{ {
o_col0 = texture(samp0, v_tex); o_col0 = texture(samp0, v_tex);
if (0.5 - fract(v_tex.y * hH) < 0.0) if ((int(gl_FragCoord.y) & 1) != 0)
discard; discard;
} }
#endif #endif

View File

@ -358,8 +358,9 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse
if (mode == 0 || mode == 2) // weave or blend if (mode == 0 || mode == 2) // weave or blend
{ {
// weave first // weave first
const int offset = static_cast<int>(yoffset) * (1 - field);
DoInterlace(m_merge, m_weavebob, field, false, 0); DoInterlace(m_merge, m_weavebob, field, false, offset);
if (mode == 2) if (mode == 2)
{ {

View File

@ -85,8 +85,7 @@ class InterlaceConstantBuffer
{ {
public: public:
GSVector2 ZrH; GSVector2 ZrH;
float hH; float _pad[2];
float _pad[1];
InterlaceConstantBuffer() { memset(this, 0, sizeof(*this)); } InterlaceConstantBuffer() { memset(this, 0, sizeof(*this)); }
}; };

View File

@ -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); 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) if (m_regs->SMODE2.INT && GSConfig.InterlaceMode != GSInterlaceMode::Off)
{ {
const bool scanmask = m_scanmask_used && scanmask_frame && GSConfig.InterlaceMode == GSInterlaceMode::Automatic; 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 field2 = 1;
constexpr int mode = 2; 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 else
{ {
const int field2 = scanmask ? 0 : 1 - ((static_cast<int>(GSConfig.InterlaceMode) - 1) & 1); const int field2 = scanmask ? 0 : 1 - ((static_cast<int>(GSConfig.InterlaceMode) - 1) & 1);
const int offset = tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y;
const int mode = scanmask ? 2 : ((static_cast<int>(GSConfig.InterlaceMode) - 1) >> 1); const int mode = scanmask ? 2 : ((static_cast<int>(GSConfig.InterlaceMode) - 1) >> 1);
g_gs_device->Interlace(ds, field ^ field2, mode, offset); g_gs_device->Interlace(ds, field ^ field2, mode, offset);

View File

@ -725,7 +725,6 @@ void GSDevice11::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool
InterlaceConstantBuffer cb; InterlaceConstantBuffer cb;
cb.ZrH = GSVector2(0, 1.0f / s.y); 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); m_ctx->UpdateSubresource(m_interlace.cb.get(), 0, nullptr, &cb, 0, 0);

View File

@ -720,7 +720,6 @@ void GSDevice12::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool
InterlaceConstantBuffer cb; InterlaceConstantBuffer cb;
cb.ZrH = GSVector2(0, 1.0f / s.y); 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); GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", size.x, size.y, shader, linear);

View File

@ -436,7 +436,6 @@ bool GSDeviceOGL::Create(HostDisplay* display)
return false; return false;
m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i); m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i);
m_interlace.ps[i].RegisterUniform("ZrH"); 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].Bind();
m_interlace.ps[shader].Uniform2f(0, 0, 1.0f / s.y); 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); StretchRect(sTex, sRect, dTex, dRect, m_interlace.ps[shader], linear);
} }

View File

@ -834,7 +834,6 @@ void GSDeviceVK::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool
InterlaceConstantBuffer cb; InterlaceConstantBuffer cb;
cb.ZrH = GSVector2(0, 1.0f / s.y); 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); GL_PUSH("DoInterlace %dx%d Shader:%d Linear:%d", size.x, size.y, shader, linear);