Mesa (master): Add dri image entry point for creating image from fd

Kristian Høgsberg krh at kemper.freedesktop.org
Tue Mar 19 01:45:23 UTC 2013


Module: Mesa
Branch: master
Commit: 2356e28452454ed3b584af9b4d28c553c2a80769
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2356e28452454ed3b584af9b4d28c553c2a80769

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Sat Feb  2 08:38:07 2013 -0500

Add dri image entry point for creating image from fd

Reviewed-by: Ander Conselvan de Oliveira <conselvan2 at gmail.com>

---

 include/GL/internal/dri_interface.h        |   15 +++++++-
 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  |   59 ++++++++++++++++++++++++++--
 4 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 42147e9..30ce175 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,16 @@ struct __DRIimageExtensionRec {
                                          int level,
                                          unsigned *error,
                                          void *loaderPrivate);
+   /**
+    * Like createImageFromNames, but takes a prime fd instead.
+    *
+    * \since 7
+    */
+   __DRIimage *(*createImageFromFds)(__DRIscreen *screen,
+                                     int width, int height, int fourcc,
+                                     int *fds, int num_fds,
+                                     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 90b985d..44f7030 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -205,6 +205,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 06a4b98..1fb6b27 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -87,6 +87,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 0d39b9d..32e9259 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -546,6 +546,10 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
          return false;
       *value = image->planar_format->components;
       return true;
+   case __DRI_IMAGE_ATTRIB_FD:
+      if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0)
+         return true;
+      return false;
   default:
       return false;
    }
@@ -623,8 +627,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 +641,52 @@ intel_create_image_from_names(__DRIscreen *screen,
 }
 
 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;
+   __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)
+      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], fds[0], "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;
@@ -692,7 +742,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,
@@ -703,7 +753,8 @@ static struct __DRIimageExtensionRec intelImageExtension = {
     .validateUsage                      = intel_validate_usage,
     .createImageFromNames               = intel_create_image_from_names,
     .fromPlanar                         = intel_from_planar,
-    .createImageFromTexture             = intel_create_image_from_texture
+    .createImageFromTexture             = intel_create_image_from_texture,
+    .createImageFromFds                 = intel_create_image_from_fds
 };
 
 static const __DRIextension *intelScreenExtensions[] = {




More information about the mesa-commit mailing list