[Mesa-dev] [PATCH v14 35/36] i965: Support dmabuf import with modifiers
Varad Gautam
varadgautam at gmail.com
Tue May 30 11:54:08 UTC 2017
From: Varad Gautam <varad.gautam at collabora.com>
Add support for createImageFromDmaBufs2, adding a modifier to the
original, and allow importing CCS resources with auxiliary data from
dmabufs.
v2: avoid DRIimageExtension version bump, pass single modifier to
createImageFromDmaBufs2.
Signed-off-by: Varad Gautam <varadgautam at gmail.com>
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 6 ++
src/mesa/drivers/dri/i965/intel_screen.c | 127 +++++++++++++++++++++-----
2 files changed, 111 insertions(+), 22 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 962d220..0693b94 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -848,6 +848,12 @@ intel_miptree_create_for_image(struct brw_context *intel,
assert(mt->logical_depth0 == 1);
create_ccs_buf_for_image(intel, image, mt);
+ if (image->dma_buf_imported)
+ /* We have an imported image with aux data. Mark it unresolved.
+ */
+ intel_miptree_set_fast_clear_state(intel, mt, mt->first_level,
+ 0, mt->logical_depth0,
+ INTEL_FAST_CLEAR_STATE_UNRESOLVED);
return mt;
}
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 857983d..ddbb43b 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -920,16 +920,19 @@ intel_create_image_from_names(__DRIscreen *dri_screen,
}
static __DRIimage *
-intel_create_image_from_fds(__DRIscreen *dri_screen,
- int width, int height, int fourcc,
- int *fds, int num_fds, int *strides, int *offsets,
- void *loaderPrivate)
+intel_create_image_from_fds_common(__DRIscreen *dri_screen,
+ int width, int height, int fourcc,
+ uint64_t modifier, int *fds,
+ int num_fds, int *strides,
+ int *offsets, void *loaderPrivate)
{
struct intel_screen *screen = dri_screen->driverPrivate;
struct intel_image_format *f;
__DRIimage *image;
struct brw_bo *bo;
- uint32_t tiling = I915_TILING_X; /* default to X-tiling */
+ uint32_t tiling;
+ unsigned tiled_height;
+ unsigned ccs_height;
int i, index, size = 0;
if (fds == NULL || num_fds < 1)
@@ -939,16 +942,33 @@ intel_create_image_from_fds(__DRIscreen *dri_screen,
if (f == NULL)
return NULL;
+ switch (modifier) {
+ case fourcc_mod_code(INTEL, 4):
+ tiling = modifier_to_tiling(modifier);
+ ccs_height = get_aux_height(modifier, height);
+ case DRM_FORMAT_MOD_INVALID:
+ /* X-tiling is the default, and also allows us to infer the tiling
+ * mode from the BO */
+ tiling = I915_TILING_X;
+ ccs_height = 0;
+ default:
+ return NULL;
+ }
+ tiled_height = get_tiled_height(tiling, height);
+
for (i = 0; i < f->nplanes; i++) {
index = f->planes[i].buffer_index;
- const int plane_height = height >> f->planes[i].height_shift;
- const int end = offsets[index] + plane_height * strides[index];
+ const int plane_height = tiled_height >> f->planes[i].height_shift;
+ const int end = offsets[index] +
+ (plane_height + ccs_height) * strides[index];
+
if (size < end)
size = end;
}
- /* We only support all planes from the same bo.
- * brw_bo_gem_create_from_prime() should return the same pointer for all
- * fds received here */
+
+ /* We only support all planes from the same bo. Check that
+ * brw_bo_gem_create_from_prime() returns the same pointer for all
+ * fds received here. */
bo = brw_bo_gem_create_from_prime(screen->bufmgr, fds[0], size, tiling);
for (i = 1; i < num_fds; i++) {
if (bo != brw_bo_gem_create_from_prime(screen->bufmgr, fds[i],
@@ -971,16 +991,10 @@ intel_create_image_from_fds(__DRIscreen *dri_screen,
image->pitch = strides[0];
image->planar_format = f;
- int size = 0;
for (i = 0; i < f->nplanes; i++) {
index = f->planes[i].buffer_index;
image->offsets[index] = offsets[index];
image->strides[index] = strides[index];
-
- const int plane_height = height >> f->planes[i].height_shift;
- const int end = offsets[index] + plane_height * strides[index];
- if (size < end)
- size = end;
}
image->bo = brw_bo_gem_create_from_prime(screen->bufmgr, fds[0], size,
@@ -989,10 +1003,18 @@ intel_create_image_from_fds(__DRIscreen *dri_screen,
free(image);
return NULL;
}
- image->modifier = tiling_to_modifier(image->bo->tiling_mode);
+
+ /* If we've explicitly specified a modifier, then we use that; else
+ * we infer the modifier from the BO's tiling mode. */
+ if (modifier != DRM_FORMAT_MOD_INVALID)
+ image->modifier = modifier;
+ else
+ image->modifier = tiling_to_modifier(image->bo->tiling_mode);
if (f->nplanes == 1) {
image->offset = image->offsets[0];
+ if (ccs_height)
+ image->aux_offset = tiled_height * image->pitch;
intel_image_warn_if_unaligned(image, __func__);
}
@@ -1000,9 +1022,21 @@ intel_create_image_from_fds(__DRIscreen *dri_screen,
}
static __DRIimage *
-intel_create_image_from_dma_bufs(__DRIscreen *dri_screen,
+intel_create_image_from_fds(__DRIscreen *dri_screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds, int *strides, int *offsets,
+ void *loaderPrivate)
+{
+ return intel_create_image_from_fds_common(dri_screen, width, height,
+ fourcc, DRM_FORMAT_MOD_INVALID,
+ fds, num_fds, strides, offsets,
+ loaderPrivate);
+}
+
+static __DRIimage *
+intel_create_image_from_dma_bufs_common(__DRIscreen *dri_screen,
int width, int height, int fourcc,
- int *fds, int num_fds,
+ uint64_t modifier, int *fds, int num_fds,
int *strides, int *offsets,
enum __DRIYUVColorSpace yuv_color_space,
enum __DRISampleRange sample_range,
@@ -1019,9 +1053,10 @@ intel_create_image_from_dma_bufs(__DRIscreen *dri_screen,
return NULL;
}
- image = intel_create_image_from_fds(dri_screen, width, height, fourcc, fds,
- num_fds, strides, offsets,
- loaderPrivate);
+ image = intel_create_image_from_fds_common(dri_screen, width, height,
+ fourcc, modifier, fds, num_fds,
+ strides, offsets,
+ loaderPrivate);
/*
* Invalid parameters and any inconsistencies between are assumed to be
@@ -1044,6 +1079,53 @@ intel_create_image_from_dma_bufs(__DRIscreen *dri_screen,
}
static __DRIimage *
+intel_create_image_from_dma_bufs(__DRIscreen *dri_screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace yuv_color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horizontal_siting,
+ enum __DRIChromaSiting vertical_siting,
+ unsigned *error,
+ void *loaderPrivate)
+{
+ return intel_create_image_from_dma_bufs_common(dri_screen, width, height,
+ fourcc,
+ DRM_FORMAT_MOD_INVALID,
+ fds, num_fds,
+ strides, offsets,
+ yuv_color_space,
+ sample_range,
+ horizontal_siting,
+ vertical_siting, error,
+ loaderPrivate);
+}
+
+static __DRIimage *
+intel_create_image_from_dma_bufs2(__DRIscreen *dri_screen,
+ int width, int height, int fourcc,
+ uint64_t modifier,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace yuv_color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horizontal_siting,
+ enum __DRIChromaSiting vertical_siting,
+ unsigned *error,
+ void *loaderPrivate)
+{
+ return intel_create_image_from_dma_bufs_common(dri_screen, width, height,
+ fourcc, modifier, fds,
+ num_fds, strides, offsets,
+ yuv_color_space,
+ sample_range,
+ horizontal_siting,
+ vertical_siting, error,
+ loaderPrivate);
+}
+
+static __DRIimage *
intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
{
int width, height, offset, stride, dri_format, index;
@@ -1122,6 +1204,7 @@ static const __DRIimageExtension intelImageExtension = {
.mapImage = NULL,
.unmapImage = NULL,
.createImageWithModifiers = intel_create_image_with_modifiers,
+ .createImageFromDmaBufs2 = intel_create_image_from_dma_bufs2,
};
static uint64_t
--
2.10.0
More information about the mesa-dev
mailing list