Signed-off-by: Kristian Høgsberg <k...@bitplanet.net>
---
 src/egl/drivers/dri2/egl_dri2.c |  123 +++++++++++++++++++++++++++++++++++++-
 1 files changed, 119 insertions(+), 4 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 5d36c49..1590190 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -42,7 +42,6 @@
 #include <X11/Xlib-xcb.h>
 
 #include <glapi/glapi.h>
-#include "eglconfigutil.h"
 #include "eglconfig.h"
 #include "eglcontext.h"
 #include "egldisplay.h"
@@ -50,6 +49,7 @@
 #include "eglcurrent.h"
 #include "egllog.h"
 #include "eglsurface.h"
+#include "eglimage.h"
 
 struct dri2_egl_driver
 {
@@ -67,10 +67,12 @@ struct dri2_egl_display
    __DRIdri2Extension       *dri2;
    __DRI2flushExtension     *flush;
    __DRItexBufferExtension  *tex_buffer;
+   __DRIimageExtension      *image;
    int                       fd;
 
    __DRIdri2LoaderExtension  loader_extension;
-   const __DRIextension     *extensions[2];
+   __DRIimageLookupExtension image_lookup_extension;
+   const __DRIextension     *extensions[3];
 };
 
 struct dri2_egl_context
@@ -93,12 +95,24 @@ struct dri2_egl_surface
 
 struct dri2_egl_config
 {
-   _EGLConfig base;
+   _EGLConfig         base;
    const __DRIconfig *dri_config;
 };
 
+struct dri2_egl_image
+{
+   _EGLImage   base;
+   __DRIimage *dri_image;
+   int         width;
+   int         height;
+   int         name;
+   int         pitch;
+   int         cpp;
+};
+
 /* standard typecasts */
 _EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl)
+_EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj)
 
 EGLint dri2_to_egl_attribute_map[] = {
    0,
@@ -346,6 +360,25 @@ dri2_flush_front_buffer(__DRIdrawable * driDrawable, void 
*loaderPrivate)
 #endif
 }
 
+static __DRIimage *
+dri2_lookup_image(__DRIcontext *context, void *image, void *data)
+{
+   struct dri2_egl_context *dri2_ctx = data;
+   _EGLDisplay *disp = dri2_ctx->base.Resource.Display;
+   struct dri2_egl_image *dri2_img;
+   _EGLImage *img;
+
+   img = _eglLookupImage(image, disp);
+   if (img == NULL) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_lookup_image");
+      return NULL;
+   }
+
+   dri2_img = dri2_egl_image(image);
+
+   return dri2_img->dri_image;
+}
+
 static __DRIbuffer *
 dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
                             int *width, int *height,
@@ -405,6 +438,7 @@ static struct dri2_extension_match dri2_driver_extensions[] 
= {
 static struct dri2_extension_match dri2_core_extensions[] = {
    { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) },
    { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) },
+   { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) },
    { NULL }
 };
 
@@ -609,8 +643,13 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
       dri2_dpy->loader_extension.getBuffersWithFormat = NULL;
    }
       
+   dri2_dpy->image_lookup_extension.base.name = __DRI_IMAGE_LOOKUP;
+   dri2_dpy->image_lookup_extension.base.version = 1;
+   dri2_dpy->image_lookup_extension.lookupImage = dri2_lookup_image;
+
    dri2_dpy->extensions[0] = &dri2_dpy->loader_extension.base;
-   dri2_dpy->extensions[1] = NULL;
+   dri2_dpy->extensions[1] = &dri2_dpy->image_lookup_extension.base;
+   dri2_dpy->extensions[2] = NULL;
 
    dri2_dpy->dri_screen =
       dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
@@ -1064,6 +1103,80 @@ dri2_release_tex_image(_EGLDriver *drv,
    return EGL_TRUE;
 }
 
+static _EGLImage *
+dri2_create_image_khr(_EGLDriver *drv, _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;
+   unsigned int attachments[1];
+   xcb_drawable_t drawable;
+   xcb_dri2_get_buffers_cookie_t cookie;
+   xcb_dri2_dri2_buffer_t *buffers;
+   xcb_dri2_get_buffers_reply_t *reply;
+
+   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))
+      return EGL_NO_IMAGE_KHR;
+
+   switch (target) {
+   case EGL_NATIVE_PIXMAP_KHR:
+      drawable = (xcb_drawable_t) buffer;
+      xcb_dri2_create_drawable (dri2_dpy->conn, drawable);
+      attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT;
+      cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
+                                              drawable, 1, 1, attachments);
+      reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, cookie, NULL);
+      buffers = xcb_dri2_get_buffers_buffers (reply);
+      if (buffers == NULL) {
+        free(dri2_img);
+        return NULL;
+      }
+
+      dri2_img->width = reply->width;
+      dri2_img->height = reply->height;
+      dri2_img->name = buffers[0].name;
+      dri2_img->pitch = buffers[0].pitch / buffers[0].cpp;
+      dri2_img->cpp = buffers[0].cpp;
+      free(reply);
+      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->createImageFromName(dri2_ctx->dri_context,
+                                          dri2_img->width,
+                                          dri2_img->height,
+                                          GL_RGBA,
+                                          dri2_img->name,
+                                          dri2_img->pitch,
+                                          dri2_img);
+
+   return &dri2_img->base;
+}
+
+static EGLBoolean
+dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_image *dri2_img = dri2_egl_image(image);
+
+   dri2_dpy->image->destroyImage(dri2_img->dri_image);
+   free(dri2_img);
+
+   return EGL_TRUE;
+}
 
 /**
  * This is the main entrypoint into the driver, called by libEGL.
@@ -1094,6 +1207,8 @@ _eglMain(const char *args)
    dri2_drv->base.API.CopyBuffers = dri2_copy_buffers;
    dri2_drv->base.API.BindTexImage = dri2_bind_tex_image;
    dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image;
+   dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr;
+   dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
 
    dri2_drv->base.Name = "DRI2";
    dri2_drv->base.Unload = dri2_unload;
-- 
1.6.5.rc2


------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to