GSdx-hw: Improve HW dithering (#3534)

* Improve HW dithering to stop it creating line artifacts across the screen

* Make DX dithering code OGL-like
This commit is contained in:
refractionpcsx2 2020-07-15 13:51:03 +01:00 committed by GitHub
parent e04d86ad39
commit a782e03ebf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 19 deletions

View File

@ -855,17 +855,22 @@ void ps_main()
return;
#endif
#if !SW_BLEND && PS_DITHER
#if !SW_BLEND
ps_dither(C);
// Dither matrix range is [-4,3] but positive values can cause issues when
// software blending is not used or is unavailable.
C.rgb -= 3.0;
#endif
ps_blend(C, alpha_blend);
ps_fbmask(C);
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
// SW_BLEND already deals with this so no need to do in those cases
#if !SW_BLEND && PS_DITHER && PS_DFMT == FMT_16 && PS_COLCLIP == 0
C.rgb = clamp(C.rgb, vec3(0.0f), vec3(255.0f));
C.rgb = uvec3(uvec3(C.rgb) & uvec3(0xF8));
#endif
// #if PS_HDR == 1
// Use negative value to avoid overflow of the texture (in accumulation mode)
// Note: code were initially done for an Half-Float texture. Due to overflow

View File

@ -675,14 +675,17 @@ void ps_fbmask(inout float4 C, float2 pos_xy)
void ps_dither(inout float3 C, float2 pos_xy)
{
#if PS_DITHER
#if PS_DITHER == 2
int2 fpos = int2(pos_xy);
#else
int2 fpos = int2(pos_xy / (float)PS_SCALE_FACTOR);
#endif
C += DitherMatrix[fpos.y&3][fpos.x&3];
#endif
if (PS_DITHER)
{
int2 fpos;
if (PS_DITHER == 2)
fpos = int2(pos_xy);
else
fpos = int2(pos_xy / (float)PS_SCALE_FACTOR);
C += DitherMatrix[fpos.y & 3][fpos.x & 3];
}
}
void ps_blend(inout float4 Color, float As, float2 pos_xy)
@ -769,17 +772,22 @@ PS_OUTPUT ps_main(PS_INPUT input)
if (C.a < A_one) C.a += A_one;
}
#if !SW_BLEND && PS_DITHER
ps_dither(C.rgb, input.p.xy);
// Dither matrix range is [-4,3] but positive values can cause issues when
// software blending is not used or is unavailable.
C.rgb -= 3.0;
#endif
if (!SW_BLEND)
ps_dither(C.rgb, input.p.xy);
ps_blend(C, alpha_blend, input.p.xy);
ps_fbmask(C, input.p.xy);
// When dithering the bottom 3 bits become meaningless and cause lines in the picture
// so we need to limit the color depth on dithered items
// SW_BLEND already deals with this so no need to do in those cases
if (!SW_BLEND && PS_DITHER && PS_DFMT == FMT_16 && !PS_COLCLIP)
{
C.rgb = clamp(C.rgb, (float3)0.0f, (float3)255.0f);
C.rgb = (uint3)((uint3)C.rgb & (uint3)0xF8);
}
output.c0 = C / 255.0f;
output.c1 = (float4)(alpha_blend);