Hi,

Attached is a patch that implements the following EGL extensions:

EGL_KHR_gl_texture_2d_image
EGL_KHR_gl_texture_3d_image
EGL_KHR_gl_renderbuffer_image
EGL_KHR_vg_parent_image

Please review and, if you find it acceptable, someone can go ahead and apply
it.

This is my first contribution so please let me know if I should do things
differently (either code-wise or process-wise).

Thanks!
-Greg, Lychee Software
From c834c77d9f1b9512fde7ed7e36cdb36452286e1e Mon Sep 17 00:00:00 2001
From: Gregory Prisament <g...@lycheesoftware.com>
Date: Sun, 12 Sep 2010 11:26:38 -0700
Subject: [PATCH 1/2] Implement additional EGL image extension.

Implements:
    - EGL_KHR_gl_texture_2d_image
    - EGL_KHR_gl_texture_3d_image
    - EGL_KHR_gl_cubemap_image
    - EGL_KHR_gl_renderbuffer_image
    - EGL_KHR_vg_parent_image
---
 src/gallium/include/state_tracker/st_api.h         |    6 +-
 src/gallium/state_trackers/egl/common/egl_g3d.c    |    6 +
 .../state_trackers/egl/common/egl_g3d_image.c      |  128 ++++++++++++++++++--
 src/gallium/state_trackers/vega/vg_manager.c       |   29 +++++
 src/mesa/state_tracker/st_manager.c                |   61 +++++++++
 5 files changed, 219 insertions(+), 11 deletions(-)

diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index 8ea1554..d265d69 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -117,7 +117,11 @@ enum st_context_resource_type {
    ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z,
    ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
    ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER,
-   ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE
+   ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE,
+
+   ST_CONTEXT_RESOURCE_COUNT,
+   ST_CONTEXT_RESOURCE_INVALID = -1
+
 };
 
 /**
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 33a838f..d955ab4 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -530,6 +530,12 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
       dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
 
+   dpy->Extensions.KHR_vg_parent_image = EGL_TRUE;
+   dpy->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+   dpy->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE;
+   dpy->Extensions.KHR_gl_texture_3D_image = EGL_TRUE;
+   dpy->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
+
    dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
    dpy->Extensions.KHR_fence_sync = EGL_TRUE;
 
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index 558638e..6bf7f7c 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -230,6 +230,37 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
 
 #endif /* EGL_MESA_drm_image */
 
+/* Map <target> param of eglCreateImageKHR to st_context_resource_type enum. */
+static enum st_context_resource_type
+egl_g3d_target_to_resource_type(EGLenum target)
+{
+   switch (target) {
+   case EGL_GL_TEXTURE_2D_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_2D;
+   case EGL_GL_TEXTURE_3D_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_3D;
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_X;
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+   case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+   case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+   case EGL_GL_RENDERBUFFER_KHR:
+      return ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER;
+   case EGL_VG_PARENT_IMAGE_KHR:
+      return ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE;
+   default:
+      return ST_CONTEXT_RESOURCE_INVALID;
+   }
+}
+
+
 _EGLImage *
 egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
                      EGLenum target, EGLClientBuffer buffer,
@@ -237,6 +268,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
 {
    struct pipe_resource *ptex;
    struct egl_g3d_image *gimg;
+   struct egl_g3d_context *gctx;
    unsigned face = 0, level = 0, zslice = 0;
 
    gimg = CALLOC_STRUCT(egl_g3d_image);
@@ -250,11 +282,76 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
       return NULL;
    }
 
+   gctx = egl_g3d_context(ctx);
+   if (!gctx) {
+      _eglError(EGL_BAD_CONTEXT, "eglCreateImageKHR");
+      FREE(gimg);
+      return NULL;
+   }
+  
+   /* Parse attributes */
+   while (*attribs != EGL_NONE)
+   {
+      EGLint attr_val = attribs[1];
+      switch (*attribs) {
+      case EGL_GL_TEXTURE_LEVEL_KHR:
+         level = attr_val;
+         break;
+      case EGL_GL_TEXTURE_ZOFFSET_KHR:
+         if (target != EGL_GL_TEXTURE_3D_KHR) {
+            goto handle_bad_parameter;
+         }
+         zslice = attr_val;
+         break;
+      default:
+         /* unsupported attribute */
+         goto handle_bad_parameter;
+      }
+      attribs += 2;
+   }
+  
+   /* Lookup client-API resource */
    switch (target) {
    case EGL_NATIVE_PIXMAP_KHR:
       ptex = egl_g3d_reference_native_pixmap(dpy,
             (EGLNativePixmapType) buffer);
       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:
+      face = (unsigned int)target -
+                  (unsigned int)EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
+      /* Intentional fall-through: */
+   case EGL_GL_TEXTURE_2D_KHR:
+   case EGL_GL_TEXTURE_3D_KHR:
+   case EGL_GL_RENDERBUFFER_KHR:
+   case EGL_VG_PARENT_IMAGE_KHR:
+      {
+         boolean result;
+         struct st_context_resource stres;
+  
+         stres.type = egl_g3d_target_to_resource_type(target);
+         assert(stres.type != ST_CONTEXT_RESOURCE_INVALID);
+  
+         stres.resource = (void *)buffer;
+  
+         if (!gctx->stctxi->get_resource_for_egl_image) {
+            goto handle_bad_parameter;
+         }
+  
+         result = 
+            gctx->stctxi->get_resource_for_egl_image(gctx->stctxi, &stres);
+         if (!result) {
+            goto handle_bad_parameter;
+         }
+  
+         ptex = stres.texture;
+         break;
+      }
+
 #ifdef EGL_MESA_drm_image
    case EGL_DRM_BUFFER_MESA:
       ptex = egl_g3d_reference_drm_buffer(dpy, (EGLint) buffer, attribs);
@@ -266,21 +363,14 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
    }
 
    if (!ptex) {
-      FREE(gimg);
-      return NULL;
+      goto handle_bad_parameter;
    }
 
    if (level > ptex->last_level) {
-      _eglError(EGL_BAD_MATCH, "eglCreateEGLImageKHR");
-      pipe_resource_reference(&gimg->texture, NULL);
-      FREE(gimg);
-      return NULL;
+      goto handle_bad_parameter;
    }
    if (zslice > ptex->depth0) {
-      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
-      pipe_resource_reference(&gimg->texture, NULL);
-      FREE(gimg);
-      return NULL;
+      goto handle_bad_parameter;
    }
 
    /* transfer the ownership to the image */
