[Mesa-dev] [PATCH 4/4] egl: Add EGL_MESA_create_image extension

Kristian Høgsberg krh at bitplanet.net
Thu May 27 18:41:47 PDT 2010


---
 include/EGL/eglext.h                       |   18 +++++
 include/GL/internal/dri_interface.h        |   13 +++
 src/egl/drivers/dri2/egl_dri2.c            |  110 ++++++++++++++++++++++++++++
 src/egl/main/eglapi.c                      |   21 +++++-
 src/egl/main/eglapi.h                      |    9 ++
 src/mesa/drivers/dri/intel/intel_regions.c |   19 +++++
 src/mesa/drivers/dri/intel/intel_regions.h |    5 +
 src/mesa/drivers/dri/intel/intel_screen.c  |   75 +++++++++++++++++++
 8 files changed, 269 insertions(+), 1 deletions(-)

diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index 664fe55..db6b8e9 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -120,6 +120,24 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGL
 #define EGL_GL_RENDERBUFFER_KHR			0x30B9	/* eglCreateImageKHR target */
 #endif
 
+/* FIXME: Unauthorized enum valus ahead! */
+#ifndef EGL_MESA_create_image
+#define EGL_MESA_create_image 1
+#define EGL_NEW_IMAGE_MESA			0x8080	/* eglCreateImageKHR target */
+#define EGL_IMAGE_FORMAT_MESA			0x8083	/* eglCreateImageKHR attribute */
+#define EGL_IMAGE_USE_MESA			0x8086	/* eglCreateImageKHR attribute */
+
+#define EGL_IMAGE_USE_SCANOUT_MESA		0x0002	/* EGL_IMAGE_USE_MESA value */
+
+#define EGL_IMAGE_HANDLE_MESA			0x8084	/* eglQueryImageKHR attribute */
+#define EGL_IMAGE_STRIDE_MESA			0x8085	/* eglQueryImageKHR attribute */
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint attribute, EGLint *value);
+#endif
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint attribute, EGLint *value);
+#endif
+
 #ifndef EGL_KHR_reusable_sync
 #define EGL_KHR_reusable_sync 1
 
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index e4c2b3a..57d6511 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -807,6 +807,9 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_FORMAT_XRGB8888     0x1002
 #define __DRI_IMAGE_FORMAT_ARGB8888     0x1003
 
+#define __DRI_IMAGE_USE_SHARE		0x0001
+#define __DRI_IMAGE_USE_SCANOUT		0x0002
+
 typedef struct __DRIimageRec          __DRIimage;
 typedef struct __DRIimageExtensionRec __DRIimageExtension;
 struct __DRIimageExtensionRec {
@@ -822,8 +825,18 @@ struct __DRIimageExtensionRec {
 					       void *loaderPrivate);
 
     void (*destroyImage)(__DRIimage *image);
+
+    /* Since version 2 */
+    __DRIimage *(*createImage)(__DRIcontext *context,
+			       int width, int height, int format,
+			       unsigned int use,
+			       void *loaderPrivate);
+
+    GLboolean (*queryImage)(__DRIimage *image,
+			    int *format, uint32_t *handle, int *pitch);
 };
 
