I'm not sure everything should be smacked into a single extension like this. Stride and Handle are very DRM but the extension sounds a bit generic.
I have some patches implementing similarly functionality and I will post them tomorrow. They are conceptually similarly but the break all of the separate pieces of functionality into different extensions (create_image, get_attrib, system_use, drm_image). Cheers Jakob. 2010/5/28 Kristian Høgsberg <[email protected]>: > --- > 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 > > _______________________________________________ > mesa-dev mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
