[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, ®ion->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