[Mesa-dev] [PATCH v3] i965: Support dmabuf import with modifiers

Varad Gautam varadgautam at gmail.com
Tue Jun 6 14:00:13 UTC 2017


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.
v3: rebase to 'i965: Improve same-buffer restriction for imports' v2

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      | 114 +++++++++++++++++++++++---
 2 files changed, 107 insertions(+), 13 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 0469960..30ec9d2 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,10 +942,26 @@ 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;
    }
@@ -988,10 +1007,18 @@ intel_create_image_from_fds(__DRIscreen *dri_screen,
    }
 
    image->bo = bo;
-   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__);
    }
 
@@ -999,9 +1026,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,
@@ -1018,9 +1057,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
@@ -1043,6 +1083,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;
@@ -1121,6 +1208,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