From 417be4f77e8e25f691b928a1ffb119f17411acae Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Mon, 25 Aug 2025 10:18:21 -0300 Subject: [PATCH] dri: check modifier in dri_create_image_from_winsys When importing an image, check that the specific combination of format plus modifier is supported, rather than just checking the format. This will allow drivers to support some YUV formats in special cases (specific modifiers, like AFBC for panfrost) while also allowing us to fall back to generic multi-plane formats when those modifier+format combinations are not supported by hardware. Reviewed-by: Daniel Stone Part-of: --- src/gallium/frontends/dri/dri2.c | 93 +++++++++++++++++++------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index ff1658af41e..036fddd338c 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -661,6 +661,26 @@ from_dri_compression_rate(enum __DRIFixedRateCompression rate) } } +static bool +format_and_modifier_supported(struct pipe_screen *pscreen, enum pipe_format format, + enum pipe_texture_target target, unsigned sample_count, + unsigned storage_sample_count, unsigned bind, + uint64_t modifier) +{ + if (!pscreen->is_format_supported(pscreen, format, target, sample_count, + storage_sample_count, bind)) + return false; + if (!pscreen->is_dmabuf_modifier_supported) + return true; + + if (pscreen->is_dmabuf_modifier_supported(pscreen, modifier, format, NULL)) + return true; + if (modifier == DRM_FORMAT_MOD_INVALID) + return pscreen->is_dmabuf_modifier_supported(pscreen, DRM_FORMAT_MOD_LINEAR, format, NULL); + + return false; +} + static struct dri_image * dri_create_image_from_winsys(struct dri_screen *screen, int width, int height, const struct dri2_format_mapping *map, @@ -675,65 +695,66 @@ dri_create_image_from_winsys(struct dri_screen *screen, int i; bool use_lowered = false; const unsigned format_planes = util_format_get_num_planes(map->pipe_format); + uint64_t modifier = whandle[0].modifier; - if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0, - PIPE_BIND_RENDER_TARGET)) + if (format_and_modifier_supported(pscreen, map->pipe_format, screen->target, 0, 0, + PIPE_BIND_RENDER_TARGET, modifier)) tex_usage |= PIPE_BIND_RENDER_TARGET; - if (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)) + if (format_and_modifier_supported(pscreen, map->pipe_format, screen->target, 0, 0, + PIPE_BIND_SAMPLER_VIEW, modifier) || + format_and_modifier_supported(pscreen, map->pipe_format, screen->target, 0, 0, + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SAMPLER_VIEW_SUBOPTIMAL, modifier)) tex_usage |= PIPE_BIND_SAMPLER_VIEW; /* For NV12, see if we have support for sampling r8_g8b8 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV12 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8B8_420_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8_G8B8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8_g8b8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } /* For NV21, see if we have support for sampling r8_b8g8 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV21 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_B8G8_420_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8_B8G8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8_b8g8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } /* For NV16, see if we have support for sampling r8_g8b8 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV16 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8B8_422_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8_G8B8_422_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8_g8b8_mapping_422; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } /* For NV15, see if we have support for sampling r10_g10b10 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV15 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10_G10B10_420_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R10_G10B10_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r10_g10b10_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV20 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10_G10B10_422_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R10_G10B10_422_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r10_g10b10_mapping_422; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } /* For YUV420_8BIT, see if we have support for sampling r8b8g8_420 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8G8B8_420_UNORM_PACKED, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8G8B8_420_UNORM_PACKED, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8g8b8_420_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R10G10B10_420_UNORM_PACKED, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R10G10B10_420_UNORM_PACKED, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r10g10b10_420_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } @@ -741,13 +762,13 @@ dri_create_image_from_winsys(struct dri_screen *screen, /* For YV12 and I420, see if we have support for sampling r8_b8_g8 or r8_g8_b8 */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV) { if (map->dri_fourcc == DRM_FORMAT_YUV420 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8_B8_420_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8_G8_B8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8_g8_b8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } else if (map->dri_fourcc == DRM_FORMAT_YVU420 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_B8_G8_420_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8_B8_G8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8_b8_g8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } @@ -757,41 +778,41 @@ dri_create_image_from_winsys(struct dri_screen *screen, * can be used for YUYV and UYVY formats. */ if (!tex_usage && map->pipe_format == PIPE_FORMAT_YUYV && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8G8_R8B8_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8G8_R8B8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8g8_r8b8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_YVYU && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8B8_R8G8_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R8B8_R8G8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r8b8_r8g8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_UYVY && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_G8R8_B8R8_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_G8R8_B8R8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &g8r8_b8r8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_VYUY && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_B8R8_G8R8_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_B8R8_G8R8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &b8r8_g8r8_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_Y210 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r10g10_r10b10_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; } if (!tex_usage && map->pipe_format == PIPE_FORMAT_Y216 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R16G16_R16B16_422_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + format_and_modifier_supported(pscreen, PIPE_FORMAT_R16G16_R16B16_422_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW, modifier)) { map = &r16g16_r16b16_mapping; tex_usage |= PIPE_BIND_SAMPLER_VIEW; }