gallium: Add format modifier plane count query

Rather than hard-code a list of all the format
modifiers supported by any gallium driver and the
number of aux planes they require in the dri state
tracker, add a screen proc that queries the number
of planes required for a given modifier+format
pair.

Since the only format modifiers that require
auxiliary planes currently are the iris driver's
I915_FORMAT_MOD_Y_TILED_CCS,
I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, and
I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS, the absence
of the screen proc implies zero aux planes for all
of the screen's supported modifiers.  Hence, when
a driver does not expose the proc, derive the
number of planes directly from the format.

Signed-off-by: James Jones <jajones@nvidia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3723>
This commit is contained in:
James Jones
2020-02-03 13:17:01 -08:00
committed by Marge Bot
parent 6ee10ab3de
commit 68d70fb969
6 changed files with 93 additions and 32 deletions

View File

@@ -1044,6 +1044,17 @@ false if non-external texture targets are supported with the specified modifier+
format, or true if only external texture targets are supported.
get_dmabuf_modifier_planes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Query the number of planes required by the image layout specified by the
**modifier** and **format** parameters. The value returned includes both planes
dictated by **format** and any additional planes required for driver-specific
auxiliary data necessary for the layout defined by **modifier**.
If the proc is NULL, no auxiliary planes are required for any layout supported by
**screen** and the number of planes can be derived directly from **format**.
Thread safety
-------------

View File

@@ -180,6 +180,17 @@ rbug_screen_is_dmabuf_modifier_supported(struct pipe_screen *_screen,
external_only);
}
static unsigned int
rbug_screen_get_dmabuf_modifier_planes(struct pipe_screen *_screen,
uint64_t modifier,
enum pipe_format format)
{
struct rbug_screen *rb_screen = rbug_screen(_screen);
struct pipe_screen *screen = rb_screen->screen;
return screen->get_dmabuf_modifier_planes(screen, modifier, format);
}
static struct pipe_context *
rbug_screen_context_create(struct pipe_screen *_screen,
void *priv, unsigned flags)
@@ -443,6 +454,7 @@ rbug_screen_create(struct pipe_screen *screen)
rb_screen->base.is_format_supported = rbug_screen_is_format_supported;
SCR_INIT(query_dmabuf_modifiers);
SCR_INIT(is_dmabuf_modifier_supported);
SCR_INIT(get_dmabuf_modifier_planes);
rb_screen->base.context_create = rbug_screen_context_create;
SCR_INIT(can_create_resource);
rb_screen->base.resource_create = rbug_screen_resource_create;

View File

@@ -263,6 +263,22 @@ iris_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
return false;
}
static unsigned int
iris_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier,
enum pipe_format format)
{
unsigned int planes = util_format_get_num_planes(format);
switch (modifier) {
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
case I915_FORMAT_MOD_Y_TILED_CCS:
return 2 * planes;
default:
return planes;
}
}
enum isl_format
iris_image_view_get_format(struct iris_context *ice,
const struct pipe_image_view *img)
@@ -2250,6 +2266,7 @@ 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->get_dmabuf_modifier_planes = iris_get_dmabuf_modifier_planes;
pscreen->resource_create_with_modifiers =
iris_resource_create_with_modifiers;
pscreen->resource_create = u_transfer_helper_resource_create;

View File

@@ -35,6 +35,7 @@
#include "loader/loader.h"
#include "pipe/p_state.h"
#include "util/u_debug.h"
#include "util/format/u_format.h"
#include "util/u_inlines.h"
#include "frontend/drm_driver.h"
@@ -526,6 +527,18 @@ tegra_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
format, external_only);
}
static unsigned int
tegra_screen_get_dmabuf_modifier_planes(struct pipe_screen *pscreen,
uint64_t modifier,
enum pipe_format format)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_dmabuf_modifier_planes ?
screen->gpu->get_dmabuf_modifier_planes(screen->gpu, modifier, format) :
util_format_get_num_planes(format);
}
static struct pipe_memory_object *
tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *handle,
@@ -605,6 +618,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.get_dmabuf_modifier_planes = tegra_screen_get_dmabuf_modifier_planes;
screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle;
return &screen->base;

