[Mesa-dev] [PATCH v2 2/2] intel: implement createImageFromVABuffer() hook.

Gwenole Beauchesne gb.devel at gmail.com
Fri Sep 14 06:12:59 PDT 2012


Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 src/mesa/drivers/dri/intel/intel_screen.c |  135 ++++++++++++++++++++++++++++-
 1 file changed, 133 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index e3a442c..835f915 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -36,6 +36,11 @@
 #include "main/version.h"
 #include "swrast/s_renderbuffer.h"
 
+#ifdef HAVE_VA_EGL_INTEROP
+#  include <va/va_egl.h>
+#  include <va/va_backend_egl.h>
+#endif
+
 #include "utils.h"
 #include "xmlpool.h"
 
@@ -572,8 +577,133 @@ intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
     return image;
 }
 
+#ifdef HAVE_VA_EGL_INTEROP
+static const struct va_dri_image_descriptor {
+   uint32_t format;
+   uint32_t dri_fourcc;
+   int nplanes;
+} va_dri_image_descriptors[] = {
+   { VA_EGL_PIXEL_FORMAT_ARGB8888, __DRI_IMAGE_FOURCC_ARGB8888, 1 },
+   { VA_EGL_PIXEL_FORMAT_XRGB8888, __DRI_IMAGE_FOURCC_XRGB8888, 1 },
+   { VA_EGL_PIXEL_FORMAT_ABGR8888, __DRI_IMAGE_FOURCC_ABGR8888, 1 },
+   { VA_EGL_PIXEL_FORMAT_NV12, __DRI_IMAGE_FOURCC_NV12, 2 },
+   { VA_EGL_PIXEL_FORMAT_YUV410P, __DRI_IMAGE_FOURCC_YUV410, 3 },
+   { VA_EGL_PIXEL_FORMAT_YUV411P, __DRI_IMAGE_FOURCC_YUV411, 3 },
+   { VA_EGL_PIXEL_FORMAT_YUV420P, __DRI_IMAGE_FOURCC_YUV420, 3 },
+   { VA_EGL_PIXEL_FORMAT_YUV422P, __DRI_IMAGE_FOURCC_YUV422, 3 },
+   { VA_EGL_PIXEL_FORMAT_YUV444P, __DRI_IMAGE_FOURCC_YUV444, 3 },
+};
+
+struct va_dri_image {
+   __DRIimage *image;
+   const struct va_dri_image_descriptor *desc;
+};
+
+static void
+intel_destroy_va_image(struct va_dri_image *img)
+{
+   if (!img)
+      return;
+   if (img->image)
+      intel_destroy_image(img->image);
+   free(img);
+}
+
+static struct va_dri_image *
+intel_create_va_image(__DRIscreen *screen, struct va_egl_client_buffer *buffer)
+{
+   struct va_dri_image *img = NULL;
+   int i, handle, pitches[3], offsets[3];
+
+   for (i = 0; i < ARRAY_SIZE(va_dri_image_descriptors); i++) {
+      if (va_dri_image_descriptors[i].format == buffer->format)
+         break;
+   }
+   if (i == ARRAY_SIZE(va_dri_image_descriptors)) {
+      _mesa_error(NULL, GL_INVALID_OPERATION,
+                  "DRI2-VA: failed to validate pixel format %d",
+                  buffer->format);
+      goto error;
+   }
+
+   img = malloc(sizeof(*img));
+   if (!img) {
+      _mesa_error(NULL, GL_OUT_OF_MEMORY, "DRI2-VA: failed to create VA image");
+      goto error;
+   }
+   img->desc = &va_dri_image_descriptors[i];
+
+   handle = buffer->handle;
+   for (i = 0; i < buffer->num_planes; i++) {
+      pitches[i] = buffer->pitches[i];
+      offsets[i] = buffer->offsets[i];
+   }
+   for (; i < ARRAY_SIZE(pitches); i++) {
+      pitches[i] = 0;
+      offsets[i] = 0;
+   }
+   img->image = intel_create_image_from_names(
+      screen, buffer->width, buffer->height,
+      img->desc->dri_fourcc, &handle, 1, pitches, offsets,
+      NULL);
+   if (!img->image)
+      goto error;
+
+   buffer->private_data = img;
+   buffer->destroy_private_data = (void (*)(void *))intel_destroy_va_image;
+   return img;
+
+error:
+   free(img);
+   return NULL;
+}
+#endif
+
+static __DRIimage *
+intel_create_image_from_va_buffer(__DRIscreen *screen, void *_buffer,
+                                  int buffer_structure, int plane,
+                                  int picture_structure, void *loaderPrivate)
+{
+#ifdef HAVE_VA_EGL_INTEROP
+   struct va_egl_client_buffer * const buffer = _buffer;
+   struct va_dri_image *img;
+
+   if (!buffer || buffer->version != VA_EGL_CLIENT_BUFFER_VERSION) {
+      _mesa_error(NULL, GL_INVALID_VALUE,
+                  "DRI2-VA: unsupported EGLClientBuffer");
+      return NULL;
+   }
+
+   if (buffer_structure && buffer_structure != buffer->structure) {
+      _mesa_error(NULL, GL_INVALID_VALUE,
+                  "DRI2-VA: buffer structure coercition is not supported yet");
+      return NULL;
+   }
+
+   if (picture_structure != VA_EGL_PICTURE_STRUCTURE_FRAME) {
+      _mesa_error(NULL, GL_INVALID_VALUE,
+                  "DRI2-VA: interlaced picture structure is not supported yet");
+      return NULL;
+   }
+
+   img = buffer->private_data;
+   if (!img) {
+      img = intel_create_va_image(screen, buffer);
+      if (!img)
+         return NULL;
+   }
+
+   if (plane >= img->desc->nplanes) {
+      _mesa_error(NULL, GL_INVALID_VALUE, "DRI2-VA: invalid plane index");
+      return NULL;
+   }
+   return intel_from_planar(img->image, plane, loaderPrivate);
+#endif
+   return NULL;
+}
+
 static struct __DRIimageExtensionRec intelImageExtension = {
-    { __DRI_IMAGE, 5 },
+    { __DRI_IMAGE, 6 },
     intel_create_image_from_name,
     intel_create_image_from_renderbuffer,
     intel_destroy_image,
@@ -582,7 +712,8 @@ static struct __DRIimageExtensionRec intelImageExtension = {
     intel_dup_image,
     intel_validate_usage,
     intel_create_image_from_names,
-    intel_from_planar
+    intel_from_planar,
+    intel_create_image_from_va_buffer
 };
 
 static const __DRIextension *intelScreenExtensions[] = {
-- 
1.7.9.5



More information about the mesa-dev mailing list