dri2+gallium: Support to import suboptimal formats

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 <rob.clark@oss.qualcomm.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35982>
This commit is contained in:
Rob Clark 2025-06-26 12:25:01 -07:00 committed by Marge Bot
parent 2870addd15
commit ba7454a155
5 changed files with 20 additions and 3 deletions

View file

@ -815,6 +815,9 @@ resources might be created and handled quite differently.
pipe_screen::flush_front_buffer must have this flag set. pipe_screen::flush_front_buffer must have this flag set.
* ``PIPE_BIND_SAMPLER_VIEW``: A texture that may be sampled from in a fragment * ``PIPE_BIND_SAMPLER_VIEW``: A texture that may be sampled from in a fragment
or vertex shader. 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_VERTEX_BUFFER``: A vertex buffer.
* ``PIPE_BIND_INDEX_BUFFER``: An vertex index/element buffer. * ``PIPE_BIND_INDEX_BUFFER``: An vertex index/element buffer.
* ``PIPE_BIND_CONSTANT_BUFFER``: A buffer of shader constants. * ``PIPE_BIND_CONSTANT_BUFFER``: A buffer of shader constants.

View file

@ -865,7 +865,9 @@ dri_create_image_from_winsys(struct dri_screen *screen,
PIPE_BIND_RENDER_TARGET)) PIPE_BIND_RENDER_TARGET))
tex_usage |= PIPE_BIND_RENDER_TARGET; tex_usage |= PIPE_BIND_RENDER_TARGET;
if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, 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; tex_usage |= PIPE_BIND_SAMPLER_VIEW;
/* For NV12, see if we have support for sampling r8_g8b8 */ /* 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; format = map->pipe_format;
bool native_sampling = pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, 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, if (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
PIPE_BIND_RENDER_TARGET) || PIPE_BIND_RENDER_TARGET) ||
native_sampling || native_sampling ||

View file

@ -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, pscreen->is_format_supported(pscreen, map->pipe_format,
screen->target, 0, 0, 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) ||
dri2_yuv_dma_buf_supported(screen, map)) { dri2_yuv_dma_buf_supported(screen, map)) {
if (j < max) if (j < max)
formats[j] = map->dri_fourcc; formats[j] = map->dri_fourcc;

View file

@ -463,7 +463,7 @@ enum pipe_flush_flags
#define PIPE_BIND_CONSTANT_BUFFER (1 << 6) /* set_constant_buffer */ #define PIPE_BIND_CONSTANT_BUFFER (1 << 6) /* set_constant_buffer */
#define PIPE_BIND_DISPLAY_TARGET (1 << 7) /* flush_front_buffer */ #define PIPE_BIND_DISPLAY_TARGET (1 << 7) /* flush_front_buffer */
#define PIPE_BIND_VERTEX_STATE (1 << 8) /* create_vertex_state */ #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_STREAM_OUTPUT (1 << 10) /* set_stream_output_buffers */
#define PIPE_BIND_CURSOR (1 << 11) /* mouse cursor */ #define PIPE_BIND_CURSOR (1 << 11) /* mouse cursor */
#define PIPE_BIND_CUSTOM (1 << 12) /* gallium frontend/winsys usages */ #define PIPE_BIND_CUSTOM (1 << 12) /* gallium frontend/winsys usages */

View file

@ -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, bool supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
nr_samples, nr_storage_samples, nr_samples, nr_storage_samples,
usage); 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; *native_supported = supported;
/* for sampling, some formats can be emulated.. it doesn't matter that /* for sampling, some formats can be emulated.. it doesn't matter that