[Mesa-dev] [PATCH 4/4] egl: Add EGL_MESA_create_image extension
Brian Paul
brianp at vmware.com
Fri May 28 08:05:36 PDT 2010
Minor code comments below.
Kristian Høgsberg wrote:
> ---
> 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;
Shouldn't there be a default case here to catch invalid attributes and
generate an error?
> + }
> + }
> +
> + 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;
Default case?
> + }
> +
> + 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;
Default case?
> + }
> +
> + 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)
How about a comment on this function explaining what it does?
> +{
> + 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;
Default case?
> + }
> +
> + *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
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> .
>
More information about the mesa-dev
mailing list