diff options
author | James Jones <jajones@nvidia.com> | 2020-08-06 16:13:07 -0700 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2020-11-11 10:51:37 +0000 |
commit | 6ee10ab3de8664011a6c75e2357faba1ec95c094 (patch) | |
tree | 14d78531a34416429f4fe8aac3cba44068594a1a | |
parent | 40e3eb9be96ec69259a000d08fe4a853a330007f (diff) |
gallium: Add pipe_screen::is_dmabuf_modifier_supported
Add a "do you support this modifier?" query to all
drivers which support format modifiers. This will
be used in a subsequent change to fully
encapsulate modifier validation and auxiliary plane
count calculation logic behind the driver
abstraction, which will in turn simplify the
addition of device-class-specific format modifiers
in the nouveau driver.
Signed-off-by: James Jones <jajones@nvidia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3723>
-rw-r--r-- | docs/gallium/screen.rst | 11 | ||||
-rw-r--r-- | src/gallium/auxiliary/driver_rbug/rbug_screen.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_screen.c | 41 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_screen.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_resource.c | 41 | ||||
-rw-r--r-- | src/gallium/drivers/lima/lima_screen.c | 33 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nvc0/nvc0_resource.c | 47 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_screen.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/tegra/tegra_screen.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/v3d/v3d_screen.c | 35 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_screen.c | 67 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_screen.h | 17 |
12 files changed, 327 insertions, 53 deletions
diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index f887f080ddc..fe3003ba788 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -1033,6 +1033,17 @@ returned. The callback itself may also be NULL if the driver doesn't support an on-disk shader cache. +is_dmabuf_modifier_supported +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Query whether the driver supports a **modifier** in combination with a +**format**, and whether it is only supported with "external" texture targets. +If the combination is supported in any fashion, true is returned. If the +**external_only** parameter is not NULL, the bool it points to is set to +false if non-external texture targets are supported with the specified modifier+ +format, or true if only external texture targets are supported. + + Thread safety ------------- diff --git a/src/gallium/auxiliary/driver_rbug/rbug_screen.c b/src/gallium/auxiliary/driver_rbug/rbug_screen.c index c3ff1feee8e..1fac4d62e17 100644 --- a/src/gallium/auxiliary/driver_rbug/rbug_screen.c +++ b/src/gallium/auxiliary/driver_rbug/rbug_screen.c @@ -165,6 +165,21 @@ rbug_screen_query_dmabuf_modifiers(struct pipe_screen *_screen, count); } +static bool +rbug_screen_is_dmabuf_modifier_supported(struct pipe_screen *_screen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + struct rbug_screen *rb_screen = rbug_screen(_screen); + struct pipe_screen *screen = rb_screen->screen; + + return screen->is_dmabuf_modifier_supported(screen, + modifier, + format, + external_only); +} + static struct pipe_context * rbug_screen_context_create(struct pipe_screen *_screen, void *priv, unsigned flags) @@ -427,6 +442,7 @@ rbug_screen_create(struct pipe_screen *screen) rb_screen->base.get_paramf = rbug_screen_get_paramf; rb_screen->base.is_format_supported = rbug_screen_is_format_supported; SCR_INIT(query_dmabuf_modifiers); + SCR_INIT(is_dmabuf_modifier_supported); rb_screen->base.context_create = rbug_screen_context_create; SCR_INIT(can_create_resource); rb_screen->base.resource_create = rbug_screen_resource_create; diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index 7b4a23d0c8b..e902b241986 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -578,13 +578,24 @@ const uint64_t supported_modifiers[] = { DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED, }; +static bool modifier_num_supported(struct pipe_screen *pscreen, int num) +{ + struct etna_screen *screen = etna_screen(pscreen); + + /* don't advertise split tiled formats on single pipe/buffer GPUs */ + if ((screen->specs.pixel_pipes == 1 || screen->specs.single_buffer) && + num >= 3) + return false; + + return true; +} + static void etna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count) { - struct etna_screen *screen = etna_screen(pscreen); int i, num_modifiers = 0; if (max > ARRAY_SIZE(supported_modifiers)) @@ -596,9 +607,7 @@ etna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, } for (i = 0; num_modifiers < max; i++) { - /* don't advertise split tiled formats on single pipe/buffer GPUs */ - if ((screen->specs.pixel_pipes == 1 || screen->specs.single_buffer) && - i >= 3) + if (!modifier_num_supported(pscreen, i)) break; if (modifiers) @@ -611,6 +620,29 @@ etna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, *count = num_modifiers; } +static bool +etna_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(supported_modifiers); i++) { + if (!modifier_num_supported(pscreen, i)) + break; + + if (modifier == supported_modifiers[i]) { + if (external_only) + *external_only = util_format_is_yuv(format) ? 1 : 0; + + return true; + } + } + + return false; +} + static void etna_determine_uniform_limits(struct etna_screen *screen) { @@ -1047,6 +1079,7 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu, pscreen->context_create = etna_context_create; pscreen->is_format_supported = etna_screen_is_format_supported; pscreen->query_dmabuf_modifiers = etna_screen_query_dmabuf_modifiers; + pscreen->is_dmabuf_modifier_supported = etna_screen_is_dmabuf_modifier_supported; screen->compiler = etna_compiler_create(etna_screen_get_name(pscreen)); if (!screen->compiler) diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 6d0c1e906b7..7e78cba585d 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -797,6 +797,27 @@ fd_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, *count = num; } +static bool +fd_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + struct fd_screen *screen = fd_screen(pscreen); + int i; + + for (i = 0; i < screen->num_supported_modifiers; i++) { + if (modifier == screen->supported_modifiers[i]) { + if (external_only) + *external_only = false; + + return true; + } + } + + return false; +} + struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle) @@ -1038,6 +1059,7 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro) pscreen->fence_get_fd = fd_fence_get_fd; pscreen->query_dmabuf_modifiers = fd_screen_query_dmabuf_modifiers; + pscreen->is_dmabuf_modifier_supported = fd_screen_is_dmabuf_modifier_supported; pscreen->get_device_uuid = fd_screen_get_device_uuid; pscreen->get_driver_uuid = fd_screen_get_driver_uuid; diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 8747ef4aa8a..96cd96e41b3 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -190,6 +190,19 @@ target_to_isl_surf_dim(enum pipe_texture_target target) unreachable("invalid texture type"); } +static inline bool is_modifier_external_only(enum pipe_format pfmt, + uint64_t modifier) +{ + /* Only allow external usage for the following cases: YUV formats + * and the media-compression modifier. The render engine lacks + * support for rendering to a media-compressed surface if the + * compression ratio is large enough. By requiring external usage + * of media-compressed surfaces, resolves are avoided. + */ + return util_format_is_yuv(pfmt) || + modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; +} + static void iris_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format pfmt, @@ -221,15 +234,8 @@ iris_query_dmabuf_modifiers(struct pipe_screen *pscreen, modifiers[supported_mods] = all_modifiers[i]; if (external_only) { - /* Only allow external usage for the following cases: YUV formats - * and the media-compression modifier. The render engine lacks - * support for rendering to a media-compressed surface if the - * compression ratio is large enough. By requiring external usage - * of media-compressed surfaces, resolves are avoided. - */ external_only[supported_mods] = - util_format_is_yuv(pfmt) || - all_modifiers[i] == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS; + is_modifier_external_only(pfmt, all_modifiers[i]); } } @@ -239,6 +245,24 @@ iris_query_dmabuf_modifiers(struct pipe_screen *pscreen, *count = supported_mods; } +static bool +iris_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, enum pipe_format pfmt, + bool *external_only) +{ + struct iris_screen *screen = (void *) pscreen; + const struct gen_device_info *devinfo = &screen->devinfo; + + if (modifier_is_supported(devinfo, pfmt, modifier)) { + if (external_only) + *external_only = is_modifier_external_only(pfmt, modifier); + + return true; + } + + return false; +} + enum isl_format iris_image_view_get_format(struct iris_context *ice, const struct pipe_image_view *img) @@ -2225,6 +2249,7 @@ void iris_init_screen_resource_functions(struct pipe_screen *pscreen) { pscreen->query_dmabuf_modifiers = iris_query_dmabuf_modifiers; + pscreen->is_dmabuf_modifier_supported = iris_is_dmabuf_modifier_supported; pscreen->resource_create_with_modifiers = iris_resource_create_with_modifiers; pscreen->resource_create = u_transfer_helper_resource_create; diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c index 72bae09d0ed..831464e3080 100644 --- a/src/gallium/drivers/lima/lima_screen.c +++ b/src/gallium/drivers/lima/lima_screen.c @@ -487,6 +487,11 @@ lima_screen_query_info(struct lima_screen *screen) return true; } +static const uint64_t lima_available_modifiers[] = { + DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, + DRM_FORMAT_MOD_LINEAR, +}; + static void lima_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, @@ -494,12 +499,7 @@ lima_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, unsigned int *external_only, int *count) { - uint64_t available_modifiers[] = { - DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, - DRM_FORMAT_MOD_LINEAR, - }; - - int num_modifiers = ARRAY_SIZE(available_modifiers); + int num_modifiers = ARRAY_SIZE(lima_available_modifiers); if (!modifiers) { *count = num_modifiers; @@ -508,12 +508,30 @@ lima_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, *count = MIN2(max, num_modifiers); for (int i = 0; i < *count; i++) { - modifiers[i] = available_modifiers[i]; + modifiers[i] = lima_available_modifiers[i]; if (external_only) external_only[i] = false; } } +static bool +lima_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + for (int i = 0; i < ARRAY_SIZE(lima_available_modifiers); i++) { + if (lima_available_modifiers[i] == modifier) { + if (external_only) + *external_only = false; + + return true; + } + } + + return false; +} + static const struct debug_named_value debug_options[] = { { "gp", LIMA_DEBUG_GP, "print GP shader compiler result of each stage" }, @@ -676,6 +694,7 @@ lima_screen_create(int fd, struct renderonly *ro) screen->base.is_format_supported = lima_screen_is_format_supported; screen->base.get_compiler_options = lima_screen_get_compiler_options; screen->base.query_dmabuf_modifiers = lima_screen_query_dmabuf_modifiers; + screen->base.is_dmabuf_modifier_supported = lima_screen_is_dmabuf_modifier_supported; lima_resource_screen_init(screen); lima_fence_screen_init(screen); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c index 67e5adabd16..e79de9f361c 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c @@ -32,35 +32,36 @@ nvc0_resource_create_with_modifiers(struct pipe_screen *screen, } } +static const uint64_t nvc0_supported_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB, +}; + static void nvc0_query_dmabuf_modifiers(struct pipe_screen *screen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count) { - static const uint64_t supported_modifiers[] = { - DRM_FORMAT_MOD_LINEAR, - DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB, - DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB, - DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB, - DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB, - DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB, - DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB, - }; int i, num = 0; - if (max > ARRAY_SIZE(supported_modifiers)) - max = ARRAY_SIZE(supported_modifiers); + if (max > ARRAY_SIZE(nvc0_supported_modifiers)) + max = ARRAY_SIZE(nvc0_supported_modifiers); if (!max) { - max = ARRAY_SIZE(supported_modifiers); + max = ARRAY_SIZE(nvc0_supported_modifiers); external_only = NULL; modifiers = NULL; } for (i = 0; i < max; i++) { if (modifiers) - modifiers[num] = supported_modifiers[i]; + modifiers[num] = nvc0_supported_modifiers[i]; if (external_only) external_only[num] = 0; @@ -71,6 +72,25 @@ nvc0_query_dmabuf_modifiers(struct pipe_screen *screen, *count = num; } +static bool +nvc0_is_dmabuf_modifier_supported(struct pipe_screen *screen, + uint64_t modifier, enum pipe_format format, + bool *external_only) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(nvc0_supported_modifiers); i++) { + if (nvc0_supported_modifiers[i] == modifier) { + if (external_only) + *external_only = false; + + return true; + } + } + + return false; +} + static struct pipe_resource * nvc0_resource_from_handle(struct pipe_screen * screen, const struct pipe_resource *templ, @@ -130,6 +150,7 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen) pscreen->resource_create = nvc0_resource_create; pscreen->resource_create_with_modifiers = nvc0_resource_create_with_modifiers; pscreen->query_dmabuf_modifiers = nvc0_query_dmabuf_modifiers; + pscreen->is_dmabuf_modifier_supported = nvc0_is_dmabuf_modifier_supported; pscreen->resource_from_handle = nvc0_resource_from_handle; pscreen->resource_get_handle = u_resource_get_handle_vtbl; pscreen->resource_destroy = u_resource_destroy_vtbl; diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index 54ab84cdfd5..24ba288be13 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -507,9 +507,9 @@ panfrost_is_format_supported( struct pipe_screen *screen, * subset of those. */ static void -panfrost_query_dmabuf_modifiers(struct pipe_screen *screen, +panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen, enum pipe_format format, int max, uint64_t *modifiers, unsigned - int *external_only, int *out_count) + int *external_only, int *out_count, uint64_t test_modifier) { /* Query AFBC status */ bool afbc = panfrost_format_supports_afbc(format); @@ -531,6 +531,10 @@ panfrost_query_dmabuf_modifiers(struct pipe_screen *screen, if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr) continue; + if (test_modifier != DRM_FORMAT_MOD_INVALID && + test_modifier != pan_best_modifiers[i]) + continue; + count++; if (max > (int) count) { @@ -544,6 +548,33 @@ panfrost_query_dmabuf_modifiers(struct pipe_screen *screen, *out_count = count; } +static void +panfrost_query_dmabuf_modifiers(struct pipe_screen *screen, + enum pipe_format format, int max, uint64_t *modifiers, unsigned + int *external_only, int *out_count) +{ + panfrost_walk_dmabuf_modifiers(screen, format, max, modifiers, + external_only, out_count, DRM_FORMAT_MOD_INVALID); +} + +static bool +panfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen, + uint64_t modifier, enum pipe_format format, + bool *external_only) +{ + uint64_t unused; + unsigned int uint_extern_only = 0; + int count; + + panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused, + &uint_extern_only, &count, modifier); + + if (external_only) + *external_only = uint_extern_only ? true : false; + + return count > 0; +} + static int panfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, enum pipe_compute_cap param, void *ret) @@ -755,6 +786,8 @@ panfrost_create_screen(int fd, struct renderonly *ro) screen->base.get_timestamp = panfrost_get_timestamp; screen->base.is_format_supported = panfrost_is_format_supported; screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers; + screen->base.is_dmabuf_modifier_supported = + panfrost_is_dmabuf_modifier_supported; screen->base.context_create = panfrost_create_context; screen->base.get_compiler_options = panfrost_screen_get_compiler_options; screen->base.fence_reference = panfrost_fence_reference; diff --git a/src/gallium/drivers/tegra/tegra_screen.c b/src/gallium/drivers/tegra/tegra_screen.c index 73efb8e904e..e2d66128292 100644 --- a/src/gallium/drivers/tegra/tegra_screen.c +++ b/src/gallium/drivers/tegra/tegra_screen.c @@ -514,6 +514,18 @@ static void tegra_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, external_only, count); } +static bool +tegra_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + struct tegra_screen *screen = to_tegra_screen(pscreen); + + return screen->gpu->is_dmabuf_modifier_supported(screen->gpu, modifier, + format, external_only); +} + static struct pipe_memory_object * tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handle *handle, @@ -592,6 +604,7 @@ tegra_screen_create(int fd) screen->base.resource_create_with_modifiers = tegra_screen_resource_create_with_modifiers; screen->base.query_dmabuf_modifiers = tegra_screen_query_dmabuf_modifiers; + screen->base.is_dmabuf_modifier_supported = tegra_screen_is_dmabuf_modifier_supported; screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle; return &screen->base; diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 1b9d76b8956..4f69c2089d9 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -631,6 +631,11 @@ v3d_screen_get_compiler_options(struct pipe_screen *pscreen, return &v3d_nir_options; } +static const uint64_t v3d_available_modifiers[] = { + DRM_FORMAT_MOD_BROADCOM_UIF, + DRM_FORMAT_MOD_LINEAR, +}; + static void v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, @@ -639,11 +644,7 @@ v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, int *count) { int i; - uint64_t available_modifiers[] = { - DRM_FORMAT_MOD_BROADCOM_UIF, - DRM_FORMAT_MOD_LINEAR, - }; - int num_modifiers = ARRAY_SIZE(available_modifiers); + int num_modifiers = ARRAY_SIZE(v3d_available_modifiers); if (!modifiers) { *count = num_modifiers; @@ -652,12 +653,32 @@ v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, *count = MIN2(max, num_modifiers); for (i = 0; i < *count; i++) { - modifiers[i] = available_modifiers[i]; + modifiers[i] = v3d_available_modifiers[i]; if (external_only) external_only[i] = false; } } +static bool +v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers); i++) { + if (v3d_available_modifiers[i] == modifier) { + if (external_only) + *external_only = false; + + return true; + } + } + + return false; +} + struct pipe_screen * v3d_screen_create(int fd, const struct pipe_screen_config *config, struct renderonly *ro) @@ -722,6 +743,8 @@ v3d_screen_create(int fd, const struct pipe_screen_config *config, pscreen->get_device_vendor = v3d_screen_get_vendor; pscreen->get_compiler_options = v3d_screen_get_compiler_options; pscreen->query_dmabuf_modifiers = v3d_screen_query_dmabuf_modifiers; + pscreen->is_dmabuf_modifier_supported = + v3d_screen_is_dmabuf_modifier_supported; return pscreen; diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index b55fed52187..18d49c4a3a7 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -411,6 +411,30 @@ vc4_screen_is_format_supported(struct pipe_screen *pscreen, return true; } +static const uint64_t *vc4_get_modifiers(struct pipe_screen *pscreen, int *num) +{ + struct vc4_screen *screen = vc4_screen(pscreen); + static const uint64_t all_modifiers[] = { + DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, + DRM_FORMAT_MOD_LINEAR, + }; + int m; + + /* We support both modifiers (tiled and linear) for all sampler + * formats, but if we don't have the DRM_VC4_GET_TILING ioctl + * we shouldn't advertise the tiled formats. + */ + if (screen->has_tiling_ioctl) { + m = 0; + *num = 2; + } else{ + m = 1; + *num = 1; + } + + return &all_modifiers[m]; +} + static void vc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, @@ -418,14 +442,12 @@ vc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, unsigned int *external_only, int *count) { - int m, i; + const uint64_t *available_modifiers; + int i; bool tex_will_lower; - uint64_t available_modifiers[] = { - DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, - DRM_FORMAT_MOD_LINEAR, - }; - struct vc4_screen *screen = vc4_screen(pscreen); - int num_modifiers = screen->has_tiling_ioctl ? 2 : 1; + int num_modifiers; + + available_modifiers = vc4_get_modifiers(pscreen, &num_modifiers); if (!modifiers) { *count = num_modifiers; @@ -433,20 +455,38 @@ vc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, } *count = MIN2(max, num_modifiers); - m = screen->has_tiling_ioctl ? 0 : 1; tex_will_lower = !vc4_tex_format_supported(format); - /* We support both modifiers (tiled and linear) for all sampler - * formats, but if we don't have the DRM_VC4_GET_TILING ioctl - * we shouldn't advertise the tiled formats. - */ for (i = 0; i < *count; i++) { - modifiers[i] = available_modifiers[m++]; + modifiers[i] = available_modifiers[i]; if (external_only) external_only[i] = tex_will_lower; } } static bool +vc4_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, + uint64_t modifier, + enum pipe_format format, + bool *external_only) +{ + const uint64_t *available_modifiers; + int i, num_modifiers; + + available_modifiers = vc4_get_modifiers(pscreen, &num_modifiers); + + for (i = 0; i < num_modifiers; i++) { + if (modifier == available_modifiers[i]) { + if (external_only) + *external_only = !vc4_tex_format_supported(format); + + return true; + } + } + + return false; +} + +static bool vc4_get_chip_info(struct vc4_screen *screen) { struct drm_vc4_get_param ident0 = { @@ -563,6 +603,7 @@ vc4_screen_create(int fd, struct renderonly *ro) pscreen->get_device_vendor = vc4_screen_get_vendor; pscreen->get_compiler_options = vc4_screen_get_compiler_options; pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers; + pscreen->is_dmabuf_modifier_supported = vc4_screen_is_dmabuf_modifier_supported; if (screen->has_perfmon_ioctl) { pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index d52dbd7e5c6..dc7be42a062 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -559,6 +559,23 @@ struct pipe_screen { */ void (*unmap_memory)(struct pipe_screen *screen, struct pipe_memory_allocation *pmem); + + /** + * Determine whether the screen supports the specified modifier + * + * Query whether the driver supports a \p modifier in combination with + * \p format. If \p external_only is not NULL, the value it points to will + * be set to 0 or a non-zero value to indicate whether the modifier and + * format combination is supported only with external, or also with non- + * external texture targets respectively. The \p external_only parameter is + * not used when the function returns false. + * + * \return true if the format+modifier pair is supported on \p screen, false + * otherwise. + */ + bool (*is_dmabuf_modifier_supported)(struct pipe_screen *screen, + uint64_t modifier, enum pipe_format, + bool *external_only); }; |