Add dri image entry point for creating image from fd
authorKristian Høgsberg <krh@bitplanet.net>
Sat, 2 Feb 2013 13:38:07 +0000 (08:38 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 19 Mar 2013 01:03:54 +0000 (21:03 -0400)
Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
include/GL/internal/dri_interface.h
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_screen.c

index 42147e90ebd2cf5e32bf952ebbec226ece3704a9..30ce175e6f0077a9d2772c6c31fe2eeb704b8f4e 100644 (file)
@@ -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);
 };
 
 
index 90b985d0b977d000d6eea75d14f32fc9d7a003c6..44f7030c712f4cc5a6d285709d3afc59f0c9f012 100644 (file)
@@ -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)
 {
index 06a4b989e88cbec273e43fcb74d48f057df75caa..1fb6b2757721bd102f56018b07b5179dbb855e73 100644 (file)
@@ -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);
 
index 0d39b9d3b302ec16d314b57e7bee7fec2e8f5194..32e92594c0821fe8c976d7ef76b0f8a7bb9ad982 100644 (file)
@@ -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++) {
@@ -636,6 +640,52 @@ intel_create_image_from_names(__DRIscreen *screen,
     return image;
 }
 
+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)
 {
@@ -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[] = {