[Mesa-dev] [PATCH 5/6] egl_dri2: Add support for MESA_image_drm
Kristian Høgsberg
krh at bitplanet.net
Fri Jun 4 06:46:27 PDT 2010
---
include/GL/internal/dri_interface.h | 19 +++
src/egl/drivers/dri2/egl_dri2.c | 220 +++++++++++++++++++++++++++++++++++
2 files changed, 239 insertions(+), 0 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index e4c2b3a..838bdce 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -807,6 +807,17 @@ 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
+
+/**
+ * queryImage attributes
+ */
+
+#define __DRI_IMAGE_ATTRIB_STRIDE 0x2000
+#define __DRI_IMAGE_ATTRIB_HANDLE 0x2001
+#define __DRI_IMAGE_ATTRIB_NAME 0x2002
+
typedef struct __DRIimageRec __DRIimage;
typedef struct __DRIimageExtensionRec __DRIimageExtension;
struct __DRIimageExtensionRec {
@@ -822,8 +833,16 @@ struct __DRIimageExtensionRec {
void *loaderPrivate);
void (*destroyImage)(__DRIimage *image);
+
+ __DRIimage *(*createImage)(__DRIcontext *context,
+ int width, int height, int format,
+ unsigned int use,
+ void *loaderPrivate);
+
+ GLboolean (*queryImage)(__DRIimage *image, int attrib, int *value);
};
+
/**
* 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 fdaf512..013ca96 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -901,6 +901,7 @@ dri2_initialize_xcb(_EGLDisplay *disp)
if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
goto cleanup_configs;
+ disp->Extensions.MESA_image_drm = EGL_TRUE;
disp->Extensions.KHR_image_base = EGL_TRUE;
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
@@ -956,9 +957,11 @@ dri2_initialize_drm(_EGLDisplay *disp)
for (i = 0; dri2_dpy->driver_configs[i]; i++)
dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, NULL, 0);
+ disp->Extensions.MESA_image_drm = EGL_TRUE;
disp->Extensions.KHR_image_base = EGL_TRUE;
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+ disp->Extensions.INTEL_no_surface = EGL_TRUE;
return EGL_TRUE;
@@ -1602,6 +1605,95 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
}
static _EGLImage *
+dri2_create_image_mesa_drm(_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;
+ EGLint width, height, format, name, stride, pitch, i, err;
+
+ name = (EGLint) buffer;
+
+ width = 0;
+ height = 0;
+ format = 0;
+ stride = 0;
+
+ for (i = 0; attr_list[i] != EGL_NONE; i++) {
+ EGLint attr = attr_list[i++];
+ EGLint val = attr_list[i];
+
+ 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_STRIDE_MESA:
+ stride = val;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglLog(_EGL_WARNING, "bad image attribute 0x%04x", attr);
+ return NULL;
+ }
+ }
+
+ if (width <= 0 || height <= 0 || stride <= 0) {
+ _eglError(EGL_BAD_PARAMETER,
+ "bad width, height or stride");
+ return NULL;
+ }
+
+ switch (format) {
+ case EGL_IMAGE_FORMAT_ARGB8888_MESA:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ pitch = stride / 4;
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER,
+ "dri2_create_image_khr: unsupported pixmap depth");
+ return NULL;
+ }
+
+ dri2_img = malloc(sizeof *dri2_img);
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_mesa_drm");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&dri2_img->base, disp, attr_list)) {
+ free(dri2_img);
+ return NULL;
+ }
+
+ dri2_img->dri_image =
+ dri2_dpy->image->createImageFromName(dri2_ctx->dri_context,
+ width,
+ height,
+ format,
+ name,
+ pitch,
+ dri2_img);
+ if (dri2_img == NULL) {
+ free(dri2_img);
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_mesa_drm");
+ return NULL;
+ }
+
+ return &dri2_img->base;
+}
+
+static _EGLImage *
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
@@ -1611,6 +1703,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_DRM_IMAGE_MESA:
+ return dri2_create_image_mesa_drm(disp, ctx, buffer, attr_list);
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
@@ -1629,6 +1723,130 @@ dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
return EGL_TRUE;
}
+static _EGLImage *
+dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLint *handle,
+ EGLint *stride, 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, dri_use, valid_mask;
+ EGLint err = EGL_SUCCESS;
+
+ dri2_img = malloc(sizeof *dri2_img);
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ if (!attr_list) {
+ err = EGL_BAD_PARAMETER;
+ goto cleanup_img;
+ }
+
+ if (!_eglInitImage(&dri2_img->base, disp, attr_list)) {
+ err = EGL_BAD_PARAMETER;
+ goto cleanup_img;
+ }
+
+ width = 0;
+ height = 0;
+ format = 0;
+ use = 0;
+ for (i = 0; attr_list[i] != EGL_NONE; i++) {
+ EGLint attr = attr_list[i++];
+ EGLint val = attr_list[i];
+
+ 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;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglLog(_EGL_WARNING, "bad image attribute 0x%04x", attr);
+ goto cleanup_img;
+ }
+ }
+
+ if (width <= 0 || height <= 0) {
+ _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", width, height);
+ goto cleanup_img;
+ }
+
+ switch (format) {
+ case EGL_IMAGE_FORMAT_ARGB8888_MESA:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ break;
+ default:
+ _eglLog(_EGL_WARNING, "bad image format value 0x%04x", format);
+ goto cleanup_img;
+ }
+
+ valid_mask = EGL_IMAGE_USE_SCANOUT_MESA | EGL_IMAGE_USE_SHARE_MESA;
+ if (use & ~valid_mask) {
+ _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", use & ~valid_mask);
+ goto cleanup_img;
+ }
+
+ dri_use = 0;
+ if (use & EGL_IMAGE_USE_SHARE_MESA)
+ dri_use |= __DRI_IMAGE_USE_SHARE;
+ if (use & EGL_IMAGE_USE_SCANOUT_MESA)
+ dri_use |= __DRI_IMAGE_USE_SCANOUT;
+
+ dri2_img->dri_image =
+ dri2_dpy->image->createImage(dri2_ctx->dri_context,
+ width, height, format, dri_use, dri2_img);
+ if (dri2_img->dri_image == NULL) {
+ err = EGL_BAD_ALLOC;
+ goto cleanup_img;
+ }
+
+ dri2_dpy->image->queryImage(dri2_img->dri_image,
+ __DRI_IMAGE_ATTRIB_HANDLE, handle);
+ dri2_dpy->image->queryImage(dri2_img->dri_image,
+ __DRI_IMAGE_ATTRIB_STRIDE, stride);
+
+ return &dri2_img->base;
+
+ cleanup_img:
+ free(dri2_img);
+ _eglError(err, "dri2_create_drm_image_mesa");
+
+ return EGL_NO_IMAGE_KHR;
+}
+
+static EGLBoolean
+dri2_share_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLImage *img, EGLint *name)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+
+ if (!dri2_dpy->image->queryImage(dri2_img->dri_image,
+ __DRI_IMAGE_ATTRIB_NAME, name)) {
+ _eglError(EGL_BAD_ALLOC, "dri2_share_drm_image_mesa");
+ return EGL_FALSE;
+ }
+
+ return EGL_TRUE;
+}
+
/**
* This is the main entrypoint into the driver, called by libEGL.
* Create a new _EGLDriver object and init its dispatch table.
@@ -1662,6 +1880,8 @@ _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.CreateDRMImageMESA = dri2_create_drm_image_mesa;
+ dri2_drv->base.API.ShareDRMImageMESA = dri2_share_drm_image_mesa;
dri2_drv->base.Name = "DRI2";
dri2_drv->base.Unload = dri2_unload;
--
1.7.1
More information about the mesa-dev
mailing list