summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Jones <jajones@nvidia.com>2020-08-06 16:13:07 -0700
committerMarge Bot <eric+marge@anholt.net>2020-11-11 10:51:37 +0000
commit6ee10ab3de8664011a6c75e2357faba1ec95c094 (patch)
tree14d78531a34416429f4fe8aac3cba44068594a1a
parent40e3eb9be96ec69259a000d08fe4a853a330007f (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.rst11
-rw-r--r--src/gallium/auxiliary/driver_rbug/rbug_screen.c16
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_screen.c41
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c22
-rw-r--r--src/gallium/drivers/iris/iris_resource.c41
-rw-r--r--src/gallium/drivers/lima/lima_screen.c33
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_resource.c47
-rw-r--r--src/gallium/drivers/panfrost/pan_screen.c37
-rw-r--r--src/gallium/drivers/tegra/tegra_screen.c13
-rw-r--r--src/gallium/drivers/v3d/v3d_screen.c35
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c67
-rw-r--r--src/gallium/include/pipe/p_screen.h17
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);
};