[Mesa-dev] [PATCH] dri2: Create image from texture (v8)

Abdiel Janulgue abdiel.janulgue at linux.intel.com
Fri Feb 1 08:32:05 PST 2013


Add create image from texture extension and bump version.

v8: - Add appropriate image errors codes in DRI interface so we don't
      have to use internal EGL functions in driver. Suggested by Chad Versace.

Reviewed-by: Eric Anholt <eric at anholt.net> (v6)
Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
---
 include/GL/internal/dri_interface.h |   32 ++++++++-
 src/egl/drivers/dri2/egl_dri2.c     |  122 +++++++++++++++++++++++++++++++++++
 2 files changed, 153 insertions(+), 1 deletion(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index c236cb7..42147e9 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 5
+#define __DRI_IMAGE_VERSION 6
 
 /**
  * These formats correspond to the similarly named MESA_FORMAT_*
@@ -1022,6 +1022,23 @@ struct __DRIdri2ExtensionRec {
 #define __DRI_IMAGE_ATTRIB_HEIGHT	0x2005
 #define __DRI_IMAGE_ATTRIB_COMPONENTS	0x2006 /* available in versions 5+ */
 
+/**
+ * \name Reasons that __DRIimageExtensionRec::createImageFromTexture might fail
+ */
+/*@{*/
+/** Success! */
+#define __DRI_IMAGE_ERROR_SUCCESS       0
+
+/** Memory allocation failure */
+#define __DRI_IMAGE_ERROR_BAD_ALLOC     1
+
+/** Client requested an invalid attribute for a texture object  */
+#define __DRI_IMAGE_ERROR_BAD_MATCH     2
+
+/** Client requested an invalid texture object */
+#define __DRI_IMAGE_ERROR_BAD_PARAMETER 3
+/*@}*/
+
 typedef struct __DRIimageRec          __DRIimage;
 typedef struct __DRIimageExtensionRec __DRIimageExtension;
 struct __DRIimageExtensionRec {
@@ -1087,6 +1104,19 @@ struct __DRIimageExtensionRec {
     */
     __DRIimage *(*fromPlanar)(__DRIimage *image, int plane,
                               void *loaderPrivate);
+
+    /**
+     * Create image from texture.
+     *
+     * \since 6
+     */
+   __DRIimage *(*createImageFromTexture)(__DRIcontext *context,
+                                         int target,
+                                         unsigned texture,
+                                         int depth,
+                                         int level,
+                                         unsigned *error,
+                                         void *loaderPrivate);
 };
 
 
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 351fbf4..d10bdf0 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -495,6 +495,11 @@ dri2_setup_screen(_EGLDisplay *disp)
       disp->Extensions.MESA_drm_image = EGL_TRUE;
       disp->Extensions.KHR_image_base = EGL_TRUE;
       disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
+      if (dri2_dpy->image->base.version >= 5 &&
+          dri2_dpy->image->createImageFromTexture) {
+         disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+         disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE;
+      }
    }
 }
 
@@ -1217,6 +1222,115 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
 }
 #endif
 
+/**
+ * Set the error code after a call to
+ * dri2_egl_image::dri_image::createImageFromTexture.
+ */
+static void
+dri2_create_image_khr_texture_error(int dri_error)
+{
+   EGLint egl_error;
+
+   switch (dri_error) {
+   case __DRI_IMAGE_ERROR_SUCCESS:
+      return;
+
+   case __DRI_IMAGE_ERROR_BAD_ALLOC:
+      egl_error = EGL_BAD_ALLOC;
+      break;
+
+   case __DRI_IMAGE_ERROR_BAD_MATCH:
+      egl_error = EGL_BAD_MATCH;
+      break;
+
+   case __DRI_IMAGE_ERROR_BAD_PARAMETER:
+      egl_error = EGL_BAD_PARAMETER;
+      break;
+
+   default:
+      assert(0);
+      egl_error = EGL_BAD_MATCH;
+      break;
+   }
+
+   _eglError(egl_error, "dri2_create_image_khr_texture");
+}
+
+static _EGLImage *
+dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
+				   EGLenum target,
+				   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;
+   GLuint texture = (GLuint) (uintptr_t) buffer;
+   _EGLImageAttribs attrs;
+   GLuint depth;
+   GLenum gl_target;
+   unsigned error;
+
+   if (texture == 0) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS)
+      return EGL_NO_IMAGE_KHR;
+
+   switch (target) {
+   case EGL_GL_TEXTURE_2D_KHR:
+      depth = 0;
+      gl_target = GL_TEXTURE_2D;
+      break;
+   case EGL_GL_TEXTURE_3D_KHR:
+      depth = attrs.GLTextureZOffset;
+      gl_target = GL_TEXTURE_3D;
+      break;
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+      depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
+      gl_target = GL_TEXTURE_CUBE_MAP;
+      break;
+   default:
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   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)) {
+      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
+      free(dri2_img);
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   dri2_img->dri_image =
+      dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context,
+                                              gl_target,
+                                              texture,
+                                              depth,
+                                              attrs.GLTextureLevel,
+                                              &error,
+                                              dri2_img);
+   dri2_create_image_khr_texture_error(error);
+
+   if (!dri2_img->dri_image) {
+      free(dri2_img);
+      return EGL_NO_IMAGE_KHR;
+   }
+   return &dri2_img->base;
+}
+
 _EGLImage *
 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
 		      _EGLContext *ctx, EGLenum target,
@@ -1225,6 +1339,14 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    (void) drv;
 
    switch (target) {
+   case EGL_GL_TEXTURE_2D_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+      return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
    case EGL_GL_RENDERBUFFER_KHR:
       return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
    case EGL_DRM_BUFFER_MESA:
-- 
1.7.9.5



More information about the mesa-dev mailing list