+ Harry, Alex
On Sat, Mar 21, 2026 at 1:29 AM Mario Kleiner <[email protected]> wrote: > > Commit d5df648ec830 ("drm/amd/display: Change dither policy for 10bpc to > round") degraded display of 12 bpc color precision output to 10 bpc sinks > by switching 10 bpc output from dithering to "truncate to 10 bpc". > > I don't find the argumentation in that commit convincing, but the > consequences highly unfortunate, especially for applications that > require effective > 10 bpc precision output of > 10 bpc framebuffers. > > The argument wasn't something strong like "there are hardware design > defects or limitations which require us to work around broken dithering > to 10 bpc", or "there are some special use cases which do require > truncation to 10 bpc", but essentially "at some point in the past we > used truncation in Polaris/Vega times and it looks like it got > inadvertently changed for Navi, so let's do that again". I couldn't find > evidence for that in the git commit logs for this. The commit message also > acknowledges that using dithering "...makes some sense for FP16... > ...but not for ARGB2101010 surfaces..." > > The problem with this is that it makes fp16 surfaces, and especially > rgba16 fixed point surfaces, less useful. These are now well > supported by Mesa 25.3 and later via OpenGL + EGL, Vulkan/WSI, and by > OSS AMDVLK Vulkan/WSI/display, and also by GNOME 50 mutter under Wayland, > and they used to provide more than 10 bpc effective precision at the > output. > > Even for 8 or 10 bpc surfaces, the color pipeline behind the framebuffer, > e.g., gamma tables, CTM, can be used for color correction and will > benefit from an effective > 10 bpc output precision via dithering, > retaining some precision that would get lost on the way through the > pipeline, e.g., due to non-linear gamma functions. > > Scientific apps rely on this for > 10 bpc display precision. Truncating > to 10 bpc, instead of dithering the pipeline internal 12 bpc precision > down to 10 bpc, causes a serious loss of precision. This also creates the > undesirable and slightly absurd situation that using a cheap monitor > with only 8 bpc input and display panel will yield roughly 12 bpc > precision via dithering from 12 -> 8 bpc, whereas investment into a > more expensive monitor with 10 bpc input and native 10 bpc display will > only yield 10 bpc, even if a fp16 or rgb16 framebuffer and/or a properly > set up color pipeline (gamma tables, CTM's etc. with more than 10 bpc out > precision) would allow effective 12 bpc precision output. > > Therefore this patch proposes reverting that commit and going back to > dithering down to 10 bpc, consistent with the behaviour for 6 bpc or 8 bpc > output. > > Successfully tested on AMD Polaris DCE 11.2 and Raven Ridge DCN 1.0 with > a native 10 bpc capable monitor, outputting a RGBA16 unorm framebuffer and > measuring resulting color precision with a photometer. No apparent visual > artifacts or problems were observed, and effective precision was measured > to be 12 bpc again, as expected. > > Fixes: d5df648ec830 ("drm/amd/display: Change dither policy for 10bpc to > round") > Signed-off-by: Mario Kleiner <[email protected]> > Tested-by: Mario Kleiner <[email protected]> > Cc: [email protected] > Cc: Aric Cyr <[email protected]> > Cc: Anthony Koo <[email protected]> > Cc: Rodrigo Siqueira <[email protected]> > Cc: Krunoslav Kovac <[email protected]> > Cc: Alex Deucher <[email protected]> > --- > drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > index c9fbb64d706a..29db5404c4a0 100644 > --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c > @@ -5056,7 +5056,7 @@ void resource_build_bit_depth_reduction_params(struct > dc_stream_state *stream, > option = DITHER_OPTION_SPATIAL8; > break; > case COLOR_DEPTH_101010: > - option = DITHER_OPTION_TRUN10; > + option = DITHER_OPTION_SPATIAL10; > break; > default: > option = DITHER_OPTION_DISABLE; > -- > 2.43.0 >