+
 /**
  * This extension must be implemented by the loader and passed to the
  * driver at screen creation time.  The EGLImage entry points in the
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 7779cd8..9c81077 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1525,6 +1525,78 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
 }
 
 static _EGLImage *
+dri2_create_image_khr_mesa(_EGLDisplay *disp, _EGLContext *ctx,
+			   EGLClientBuffer buffer,
+			   const EGLint *attr_list)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+   struct dri2_egl_image *dri2_img;
+   int width, height, format, i;
+   unsigned int use;
+
+   dri2_img = malloc(sizeof *dri2_img);
+   if (!dri2_img) {
+      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   if (!_eglInitImage(&dri2_img->base, disp, attr_list)) {
+      free(dri2_img);
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   if (!attr_list) {
+      free(dri2_img);
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   for (i = 0; attr_list[i] != EGL_NONE; i += 2) {
+      EGLint attr = attr_list[i];
+      EGLint val = attr_list[i + 1];
+
+      switch (attr) {
+      case EGL_WIDTH:
+	 width = val;
+         break;
+      case EGL_HEIGHT:
+	 height = val;
+         break;
+      case EGL_IMAGE_FORMAT_MESA:
+	 format = val;
+         break;
+      case EGL_IMAGE_USE_MESA:
+	 use = val;
+         break;
+      }
+   }
+
+   switch (format) {
+   case EGL_FORMAT_RGB_565_KHR:
+      format = __DRI_IMAGE_FORMAT_RGB565;
+      break;
+   case EGL_FORMAT_RGBA_8888_KHR:
+      format = __DRI_IMAGE_FORMAT_XRGB8888;
+      break;
+   default:
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      free(dri2_img);
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   dri2_img->dri_image = 
+      dri2_dpy->image->createImage(dri2_ctx->dri_context,
+				   width, height, format, use, dri2_img);
+   if (dri2_img->dri_image == NULL) {
+      free(dri2_img);
+      return EGL_NO_IMAGE_KHR;
+   }      
+
+   return &dri2_img->base;
+}
+
+static _EGLImage *
 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 		      _EGLContext *ctx, EGLenum target,
 		      EGLClientBuffer buffer, const EGLint *attr_list)
@@ -1534,6 +1606,8 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
       return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
    case EGL_GL_RENDERBUFFER_KHR:
       return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
+   case EGL_NEW_IMAGE_MESA:
+      return dri2_create_image_khr_mesa(disp, ctx, buffer, attr_list);
    default:
       _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
       return EGL_NO_IMAGE_KHR;
@@ -1552,6 +1626,41 @@ dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
    return EGL_TRUE;
 }
 
+static EGLBoolean 
+dri2_query_image_mesa(_EGLDriver *drv, _EGLDisplay *disp,
+		      _EGLImage *image, EGLint attribute, EGLint *value)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_image *dri2_img = dri2_egl_image(image);
+   int format, pitch;
+   uint32_t handle;
+
+   dri2_dpy->image->queryImage(dri2_img->dri_image,
+			       &format, &handle, &pitch);
+   switch (format) {
+   case __DRI_IMAGE_FORMAT_RGB565:
+      format = EGL_FORMAT_RGB_565_KHR;
+      break;
+   case __DRI_IMAGE_FORMAT_XRGB8888:
+      format = EGL_FORMAT_RGBA_8888_KHR;
+      break;
+   }
+
+   switch (attribute) {
+   case EGL_IMAGE_FORMAT_MESA:
+      *value = format;
+      return EGL_TRUE;
+   case EGL_IMAGE_HANDLE_MESA:
+      *value = handle;
+      return EGL_TRUE;
+   case EGL_IMAGE_STRIDE_MESA:
+      *value = pitch;
+      return EGL_TRUE;
+   }
+
+   return EGL_FALSE;
+}
+
 /**
  * This is the main entrypoint into the driver, called by libEGL.
  * Create a new _EGLDriver object and init its dispatch table.
@@ -1585,6 +1694,7 @@ _eglMain(const char *args)
    dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
    dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
    dri2_drv->base.API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
+   dri2_drv->base.API.QueryImageMESA = dri2_query_image_mesa;
 
    dri2_drv->base.Name = "DRI2";
    dri2_drv->base.Unload = dri2_unload;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index d158714..86a3122 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -1258,7 +1258,6 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
    RETURN_EGL_EVAL(disp, ret);
 }
 
-
 #endif /* EGL_KHR_image_base */
 
 
@@ -1289,3 +1288,23 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
 }
 
 #endif /* EGL_NOK_swap_region */
+
+#ifdef EGL_MESA_create_image
+
+EGLBoolean
+eglQueryImageMESA(EGLDisplay dpy, EGLImageKHR image,
+		   EGLint attribute, EGLint *value)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLImage *img = _eglLookupImage(image, disp);
+   _EGLDriver *drv;
+   EGLBoolean ret;
+
+   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+   ret = drv->API.QueryImageMESA(drv, disp, img, attribute, value);
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
+#endif /* EGL_MESA_create_image */
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index d8c8b49..8f75fc6 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -80,6 +80,11 @@ typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLI
 typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
 #endif
 
+#ifdef EGL_MESA_create_image
+typedef EGLBoolean (*QueryImageIntel_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image, EGLint attribute, EGLint *value);
+#endif
+
+
 /**
  * The API dispatcher jumps through these functions
  */
@@ -141,6 +146,10 @@ struct _egl_api
 #ifdef EGL_NOK_swap_region
    SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
 #endif
