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
{
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);
}

View File

@ -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

View File

@ -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

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
{
// 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)
{

View File

@ -85,8 +85,7 @@ class InterlaceConstantBuffer
{
public:
GSVector2 ZrH;
float hH;
float _pad[1];
float _pad[2];
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);
// 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<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);
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;
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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);