Add dri image entry point for creating image from fd
[mesa.git] / src / mesa / drivers / dri / intel / intel_screen.c
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[] = {