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@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev .
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev