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 <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35771>
This commit is contained in:
Eric R. Smith
2025-08-25 10:18:21 -03:00
committed by Marge Bot
parent b11f543c4e
commit 417be4f77e
+57 -36
View File
@@ -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;
}