From ba7454a15565d10e6f7d7d535ed41f433dab0f04 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 26 Jun 2025 12:25:01 -0700 Subject: [PATCH] dri2+gallium: Support to import suboptimal formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases a format may be supported in a more limited way by the hardware. For example, formats with NPoT pixel sizes. A driver might normally prefer that mesa/st use R8G8B8X8 rather than R8G8B8. But if the user wants to (dma-buf/etc) import R8G8B8, it is still possible, and in this case zero copy is more important. So add a PIPE_BIND_x flag as a hint to the driver when checking if a format is supported. Signed-off-by: Rob Clark Reviewed-by: Marek Olšák Part-of: --- docs/gallium/screen.rst | 3 +++ src/gallium/frontends/dri/dri2.c | 8 ++++++-- src/gallium/frontends/dri/dri_helpers.c | 3 +++ src/gallium/include/pipe/p_defines.h | 2 +- src/mesa/state_tracker/st_cb_eglimage.c | 7 +++++++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index db23e39e392..e8c09647bc8 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -815,6 +815,9 @@ resources might be created and handled quite differently. pipe_screen::flush_front_buffer must have this flag set. * ``PIPE_BIND_SAMPLER_VIEW``: A texture that may be sampled from in a fragment or vertex shader. +* ``PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL``: A hint to go along with ``PIPE_BIND_SAMPLER_VIEW`` + that we'd like to use a particular format (ie. for zero-copy import) even if + it is not optimal from a hw standpoint. * ``PIPE_BIND_VERTEX_BUFFER``: A vertex buffer. * ``PIPE_BIND_INDEX_BUFFER``: An vertex index/element buffer. * ``PIPE_BIND_CONSTANT_BUFFER``: A buffer of shader constants. diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index a7fff98c7f0..f70b3f0cc3e 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -865,7 +865,9 @@ dri_create_image_from_winsys(struct dri_screen *screen, PIPE_BIND_RENDER_TARGET)) tex_usage |= PIPE_BIND_RENDER_TARGET; if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, - PIPE_BIND_SAMPLER_VIEW)) + PIPE_BIND_SAMPLER_VIEW) || + pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL)) tex_usage |= PIPE_BIND_SAMPLER_VIEW; /* For NV12, see if we have support for sampling r8_g8b8 */ @@ -1518,7 +1520,9 @@ dri_query_dma_buf_modifiers(struct dri_screen *screen, int fourcc, int max, format = map->pipe_format; bool native_sampling = pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, - PIPE_BIND_SAMPLER_VIEW); + PIPE_BIND_SAMPLER_VIEW) || + pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL); if (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, PIPE_BIND_RENDER_TARGET) || native_sampling || diff --git a/src/gallium/frontends/dri/dri_helpers.c b/src/gallium/frontends/dri/dri_helpers.c index 7d1bc1e44f8..f6067cdbc6f 100644 --- a/src/gallium/frontends/dri/dri_helpers.c +++ b/src/gallium/frontends/dri/dri_helpers.c @@ -779,6 +779,9 @@ dri_query_dma_buf_formats(struct dri_screen *screen, int max, int *formats, pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW) || + pscreen->is_format_supported(pscreen, map->pipe_format, + screen->target, 0, 0, + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL) || dri2_yuv_dma_buf_supported(screen, map)) { if (j < max) formats[j] = map->dri_fourcc; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 6f036991932..65a583ac059 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -463,7 +463,7 @@ enum pipe_flush_flags #define PIPE_BIND_CONSTANT_BUFFER (1 << 6) /* set_constant_buffer */ #define PIPE_BIND_DISPLAY_TARGET (1 << 7) /* flush_front_buffer */ #define PIPE_BIND_VERTEX_STATE (1 << 8) /* create_vertex_state */ -/* gap */ +#define PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL (1 << 9) /* create_sampler_view */ #define PIPE_BIND_STREAM_OUTPUT (1 << 10) /* set_stream_output_buffers */ #define PIPE_BIND_CURSOR (1 << 11) /* mouse cursor */ #define PIPE_BIND_CUSTOM (1 << 12) /* gallium frontend/winsys usages */ diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index c2f10f5b4b0..9f52810742e 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -48,6 +48,13 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, bool supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage); + + if (!supported && (usage & PIPE_BIND_SAMPLER_VIEW)) { + supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, + nr_samples, nr_storage_samples, + usage | PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL); + } + *native_supported = supported; /* for sampling, some formats can be emulated.. it doesn't matter that