diff --git a/plugins/GSdx/res/glsl/tfx_fs.glsl b/plugins/GSdx/res/glsl/tfx_fs.glsl index eac789dcd6..7cead42de9 100644 --- a/plugins/GSdx/res/glsl/tfx_fs.glsl +++ b/plugins/GSdx/res/glsl/tfx_fs.glsl @@ -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 diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index c92d769ab2..3c7e8466a5 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -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);