GS: Sample LOD 0 explicitly in interlace shaders

Can't use normal sampling because the derivates are undefined in
non-uniform control flow (in MAD).
This commit is contained in:
Stenzek 2023-03-19 16:39:57 +10:00 committed by refractionpcsx2
parent 76e8bfe42f
commit b26acad721
5 changed files with 56 additions and 52 deletions

View File

@ -23,7 +23,7 @@ float4 ps_main0(PS_INPUT input) : SV_Target0
const int vpos = int(input.p.y); // vertical position of destination texture
if ((vpos & 1) == field)
return Texture.Sample(Sampler, input.t);
return Texture.SampleLevel(Sampler, input.t, 0);
else
discard;
@ -34,7 +34,7 @@ float4 ps_main0(PS_INPUT input) : SV_Target0
// Bob shader
float4 ps_main1(PS_INPUT input) : SV_Target0
{
return Texture.Sample(Sampler, input.t);
return Texture.SampleLevel(Sampler, input.t, 0);
}
@ -42,9 +42,9 @@ float4 ps_main1(PS_INPUT input) : SV_Target0
float4 ps_main2(PS_INPUT input) : SV_Target0
{
float2 vstep = float2(0.0f, ZrH.y);
float4 c0 = Texture.Sample(Sampler, input.t - vstep);
float4 c1 = Texture.Sample(Sampler, input.t);
float4 c2 = Texture.Sample(Sampler, input.t + vstep);
float4 c0 = Texture.SampleLevel(Sampler, input.t - vstep, 0);
float4 c1 = Texture.SampleLevel(Sampler, input.t, 0);
float4 c2 = Texture.SampleLevel(Sampler, input.t + vstep, 0);
return (c0 + c1 * 2 + c2) / 4;
}
@ -74,7 +74,7 @@ float4 ps_main3(PS_INPUT input) : SV_Target0
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
return Texture.Sample(Sampler, iptr);
return Texture.SampleLevel(Sampler, iptr, 0);
else
discard;
@ -133,13 +133,13 @@ float4 ps_main4(PS_INPUT input) : SV_Target0
// calculating motion, only relevant for missing lines where the "center line" is pointed by p_t1
float4 hn = Texture.Sample(Sampler, p_t0 - lofs); // new high pixel
float4 cn = Texture.Sample(Sampler, p_t1); // new center pixel
float4 ln = Texture.Sample(Sampler, p_t0 + lofs); // new low pixel
float4 hn = Texture.SampleLevel(Sampler, p_t0 - lofs, 0); // new high pixel
float4 cn = Texture.SampleLevel(Sampler, p_t1, 0); // new center pixel
float4 ln = Texture.SampleLevel(Sampler, p_t0 + lofs, 0); // new low pixel
float4 ho = Texture.Sample(Sampler, p_t2 - lofs); // old high pixel
float4 co = Texture.Sample(Sampler, p_t3); // old center pixel
float4 lo = Texture.Sample(Sampler, p_t2 + lofs); // old low pixel
float4 ho = Texture.SampleLevel(Sampler, p_t2 - lofs, 0); // old high pixel
float4 co = Texture.SampleLevel(Sampler, p_t3, 0); // old center pixel
float4 lo = Texture.SampleLevel(Sampler, p_t2 + lofs, 0); // old low pixel
float3 mh = hn.rgb - ho.rgb; // high pixel motion
float3 mc = cn.rgb - co.rgb; // center pixel motion
@ -164,7 +164,7 @@ float4 ps_main4(PS_INPUT input) : SV_Target0
if ((vpos & 1) == field)
{
// output coordinate present on current field
return Texture.Sample(Sampler, p_t0);
return Texture.SampleLevel(Sampler, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{

View File

@ -19,7 +19,7 @@ void ps_main0()
int vpos = int(gl_FragCoord.y); // vertical position of destination texture
if ((vpos & 1) == field)
SV_Target0 = texture(TextureSampler, PSin_t);
SV_Target0 = textureLod(TextureSampler, PSin_t, 0);
else
discard;
}
@ -28,7 +28,7 @@ void ps_main0()
// Bob shader
void ps_main1()
{
SV_Target0 = texture(TextureSampler, PSin_t);
SV_Target0 = textureLod(TextureSampler, PSin_t, 0);
}
@ -36,9 +36,9 @@ void ps_main1()
void ps_main2()
{
vec2 vstep = vec2(0.0f, ZrH.y);
vec4 c0 = texture(TextureSampler, PSin_t - vstep);
vec4 c1 = texture(TextureSampler, PSin_t);
vec4 c2 = texture(TextureSampler, PSin_t + vstep);
vec4 c0 = textureLod(TextureSampler, PSin_t - vstep, 0);
vec4 c1 = textureLod(TextureSampler, PSin_t, 0);
vec4 c2 = textureLod(TextureSampler, PSin_t + vstep, 0);
SV_Target0 = (c0 + c1 * 2.0f + c2) / 4.0f;
}
@ -68,7 +68,7 @@ void ps_main3()
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
SV_Target0 = texture(TextureSampler, iptr);
SV_Target0 = textureLod(TextureSampler, iptr, 0);
else
discard;
}
@ -126,13 +126,13 @@ void ps_main4()
// calculating motion, only relevant for missing lines where the "center line" is pointed
// by p_t1
vec4 hn = texture(TextureSampler, p_t0 - lofs); // new high pixel
vec4 cn = texture(TextureSampler, p_t1); // new center pixel
vec4 ln = texture(TextureSampler, p_t0 + lofs); // new low pixel
vec4 hn = textureLod(TextureSampler, p_t0 - lofs, 0); // new high pixel
vec4 cn = textureLod(TextureSampler, p_t1, 0); // new center pixel
vec4 ln = textureLod(TextureSampler, p_t0 + lofs, 0); // new low pixel
vec4 ho = texture(TextureSampler, p_t2 - lofs); // old high pixel
vec4 co = texture(TextureSampler, p_t3); // old center pixel
vec4 lo = texture(TextureSampler, p_t2 + lofs); // old low pixel
vec4 ho = textureLod(TextureSampler, p_t2 - lofs, 0); // old high pixel
vec4 co = textureLod(TextureSampler, p_t3, 0); // old center pixel
vec4 lo = textureLod(TextureSampler, p_t2 + lofs, 0); // old low pixel
vec3 mh = hn.rgb - ho.rgb; // high pixel motion
vec3 mc = cn.rgb - co.rgb; // center pixel motion
@ -158,7 +158,7 @@ void ps_main4()
if ((vpos & 1) == field)
{
// output coordinate present on current field
SV_Target0 = texture(TextureSampler, p_t0);
SV_Target0 = textureLod(TextureSampler, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{

View File

@ -35,7 +35,7 @@ void ps_main0()
const int vpos = int(gl_FragCoord.y); // vertical position of destination texture
if ((vpos & 1) == field)
o_col0 = texture(samp0, v_tex);
o_col0 = textureLod(samp0, v_tex, 0);
else
discard;
}
@ -46,7 +46,7 @@ void ps_main0()
#ifdef ps_main1
void ps_main1()
{
o_col0 = texture(samp0, v_tex);
o_col0 = textureLod(samp0, v_tex, 0);
}
#endif
@ -56,9 +56,9 @@ void ps_main1()
void ps_main2()
{
vec2 vstep = vec2(0.0f, ZrH.y);
vec4 c0 = texture(samp0, v_tex - vstep);
vec4 c1 = texture(samp0, v_tex);
vec4 c2 = texture(samp0, v_tex + vstep);
vec4 c0 = textureLod(samp0, v_tex - vstep, 0);
vec4 c1 = textureLod(samp0, v_tex, 0);
vec4 c2 = textureLod(samp0, v_tex + vstep, 0);
o_col0 = (c0 + c1 * 2.0f + c2) / 4.0f;
}
@ -90,7 +90,7 @@ void ps_main3()
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
o_col0 = texture(samp0, iptr);
o_col0 = textureLod(samp0, iptr, 0);
else
discard;
}
@ -150,13 +150,13 @@ void ps_main4()
// calculating motion, only relevant for missing lines where the "center line" is pointed by p_t1
vec4 hn = texture(samp0, p_t0 - lofs); // new high pixel
vec4 cn = texture(samp0, p_t1); // new center pixel
vec4 ln = texture(samp0, p_t0 + lofs); // new low pixel
vec4 hn = textureLod(samp0, p_t0 - lofs, 0); // new high pixel
vec4 cn = textureLod(samp0, p_t1, 0); // new center pixel
vec4 ln = textureLod(samp0, p_t0 + lofs, 0); // new low pixel
vec4 ho = texture(samp0, p_t2 - lofs); // old high pixel
vec4 co = texture(samp0, p_t3); // old center pixel
vec4 lo = texture(samp0, p_t2 + lofs); // old low pixel
vec4 ho = textureLod(samp0, p_t2 - lofs, 0); // old high pixel
vec4 co = textureLod(samp0, p_t3, 0); // old center pixel
vec4 lo = textureLod(samp0, p_t2 + lofs, 0); // old low pixel
vec3 mh = hn.rgb - ho.rgb; // high pixel motion
vec3 mc = cn.rgb - co.rgb; // center pixel motion
@ -181,7 +181,7 @@ void ps_main4()
if ((vpos & 1) == field) // output coordinate present on current field
{
// output coordinate present on current field
o_col0 = texture(samp0, p_t0);
o_col0 = textureLod(samp0, p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{

View File

@ -33,6 +33,10 @@ struct ConvertPSRes
{
return texture.sample(s, coord);
}
float4 sample_level(float2 coord, float lod)
{
return texture.sample(s, coord, level(lod));
}
};
struct ConvertPSDepthRes

View File

@ -27,7 +27,7 @@ fragment float4 ps_interlace0(ConvertShaderData data [[stage_in]], ConvertPSRes
const int vpos = int(data.p.y); // vertical position of destination texture
if ((vpos & 1) == field)
return res.sample(data.t);
return res.sample_level(data.t, 0);
else
discard_fragment();
@ -38,7 +38,7 @@ fragment float4 ps_interlace0(ConvertShaderData data [[stage_in]], ConvertPSRes
// Bob shader
fragment float4 ps_interlace1(ConvertShaderData data [[stage_in]], ConvertPSRes res)
{
return res.sample(data.t);
return res.sample_level(data.t);
}
@ -47,9 +47,9 @@ fragment float4 ps_interlace2(ConvertShaderData data [[stage_in]], ConvertPSRes
constant GSMTLInterlacePSUniform& uniform [[buffer(GSMTLBufferIndexUniforms)]])
{
float2 vstep = float2(0.0f, uniform.ZrH.y);
float4 c0 = res.sample(data.t - vstep);
float4 c1 = res.sample(data.t);
float4 c2 = res.sample(data.t + vstep);
float4 c0 = res.sample_level(data.t - vstep, 0);
float4 c1 = res.sample_level(data.t, 0);
float4 c2 = res.sample_level(data.t + vstep, 0);
return (c0 + c1 * 2.f + c2) / 4.f;
}
@ -79,7 +79,7 @@ fragment float4 ps_interlace3(ConvertShaderData data [[stage_in]], ConvertPSRes
// if the index of current destination line belongs to the current fiels we update it, otherwise
// we leave the old line in the destination buffer
if ((optr.y >= 0.0f) && (optr.y < 0.5f) && ((vpos & 1) == field))
return res.sample(iptr);
return res.sample_level(iptr, 0);
else
discard_fragment();
@ -137,13 +137,13 @@ fragment float4 ps_interlace4(ConvertShaderData data [[stage_in]], ConvertPSRes
// calculating motion, only relevant for missing lines where the "center line" is pointed by p_t1
float4 hn = res.sample(p_t0 - lofs); // new high pixel
float4 cn = res.sample(p_t1); // new center pixel
float4 ln = res.sample(p_t0 + lofs); // new low pixel
float4 hn = res.sample_level(p_t0 - lofs, 0); // new high pixel
float4 cn = res.sample_level(p_t1, 0); // new center pixel
float4 ln = res.sample_level(p_t0 + lofs, 0); // new low pixel
float4 ho = res.sample(p_t2 - lofs); // old high pixel
float4 co = res.sample(p_t3); // old center pixel
float4 lo = res.sample(p_t2 + lofs); // old low pixel
float4 ho = res.sample_level(p_t2 - lofs, 0); // old high pixel
float4 co = res.sample_level(p_t3, 0); // old center pixel
float4 lo = res.sample_level(p_t2 + lofs, 0); // old low pixel
float3 mh = hn.rgb - ho.rgb;
float3 mc = cn.rgb - co.rgb;
@ -168,7 +168,7 @@ fragment float4 ps_interlace4(ConvertShaderData data [[stage_in]], ConvertPSRes
if ((vpos & 1) == field)
{
// output coordinate present on current field
return res.sample(p_t0);
return res.sample_level(p_t0, 0);
}
else if ((iptr.y > 0.5f - lofs.y) || (iptr.y < 0.0 + lofs.y))
{