[Mesa-dev] [PATCH 4/8] intel: prepare for dri images having more than plane

Topi Pohjolainen topi.pohjolainen at intel.com
Tue Apr 16 03:45:03 PDT 2013


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/intel/intel_screen.c | 101 +++++++++++++++++++++---------
 1 file changed, 71 insertions(+), 30 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 3d0344e..8716688 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -496,8 +496,14 @@ intel_create_image_from_texture(__DRIcontext *context, int target,
 static void
 intel_destroy_image(__DRIimage *image)
 {
-    intel_region_release(&image->regions[0]);
-    free(image);
+   int i;
+
+   for (i = 0; i < sizeof(image->regions) / sizeof(struct intel_region); ++i) {
+      if (image->regions[i]->bo)
+         intel_region_release(&image->regions[i]);
+   }
+
+   free(image);
 }
 
 static __DRIimage *
@@ -571,16 +577,25 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
 static __DRIimage *
 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
 {
+   int i;
    __DRIimage *image;
 
    image = calloc(1, sizeof *image);
    if (image == NULL)
       return NULL;
 
-   intel_region_reference(&image->regions[0], orig_image->regions[0]);
-   if (image->regions[0] == NULL) {
-      free(image);
-      return NULL;
+   for (i = 0; i < sizeof(image->regions) / sizeof(struct intel_region); ++i) {
+      if (!orig_image->regions[i]->bo)
+         break;
+
+      intel_region_reference(&image->regions[i], orig_image->regions[i]);
+      if (image->regions[i] == NULL) {
+         for (--i; i >= 0; --i)
+            intel_region_release(&image->regions[i]);
+
+	 free(image);
+         return NULL;
+      }
    }
 
    image->internal_format = orig_image->internal_format;
@@ -649,45 +664,71 @@ intel_create_image_from_names(__DRIscreen *screen,
 }
 
 static __DRIimage *
+intel_setup_image_from_fds(struct intel_screen *screen, int width, int height,
+                           const struct intel_image_format *f,
+                           const int *fds, int num_fds, const int *strides,
+                           void *loaderPriv)
+{
+   int i;
+   __DRIimage *img = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPriv);
+
+   if (img == NULL)
+      return NULL;
+
+   for (i = 0; i < num_fds; i++) {
+      img->regions[i] = intel_region_alloc_for_fd(screen, f->planes[i].cpp,
+                           width >> f->planes[i].width_shift,
+                           height >> f->planes[i].height_shift,
+                           strides[i], fds[i], "image");
+
+      if (img->regions[i] == NULL) {
+         for (--i; i >= 0; --i)
+            intel_region_release(&img->regions[i]);
+
+         free(img);
+         return NULL;
+      }
+   }
+
+   return img;
+}
+
+static __DRIimage *
 intel_create_image_from_fds(__DRIscreen *screen,
                             int width, int height, int fourcc,
                             int *fds, int num_fds, int *strides, int *offsets,
                             void *loaderPrivate)
 {
    struct intel_screen *intelScreen = screen->driverPrivate;
-   struct intel_image_format *f = NULL;
+   struct intel_image_format *f = intel_image_format_lookup(fourcc);
    __DRIimage *image;
    int i, index;
 
-   if (fds == NULL || num_fds != 1)
-      return NULL;
-
-   for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
-      if (intel_image_formats[i].fourcc == fourcc) {
-         f = &intel_image_formats[i];
-      }
-   }
-
-   if (f == NULL)
+   /**
+    * In case the image is to consist of multiple regions, there must be exactly
+    * one region per plane.
+    */
+   if (fds == NULL || f == NULL || (num_fds > 1 && f->nplanes != num_fds))
       return NULL;
 
-   image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
+   image = intel_setup_image_from_fds(intelScreen, width, height, f,
+                                      fds, num_fds, strides, loaderPrivate);
    if (image == NULL)
       return NULL;
 
-   image->regions[0] = intel_region_alloc_for_fd(intelScreen,
-                                             1, width, height,
-                                             strides[0], fds[0], "image");
-   if (image->regions[0] == NULL) {
-      free(image);
-      return NULL;
-   }
-
    image->planar_format = f;
-   for (i = 0; i < f->nplanes; i++) {
-      index = f->planes[i].buffer_index;
-      image->offsets[index] = offsets[index];
-      image->strides[index] = strides[index];
+
+   /**
+    * In case the image is to consist of multiple planes all in the same region,
+    * one needs to record not only the invidual strides, but also the locations
+    * of the planes within the region.
+    */
+   if (num_fds == 1 && f->nplanes > 1) {
+      for (i = 0; i < f->nplanes; i++) {
+         index = f->planes[i].buffer_index;
+         image->offsets[index] = offsets[index];
+         image->strides[index] = strides[index];
+      }
    }
 
    return image;
-- 
1.8.1.2



More information about the mesa-dev mailing list