To clarify: I do agree with Michel and Kruno that in most typical use cases you'd probably want to get all or as much of the internal HW pipelines precision as possible to the Eyes of the person in front of the display, or at least an approximation of it. My understanding of current AMD hardware is that you can have an up to 16 bpc framebuffer, which gets truncated/rounded down to 12 bpc somewhere in the pipeline (gamma tables, color transformation matrices, etc.) and then retained at 12 bpc until shortly before the actual output, which can be 6, 8, 10 or 12 bpc depending on connection type, bandwidth, "max bpc" etc.
If the final output depth is lower than 12 bpc one would usually still want an approximation of 12 bpc reaching the "eyes" of the person (/animal/retina in some of the use cases of my research users) in front of the display, and spatial dithering down from 12 bpc -> 10/8/6 bpc is the way to go. That's also true for most of my users use cases, and especially for the use cases involving 16 bpc framebuffers/surfaces. Some more special use cases will require an absolutely perfect identity passthrough of pixel color values, where any kind of transformation in the pipeline, including spatial dithering, would be bad. Some of your customers seem to require this for 10 bpc output. Some of my users require this for 8 bpc output of a 8 bpc framebuffer. Specifically, some neuroscience research requires up to 16 bpc color or luminance precision, but all graphics cards and normal displays max out at 12 bpc. There exist special display devices and converters that can do up to 16 bpc precision (native or via some form of spatial or temporal dithering), e.g., the Bits# or Display++ from Cambridge Research Systems (UK) and Datapixx, ViewPixx and ProPixx devices from VPixx in Canada. These are essentially active DVI-D or DisplayPort 8 bpc to 14 bpc or 16 bpc VGA analog converters with 14 or 16 DAC's, or special purpose LCD panels or DLP video projectors which can do 14/16 bpc precision. Because commercially available gpu's and PHY's do not support true 16 bpc output (the DP and HDMI standards specify such signal formats, but no actual transmitter hardware afaik), these devices encode 16 bpc color content on top of a 8 bpc framebuffer and link: The software renders 16 bpc unorm/fp or 32 bpc float content and then uses GLSL shaders to split up 16 bpc into 8 MSB and 8 LSB and puts the 8 MSB into the 8 bpc red channel and 8 LSB into the 8 bpc blue channel (and 8 bpc color index overlay into the 8 bpc blue channel) to false-color encode a pure grayscale image + some 256 color index palette overlay. Or for true color images, it sacrifices half the horizontal resolution by putting 8 MSB of each color channel into the even pixel columns, and the 8 LSB into the odd pixel columns. So a false color 8 rgb8 framebuffer -> pixel identity passthrough -> 8 bpc link output via DVI-D or DP, and the video sink then decodes and reassembles again into 16 bpc color/luminance content and uses special display hardware to these 16 bpc into the eyes of the being in front of the display. Some medical imaging displays, e.g., for Radiology use (e.g., cancer screening) in hospitals or at eye doctors, also use such special framebuffer encodings to get > 12 bpc content out of the gpu Siemens Medical and similar companies sell these for research and medical use. Another use case of my users requiring perfect pixel identity passthrough is to encode side-band signals into the scanlines of the vactive area of an image, encoding binary control data and packets as false color pixel values, similar to the various info packets transmitted inside vblank. This for control data that is very custom and not standardized in any Vesa or HDMI standard, e.g., in my case to control special neuroscience hardware, e.g., sound microsecond synchronized to pictures, sending various analog waveforms to electrophysiology equipment or haptic stimulation, or digital trigger signals to transmagnetic stimulators (magnetic pulses to brain regions), or start/stop/synchronize various recording equipment (fMRI and MEG scanners, electrophysiological recordings, video capture etc.) For the pixel identity passthrough, the difference is that I only need it for 8 bpc framebuffers to 8 bpc (DVI-D or DP) outputs atm., and that works fine under OpenGL with an identity gamma table loaded, despite spatial dithering down to 8 bpc active. Right now, I neither have the need nor the equipment to verify 10 bpc identity passthrough, as my capture hw can only process 8 bpc signals. I don't think there is an automated way for the driver to guess the proper configuration in all cases. The proper solution would be a drm connector property that can be queried/set to control dithering on/off/method/target depth, and plumb that through. Or maybe something that could be derived from existing connector properties? E.g., if a content property has something standardized that essentially requires identity passthrough? In my case, it is important that such settings still fully work under native X11 via RandR properties. Something that is only realistically accessible via an atomic client or Wayland server is insufficient for me. So yes, as Michel points out, there is a disconnect between the framebuffer color depth and hw pipeline depth and what dither settings should be used. But Harry's patch, if it worked, would be at least a good enough guess-o-matic or heuristic to make the situation better in the short term, even if it is not optimal. Or at least for my users use cases it would make it better, as for my use cases the framebuffer color depth usually corresponds to what my users need as effective output precision. For me there is also the urgency of wanting to have a not broken situation for Linux 7.0 and upcoming Ubuntu 26.04-LTS / Fedora Core 44. If I have the choice of having the current state, or this patch, I'd gladly have this patch as a step up. I hoped this patch would be still simple and contained and early enough, to make it into drm-fixes for Linux 7.0, and maybe be backportable to older kernels, as all kernels since late 2023 are impaired from my use cases point of view. But as I said, my testing didn't confirm the patch is actually working - it always ends up enabling dithering. Which, to be sneaky, would also be a step up for me, as that "only" breaks use cases that don't affect my users specifically :/ On Tue, Mar 31, 2026 at 9:16 AM Michel Dänzer <[email protected]> wrote: > On 3/30/26 19:36, Harry Wentland wrote: > > On 2026-03-30 12:20, Michel Dänzer wrote: > >> On 3/24/26 20:20, Mario Kleiner wrote: > >>> On Sun, Mar 22, 2026 at 7:11 PM Kovac, Krunoslav < > [email protected] <mailto:[email protected]>> wrote: > > > >>>> I believe we don't have surface info in that code, but one way to > work around it would be to use spatial dithering for FP16/ARGB16 and > rounding for 10 bits. But if we just switch to spatial, some of the earlier > complaints about 10-bit output having one-off bit errors will be coming > back. > >>> > >>> Looking at all callers of resource_build_bit_depth_reduction_params(), > they all have access to the associated "struct pipe_ctx", which should give > access to pipe_ctx ->plane_state->format of an associated display plane. I > could prepare a patch that passes the pipe_ctx from each caller > into resource_build_bit_depth_reduction_params() and that function could > check if a 16 bpc framebuffer is in use and switch to spatial dithering > down-to-10-bpc in this case, and leave the rounding/truncation to 10 bpc > otherwise. > >> > >> That doesn't really make sense, the output of the display HW colour > pipeline has more than 10 bpc regardless of framebuffer format. > >> > > > > The output will be determined by the link bandwidth, display-advertised > supported bpc, and userspace-selected "max bpc" on a drm_connector. This > could very well be 10 bpc, 8 bpc, even 6 bpc. Or are you referring to the > internal DCN HW representation of the values? > > I am indeed. > > > They're higher, but that's somewhat irrelevant. > > How so? Surely dithering is applied to those values, not to the original > values sampled from the framebuffer. > > > -- > Earthling Michel Dänzer \ GNOME / Xwayland / Mesa developer > https://redhat.com \ Libre software enthusiast >
