[PATCH 2/3] Add dri image entry point for creating image from fd

Kristian Høgsberg krh at bitplanet.net
Wed Feb 27 17:52:50 PST 2013


---
 include/GL/internal/dri_interface.h        | 14 +++++++-
 src/mesa/drivers/dri/intel/intel_regions.c | 33 +++++++++++++++++++
 src/mesa/drivers/dri/intel/intel_regions.h |  6 ++++
 src/mesa/drivers/dri/intel/intel_screen.c  | 53 ++++++++++++++++++++++++++++--
 4 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 42147e9..a1392ab 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -938,7 +938,7 @@ struct __DRIdri2ExtensionRec {
  * extensions.
  */
 #define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 6
+#define __DRI_IMAGE_VERSION 7
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -1021,6 +1021,9 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_ATTRIB_WIDTH	0x2004 /* available in versions 4+ */
 #define __DRI_IMAGE_ATTRIB_HEIGHT	0x2005
 #define __DRI_IMAGE_ATTRIB_COMPONENTS	0x2006 /* available in versions 5+ */
+#define __DRI_IMAGE_ATTRIB_FD           0x2007 /* available in versions
+                                                * 7+. Each query will return a
+                                                * new fd. */
 
 /**
  * \name Reasons that __DRIimageExtensionRec::createImageFromTexture might fail
@@ -1117,6 +1120,15 @@ struct __DRIimageExtensionRec {
                                          int level,
                                          unsigned *error,
                                          void *loaderPrivate);
+   /**
+    * Like createImageFromNames, but takes a prime fd instead.
+    *
+    * \since 7
+    */
+   __DRIimage *(*createImageFromFd)(__DRIscreen *screen,
+                                    int width, int height, int fourcc,
+                                    int fd, int *strides, int *offsets,
+                                    void *loaderPrivate);
 };
 
 
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 89d91b0..74f191f 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -284,6 +284,39 @@ intel_region_alloc_for_handle(struct intel_screen *screen,
    return region;
 }
 
+struct intel_region *
+intel_region_alloc_for_fd(struct intel_screen *screen,
+                          GLuint cpp,
+                          GLuint width, GLuint height, GLuint pitch,
+                          int fd, const char *name)
+{
+   struct intel_region *region;
+   drm_intel_bo *buffer;
+   int ret;
+   uint32_t bit_6_swizzle, tiling;
+
+   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr,
+                                               fd, height * pitch);
+   if (buffer == NULL)
+      return NULL;
+   ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
+   if (ret != 0) {
+      fprintf(stderr, "Couldn't get tiling of buffer (%s): %s\n",
+	      name, strerror(-ret));
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   region = intel_region_alloc_internal(screen, cpp,
+					width, height, pitch, tiling, buffer);
+   if (region == NULL) {
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   return region;
+}
+
 void
 intel_region_reference(struct intel_region **dst, struct intel_region *src)
 {
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 28d581c..6757cc2 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -89,6 +89,12 @@ intel_region_alloc_for_handle(struct intel_screen *screen,
 			      GLuint width, GLuint height, GLuint pitch,
 			      unsigned int handle, const char *name);
 
+struct intel_region *
+intel_region_alloc_for_fd(struct intel_screen *screen,
+                          GLuint cpp,
+                          GLuint width, GLuint height, GLuint pitch,
+                          int fd, const char *name);
+
 bool
 intel_region_flink(struct intel_region *region, uint32_t *name);
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 277b133..3ee0d69 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -546,6 +546,9 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
          return false;
       *value = image->planar_format->components;
       return true;
+   case __DRI_IMAGE_ATTRIB_FD:
+      drm_intel_bo_gem_export_to_prime(image->region->bo, value);
+      return true;
   default:
       return false;
    }
@@ -623,8 +626,8 @@ intel_create_image_from_names(__DRIscreen *screen,
                                          names[0], strides[0],
                                          loaderPrivate);
 
-    if (image == NULL)
-        return NULL;
+   if (image == NULL)
+      return NULL;
 
     image->planar_format = f;
     for (i = 0; i < f->nplanes; i++) {
@@ -637,6 +640,49 @@ intel_create_image_from_names(__DRIscreen *screen,
 }
 
 static __DRIimage *
+intel_create_image_from_fd(__DRIscreen *screen,
+                           int width, int height, int fourcc,
+                           int fd, int *strides, int *offsets,
+                           void *loaderPrivate)
+{
+   struct intel_screen *intelScreen = screen->driverPrivate;
+   struct intel_image_format *f = NULL;
+   __DRIimage *image;
+   int i, index;
+
+   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)
+      return NULL;
+
+   image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
+   if (image == NULL)
+      return NULL;
+
+   image->region = intel_region_alloc_for_fd(intelScreen,
+                                             1, width, height,
+                                             strides[0], fd, "image");
+   if (image->region == 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];
+   }
+
+   return image;
+}
+
+
+static __DRIimage *
 intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
 {
     int width, height, offset, stride, dri_format, index;
@@ -693,7 +739,7 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
 }
 
 static struct __DRIimageExtensionRec intelImageExtension = {
-    .base = { __DRI_IMAGE, 6 },
+    .base = { __DRI_IMAGE, 7 },
 
     .createImageFromName                = intel_create_image_from_name,
     .createImageFromRenderbuffer        = intel_create_image_from_renderbuffer,
@@ -705,6 +751,7 @@ static struct __DRIimageExtensionRec intelImageExtension = {
     .createImageFromNames               = intel_create_image_from_names,
     .fromPlanar                         = intel_from_planar,
     .createImageFromTexture             = intel_create_image_from_texture
+    .createImageFromFd                  = intel_create_image_from_fd
 };
 
 static const __DRIextension *intelScreenExtensions[] = {
-- 
1.8.1.2



More information about the wayland-devel mailing list