dri,gallium: Add support for RGB[A]16_UNORM display formats.

These are useful for displaying very high color precision images with
more than 10 bpc color depth, and also more precision than what fp16
can do on a standard dynamic range (SDR) display, where fp16 for values
in the unorm 0.0 - 1.0 range is about equivalent to at most ~11 bpc
linear color depth. This is especially useful for and aimed at scientific
applications, e.g., neuroscience and other bio-medical research cases.

At least current generation AMD gpu's released during the last 10 years
and supported by amdgpu-kms + atomic modesetting do allow for scanout of
such 16 bpc framebuffers and of up to 12 bpc output to suitable HDMI or
DisplayPort high precision displays.

We gate the format behind a new driconf option 'allow_rgb16_configs',
which defaults to true, but allows to disable the formats if any issues
should arise.

Most regular applications won't need the high display precision of
these new 16 bpc 64 bpp formats which have higher memory and bandwidth
requirements, and therefore a potential undesired performance impact
for regular apps. Followup per-platform enablement commits will use
the EGL_EXT_config_select_group extension to put these 16 bpc unorm
formats into a lower priority config select group 1, so they don't get
preferably chosen by default by eglChooseConfig(), but must be explicitely
requested by client applications which really need the high color
precision of these 64 bpp formats and are happy to pay the potential
performance impact. Thanks to Adam Jackson for pointing me to the
EGL_EXT_config_select_group extension.

If the format would be put into the default config select group 0, a
simple EGL eglChooseConfig() call would end up choosing these formats,
which is not what such regular apps would want.

Tested to not cause any change on native X11/EGL and X11/GLX, which only
supports at most 30 bpc / 32 bpp formats.

Followup commits will enable these formats for the EGL/Wayland backend,
and on the EGL/DRM backend.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38588>
This commit is contained in:
Mario Kleiner 2025-11-06 07:23:53 +00:00 committed by Marge Bot
parent 1fe73481ba
commit f2aaa9ce00
4 changed files with 20 additions and 0 deletions

View file

@ -69,5 +69,6 @@ DRI_CONF_SECTION_MISCELLANEOUS
DRI_CONF_VS_POSITION_ALWAYS_INVARIANT(false)
DRI_CONF_VS_POSITION_ALWAYS_PRECISE(false)
DRI_CONF_ALLOW_RGB10_CONFIGS(true)
DRI_CONF_ALLOW_RGB16_CONFIGS(true)
DRI_CONF_FORCE_INTEGER_TEX_NEAREST(false)
DRI_CONF_SECTION_END

View file

@ -324,6 +324,8 @@ dri_fill_in_modes(struct dri_screen *screen)
PIPE_FORMAT_B5G6R5_UNORM,
PIPE_FORMAT_R16G16B16A16_FLOAT,
PIPE_FORMAT_R16G16B16X16_FLOAT,
PIPE_FORMAT_R16G16B16A16_UNORM,
PIPE_FORMAT_R16G16B16X16_UNORM,
PIPE_FORMAT_RGBA8888_UNORM,
PIPE_FORMAT_RGBX8888_UNORM,
PIPE_FORMAT_RGBA8888_SRGB,
@ -341,6 +343,7 @@ dri_fill_in_modes(struct dri_screen *screen)
bool mixed_color_depth;
bool allow_rgba_ordering;
bool allow_rgb10;
bool allow_rgb16;
bool allow_fp16;
static const bool db_modes[] = { false, true };
@ -350,6 +353,7 @@ dri_fill_in_modes(struct dri_screen *screen)
allow_rgba_ordering = dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING);
allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs");
allow_rgb16 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb16_configs");
allow_fp16 = dri_loader_get_cap(screen, DRI_LOADER_CAP_FP16);
#define HAS_ZS(fmt) \
@ -405,6 +409,16 @@ dri_fill_in_modes(struct dri_screen *screen)
UTIL_FORMAT_COLORSPACE_RGB, 2) == 10)
continue;
/* Block RGB[A]16_UNORM formats, if forbidden by config */
if (!allow_rgb16 && !util_format_is_float(pipe_formats[f]) &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 0) == 16 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 1) == 16 &&
util_format_get_component_bits(pipe_formats[f],
UTIL_FORMAT_COLORSPACE_RGB, 2) == 16)
continue;
if (!allow_fp16 && util_format_is_float(pipe_formats[f]))
continue;

View file

@ -416,6 +416,7 @@ st_new_renderbuffer_fb(enum pipe_format format, unsigned samples, bool sw)
case PIPE_FORMAT_R16G16B16A16_UNORM:
rb->InternalFormat = GL_RGBA16;
break;
case PIPE_FORMAT_R16G16B16X16_UNORM:
case PIPE_FORMAT_R16G16B16_UNORM:
rb->InternalFormat = GL_RGB16;
break;

View file

@ -515,6 +515,10 @@
DRI_CONF_OPT_B(allow_rgb10_configs, def, \
"Allow exposure of visuals and fbconfigs with rgb10a2 formats")
#define DRI_CONF_ALLOW_RGB16_CONFIGS(def) \
DRI_CONF_OPT_B(allow_rgb16_configs, def, \
"Allow exposure of visuals and fbconfigs with rgb16 and rgba16 formats")
#define DRI_CONF_ALLOW_RGB565_CONFIGS(def) \
DRI_CONF_OPT_B(allow_rgb565_configs, def, \
"Allow exposure of visuals and fbconfigs with rgb565 formats")