+
+#ifdef EGL_MESA_create_image
+   QueryImageIntel_t QueryImageMESA;
+#endif
 };
 
 #endif /* EGLAPI_INCLUDED */
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 8cdeaf6..2564b81 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -194,6 +194,25 @@ intel_region_alloc(struct intel_context *intel,
    return region;
 }
 
+GLboolean
+intel_region_flink(struct intel_context *intel,
+		   struct intel_region *region,
+		   uint32_t target_context, uint32_t *name)
+{
+   if (region->name == 0) {
+      if (drm_intel_bo_flink(region->buffer, &region->name))
+	 return GL_FALSE;
+      
+      region->screen = intel->intelScreen;
+      _mesa_HashInsert(intel->intelScreen->named_regions,
+		       region->name, region);
+   }
+
+   *name = region->name;
+
+   return GL_TRUE;
+}
+
 struct intel_region *
 intel_region_alloc_for_handle(struct intel_context *intel,
 			      GLuint cpp,
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 2459c9a..dac9d84 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -87,6 +87,11 @@ intel_region_alloc_for_handle(struct intel_context *intel,
 			      GLuint width, GLuint height, GLuint pitch,
 			      unsigned int handle, const char *name);
 
+GLboolean
+intel_region_flink(struct intel_context *intel,
+		   struct intel_region *region,
+		   uint32_t target_context, uint32_t *name);
+
 void intel_region_reference(struct intel_region **dst,
                             struct intel_region *src);
 
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 15a465c..611a98a 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -206,11 +206,86 @@ intel_destroy_image(__DRIimage *image)
     FREE(image);
 }
 
+static __DRIimage *
+intel_create_image(__DRIcontext *context,
+		   int width, int height, int format,
+		   unsigned int use,
+		   void *loaderPrivate)
+{
+   __DRIimage *image;
+   struct intel_context *intel = context->driverPrivate;
+   int cpp;
+
+   image = CALLOC(sizeof *image);
+   if (image == NULL)
+      return NULL;
+
+   switch (format) {
+   case __DRI_IMAGE_FORMAT_RGB565:
+      image->format = MESA_FORMAT_RGB565;
+      image->internal_format = GL_RGB;
+      image->data_type = GL_UNSIGNED_BYTE;
+      break;
+   case __DRI_IMAGE_FORMAT_XRGB8888:
+      image->format = MESA_FORMAT_XRGB8888;
+      image->internal_format = GL_RGB;
+      image->data_type = GL_UNSIGNED_BYTE;
+      break;
+   case __DRI_IMAGE_FORMAT_ARGB8888:
+      image->format = MESA_FORMAT_ARGB8888;
+      image->internal_format = GL_RGBA;
+      image->data_type = GL_UNSIGNED_BYTE;
+      break;
+   default:
+      free(image);
+      return NULL;
+   }
+
+   image->data = loaderPrivate;
+   cpp = _mesa_get_format_bytes(image->format);
+
+   image->region =
+      intel_region_alloc(intel, I915_TILING_NONE,
+			 cpp, width, height, GL_TRUE);
+   if (image->region == NULL) {
+      FREE(image);
+      return NULL;
+   }
+   
+   return image;
+}
+
+
+
+static GLboolean
+intel_query_image(__DRIimage *image,
+		  int *format, uint32_t *handle, int *pitch)
+{
+   switch (image->format) {
+   case MESA_FORMAT_RGB565:
+      *format = __DRI_IMAGE_FORMAT_RGB565;
+      break;
+   case MESA_FORMAT_XRGB8888:
+      *format = __DRI_IMAGE_FORMAT_XRGB8888;
+      break;
+   case MESA_FORMAT_ARGB8888:
+      *format = __DRI_IMAGE_FORMAT_ARGB8888;
+      break;
+   }
+   
+   *handle = image->region->buffer->handle;
+   *pitch = image->region->pitch;
+
+   return GL_TRUE;
+}
+
 static struct __DRIimageExtensionRec intelImageExtension = {
     { __DRI_IMAGE, __DRI_IMAGE_VERSION },
     intel_create_image_from_name,
     intel_create_image_from_renderbuffer,
     intel_destroy_image,
+    intel_create_image,
+    intel_query_image
 };
 
 static const __DRIextension *intelScreenExtensions[] = {
-- 
1.7.0.1



More information about the mesa-dev mailing list