@@ -290,6 +380,24 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
    gimg->zslice = zslice;
 
    return &gimg->base;
+
+   /* error handling */
+handle_bad_parameter:
+   _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+   goto handle_error;
+  
+handle_bad_match:
+   _eglError(EGL_BAD_MATCH, "eglCreateEGLImageKHR");
+   goto handle_error;
+  
+handle_error:
+   if (gimg && gimg->texture)
+      pipe_resource_reference(&gimg->texture, NULL);
+  
+   if (gimg)
+      FREE(gimg);
+  
+   return NULL;
 }
 
 EGLBoolean
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index e799674..86221e2 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -332,6 +332,32 @@ vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
       vg_manager_flush_frontbuffer(ctx);
 }
 
+static boolean
+vg_context_get_resource_for_egl_image(struct st_context_iface *stctxi, 
+                                      struct st_context_resource *stres)
+{
+   struct vg_context *ctx;
+   struct vg_image *img;
+   struct pipe_sampler_view *sampler_view;
+
+   ctx = (struct vg_context *) stctxi;
+   if (!ctx) 
+      return FALSE;
+
+   img = (struct vg_image *)stres->resource;
+   if (!img)
+      return FALSE;
+
+   sampler_view = img->sampler_view;
+   if (!sampler_view)
+      return FALSE;
+
+   stres->texture = sampler_view->texture;
+
+   return TRUE;
+}
+
+
 static void
 vg_context_destroy(struct st_context_iface *stctxi)
 {
@@ -373,6 +399,9 @@ vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
    ctx->iface.teximage = NULL;
    ctx->iface.copy = NULL;
 
+   ctx->iface.get_resource_for_egl_image =
+      vg_context_get_resource_for_egl_image;
+
    ctx->iface.st_context_private = (void *) smapi;
 
    return &ctx->iface;
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 450b045..f8f4223 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -601,6 +601,66 @@ st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target
    return TRUE;
 }
 
+static boolean
+st_context_get_resource_for_egl_image(struct st_context_iface *stctxi, 
+                                    struct st_context_resource *stres)
+{
+   struct st_context *st = (struct st_context *) stctxi;
+
+   switch (stres->type) {
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_2D:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_3D:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_X:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+   case ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+   {
+      GLuint texID;
+      struct gl_texture_object *texObj;
+      struct pipe_resource *resource;
+
+      texID = (GLuint)stres->resource;
+
+      texObj = _mesa_lookup_texture(st->ctx, texID);
+      if (!texObj)
+         return FALSE;
+
+      resource = st_get_texobj_resource(texObj);
+      if (!resource)
+         return FALSE;
+
+      stres->texture = resource;
+      return TRUE;
+   }
+   case ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER:
+   {
+      GLuint rbID;
+      struct gl_renderbuffer *rbObj;
+      struct st_renderbuffer *stRb;
+
+      rbID = (GLuint)stres->resource;
+
+      rbObj = _mesa_lookup_renderbuffer(st->ctx, rbID);
+      if (!rbObj)
+         return FALSE;
+
+      stRb = st_renderbuffer(rbObj);
+      if (!stRb)
+         return FALSE;
+
+      stres->texture = stRb->texture;
+      return TRUE;
+   }
+   default:
+      return FALSE;
+   }
+
+   return FALSE;
+}
+
+
 static void
 st_context_destroy(struct st_context_iface *stctxi)
 {
@@ -669,6 +729,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
    st->iface.flush = st_context_flush;
    st->iface.teximage = st_context_teximage;
    st->iface.copy = NULL;
+   st->iface.get_resource_for_egl_image = st_context_get_resource_for_egl_image;
    st->iface.st_context_private = (void *) smapi;
 
    return &st->iface;
-- 
1.6.3.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to