View File

@@ -887,48 +887,33 @@ dri2_create_image_from_name(__DRIscreen *_screen,
}
static unsigned
dri2_get_modifier_num_planes(uint64_t modifier, int fourcc)
dri2_get_modifier_num_planes(__DRIscreen *_screen,
uint64_t modifier, int fourcc)
{
struct pipe_screen *pscreen = dri_screen(_screen)->base.screen;
const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
if (!map)
return 0;
switch (modifier) {
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
case I915_FORMAT_MOD_Y_TILED_CCS:
return 2 * util_format_get_num_planes(map->pipe_format);
case DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED:
case DRM_FORMAT_MOD_ARM_AFBC(
AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_SPARSE |
AFBC_FORMAT_MOD_YTR):
case DRM_FORMAT_MOD_ARM_AFBC(
AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
AFBC_FORMAT_MOD_SPARSE):
case DRM_FORMAT_MOD_BROADCOM_UIF:
case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
case DRM_FORMAT_MOD_LINEAR:
/* DRM_FORMAT_MOD_NONE is the same as LINEAR */
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB:
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB:
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB:
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB:
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB:
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB:
case DRM_FORMAT_MOD_QCOM_COMPRESSED:
case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
case DRM_FORMAT_MOD_VIVANTE_TILED:
/* FD_FORMAT_MOD_QCOM_TILED is not in drm_fourcc.h */
case I915_FORMAT_MOD_X_TILED:
case I915_FORMAT_MOD_Y_TILED:
case DRM_FORMAT_MOD_INVALID:
return util_format_get_num_planes(map->pipe_format);
default:
return 0;
if (!pscreen->is_dmabuf_modifier_supported ||
!pscreen->is_dmabuf_modifier_supported(pscreen, modifier,
map->pipe_format, NULL)) {
return 0;
}
if (pscreen->get_dmabuf_modifier_planes) {
return pscreen->get_dmabuf_modifier_planes(pscreen, modifier,
map->pipe_format);
}
return map->nplanes;
}
}
@@ -944,7 +929,7 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
__DRIimage *img = NULL;
unsigned err = __DRI_IMAGE_ERROR_SUCCESS;
int i;
const int expected_num_fds = dri2_get_modifier_num_planes(modifier, fourcc);
const int expected_num_fds = dri2_get_modifier_num_planes(_screen, modifier, fourcc);
if (!map || expected_num_fds == 0) {
err = __DRI_IMAGE_ERROR_BAD_MATCH;
@@ -1483,7 +1468,8 @@ dri2_query_dma_buf_format_modifier_attribs(__DRIscreen *_screen,
switch (attrib) {
case __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT: {
uint64_t mod_planes = dri2_get_modifier_num_planes(modifier, fourcc);
uint64_t mod_planes = dri2_get_modifier_num_planes(_screen, modifier,
fourcc);
if (mod_planes > 0)
*value = mod_planes;
return mod_planes > 0;

View File

@@ -576,6 +576,27 @@ struct pipe_screen {
bool (*is_dmabuf_modifier_supported)(struct pipe_screen *screen,
uint64_t modifier, enum pipe_format,
bool *external_only);
/**
* Get the number of planes required for a given modifier/format pair.
*
* If not NULL, this function returns the number of planes needed to
* represent \p format in the layout specified by \p modifier, including
* any driver-specific auxiliary data planes.
*
* Must only be called on a modifier supported by the screen for the
* specified format.
*
* If NULL, no auxiliary planes are required for any modifier+format pairs
* supported by \p screen. Hence, the plane count can be derived directly
* from \p format.
*
* \return Number of planes needed to store image data in the layout defined
* by \p format and \p modifier.
*/
unsigned int (*get_dmabuf_modifier_planes)(struct pipe_screen *screen,
uint64_t modifier,
enum pipe_format format);
};