[Mesa-dev] [PATCH 6/6] st/egl: WIP support for new drm EGLImage extensions
Jakob Bornecrantz
wallbraker at gmail.com
Sat May 29 05:56:34 PDT 2010
---
src/gallium/state_trackers/egl/common/egl_g3d.c | 16 +++
.../state_trackers/egl/common/egl_g3d_api.c | 4 +
.../state_trackers/egl/common/egl_g3d_image.c | 59 ++++++++++++
.../state_trackers/egl/common/egl_g3d_image.h | 3 +
src/gallium/state_trackers/egl/common/native.h | 8 ++
src/gallium/state_trackers/egl/drm/drm_display.c | 15 +++
src/gallium/state_trackers/egl/drm/drm_image.c | 100 +++++++++++++++++++-
src/gallium/state_trackers/egl/kms/native_kms.c | 43 +++++++++
src/gallium/state_trackers/egl/x11/native_dri2.c | 43 +++++++++
9 files changed, 289 insertions(+), 2 deletions(-)
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index d63b81a..5f1f6e0 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -510,6 +510,21 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
+#ifdef EGL_MESA_create_image
+ dpy->Extensions.MESA_create_image = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_get_image_attrib
+ dpy->Extensions.MESA_get_image_attrib = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_image_system_use
+ if (gdpy->native->get_drm_attrib)
+ dpy->Extensions.MESA_image_system_use = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_drm_image
+ if (gdpy->native->get_drm_attrib)
+ dpy->Extensions.MESA_drm_image = EGL_TRUE;
+#endif
+
if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
goto fail;
@@ -548,6 +563,7 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
return (_EGLProc) NULL;
}
+
static EGLint
egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
{
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 4615a58..30bc676 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -717,6 +717,10 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
drv->API.CreateImageKHR = egl_g3d_create_image;
drv->API.DestroyImageKHR = egl_g3d_destroy_image;
+#ifdef EGL_MESA_get_image_attrib
+ drv->API.GetImageAttribMESA = egl_g3d_get_image_attrib;
+#endif
+
#ifdef EGL_MESA_screen_surface
drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index b1fe30a..74d17e5 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -37,6 +37,35 @@
#include "egl_g3d_api.h"
#include "egl_g3d_image.h"
+#ifdef EGL_MESA_create_image
+/**
+ * Create a new texture resource
+ */
+static struct pipe_resource *
+egl_g3d_create_image_new(struct egl_g3d_display *gdpy, struct egl_g3d_image *gimg, const EGLint *attr_list)
+{
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_resource tmplt;
+
+ memset(&tmplt, 0, sizeof(tmplt));
+ tmplt.target = PIPE_TEXTURE_2D;
+ tmplt.last_level = 0;
+ tmplt.width0 = gimg->base.Width;
+ tmplt.height0 = gimg->base.Height;
+ tmplt.depth0 = 1;
+ tmplt.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* XXX format */
+
+ if (gimg->base.UseSystem & EGL_SYSTEM_SCANOUT_BIT_MESA)
+ tmplt.bind |= PIPE_BIND_SCANOUT;
+
+ if (gimg->base.UseSystem & EGL_SYSTEM_SHARABLE_BIT_MESA)
+ tmplt.bind |= PIPE_BIND_SHARED;
+
+ return screen->resource_create(screen, &tmplt);
+}
+#endif /* EGL_MESA_create_image */
+
/**
* Reference and return the front left buffer of the native pixmap.
*/
@@ -72,6 +101,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer,
const EGLint *attribs)
{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_resource *ptex;
struct egl_g3d_image *gimg;
unsigned face = 0, level = 0, zslice = 0;
@@ -92,6 +122,11 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
ptex = egl_g3d_reference_native_pixmap(dpy,
(EGLNativePixmapType) buffer);
break;
+#ifdef EGL_MESA_create_image
+ case EGL_NEW_IMAGE_MESA:
+ ptex = egl_g3d_create_image_new(gdpy, gimg, attribs);
+ break;
+#endif
default:
ptex = NULL;
break;
@@ -134,3 +169,27 @@ egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
return EGL_TRUE;
}
+
+#ifdef EGL_MESA_get_image_attrib
+EGLBoolean
+egl_g3d_get_image_attrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, EGLenum attrib, EGLint *out)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_image *gimg = egl_g3d_image(img);
+
+ switch(attrib) {
+ case EGL_DRM_STRIDE_MESA:
+ case EGL_DRM_KMS_HANDLE_MESA:
+ case EGL_DRM_SHARED_HANDLE_MESA:
+ if (!gdpy->native->get_drm_attrib) {
+ _eglError(EGL_BAD_PARAMETER, "eglGetImageAttribMESA");
+ return EGL_FALSE;
+ }
+ return gdpy->native->get_drm_attrib(gdpy->native,
+ gimg->texture,
+ attrib, out);
+ default:
+ return _eglGetImageAttribMESA(drv, dpy, img, attrib, out);
+ }
+}
+#endif /* EGL_MESA_get_image_attrib */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.h b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
index adda933..cd2461c 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
@@ -37,6 +37,9 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
const EGLint *attribs);
EGLBoolean
+egl_g3d_get_image_attrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, EGLenum attrib, EGLint *out);
+
+EGLBoolean
egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
#endif /* _EGL_G3D_IMAGE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 3f60348..d6b3643 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -181,6 +181,14 @@ struct native_display {
EGLNativePixmapType pix,
const struct native_config *nconf);
+ /*
+ * Used by eglGetImageAttrib for the EGL_MESA_drm_image extension.
+ */
+ EGLBoolean (*get_drm_attrib)(struct native_display *ndpy,
+ struct pipe_resource *res,
+ EGLenum attrib,
+ EGLint *out);
+
const struct native_display_modeset *modeset;
};
diff --git a/src/gallium/state_trackers/egl/drm/drm_display.c b/src/gallium/state_trackers/egl/drm/drm_display.c
index 5692f79..319ecce 100644
--- a/src/gallium/state_trackers/egl/drm/drm_display.c
+++ b/src/gallium/state_trackers/egl/drm/drm_display.c
@@ -48,6 +48,9 @@ _eglMain(const char *args)
drv->API.CreateImageKHR = drm_create_image;
drv->API.DestroyImageKHR = drm_destroy_image;
+#ifdef EGL_MESA_get_image_attrib
+ drv->API.GetImageAttribMESA = drm_get_image_attrib;
+#endif
drv->Name = "DRM/Gallium/Win";
drv->Unload = drm_unload;
@@ -120,6 +123,18 @@ drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor)
dpy->ClientAPIsMask = EGL_OPENGL_BIT;
dpy->Extensions.KHR_image_base = EGL_TRUE;
+#ifdef EGL_MESA_create_image
+ dpy->Extensions.MESA_create_image = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_get_image_attrib
+ dpy->Extensions.MESA_get_image_attrib = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_image_system_use
+ dpy->Extensions.MESA_image_system_use = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_drm_image
+ dpy->Extensions.MESA_drm_image = EGL_TRUE;
+#endif
*major = 1;
*minor = 4;
diff --git a/src/gallium/state_trackers/egl/drm/drm_image.c b/src/gallium/state_trackers/egl/drm/drm_image.c
index a25f486..b95a3be 100644
--- a/src/gallium/state_trackers/egl/drm/drm_image.c
+++ b/src/gallium/state_trackers/egl/drm/drm_image.c
@@ -4,11 +4,44 @@
#include "drm_tracker.h"
+#include "state_tracker/drm_api.h"
+
+#include "pipe/p_screen.h"
#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
-/*
- * Stub
+#ifdef EGL_MESA_create_image
+/**
+ * Create a new texture resource
*/
+static struct pipe_resource *
+drm_create_image_new(struct drm_device *dev, struct drm_image *img, const EGLint *attr_list)
+{
+ struct pipe_screen *screen = dev->manager.screen;
+ struct pipe_resource tmplt;
+
+ memset(&tmplt, 0, sizeof(tmplt));
+ tmplt.target = PIPE_TEXTURE_2D;
+ tmplt.last_level = 0;
+ tmplt.width0 = img->base.Width;
+ tmplt.height0 = img->base.Height;
+ tmplt.depth0 = 1;
+ tmplt.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* XXX format */
+
+#ifdef EGL_MESA_image_system_use
+ if (img->base.UseSystem & EGL_SYSTEM_SCANOUT_BIT_MESA)
+ tmplt.bind |= PIPE_BIND_SCANOUT;
+
+ if (img->base.UseSystem & EGL_SYSTEM_SHARABLE_BIT_MESA)
+ tmplt.bind |= PIPE_BIND_SHARED;
+#endif
+
+ return screen->resource_create(screen, &tmplt);
+}
+#endif /* EGL_MESA_create_image */
+
_EGLImage *
drm_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer,
@@ -26,6 +59,11 @@ drm_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
goto out_free;
switch (target) {
+#ifdef EGL_MESA_create_image
+ case EGL_NEW_IMAGE_MESA:
+ res = drm_create_image_new(dev, img, attribs);
+ break;
+#endif
default:
res = NULL;
}
@@ -84,3 +122,61 @@ drm_get_egl_image(struct st_manager *manager,
return TRUE;
}
+
+
+#ifdef EGL_MESA_get_image_attrib
+/**
+ * Get the handle or stride from a pipe_resource.
+ *
+ * Helper function for drm_get_image_attrib to make
+ * switch case more readable.
+ */
+static INLINE EGLBoolean
+drm_get_handle(struct pipe_screen *screen,
+ struct pipe_resource *res,
+ unsigned type, EGLBoolean stride,
+ EGLint *out)
+{
+ struct winsys_handle whandle;
+ EGLBoolean ret;
+
+ whandle.type = type;
+
+ ret = screen->resource_get_handle(screen, res, &whandle);
+
+ if (ret)
+ *out = stride ? whandle.stride : whandle.handle;
+ else
+ _eglError(EGL_BAD_ALLOC, "eglGetImageAttribMESA");
+ return ret;
+}
+
+/**
+ * Implement EGL_MESA_get_image_attrib extension need special case for
+ * EGL_MESA_drm_image getters the rest is handled by common egl code.
+ */
+EGLBoolean
+drm_get_image_attrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image, EGLenum attrib, EGLint *out)
+{
+ struct drm_device *dev = lookup_drm_device(dpy);
+ struct drm_image *img = lookup_drm_image(image);
+ struct pipe_screen *screen = dev->manager.screen;
+
+ switch(attrib) {
+ case EGL_DRM_STRIDE_MESA:
+ return drm_get_handle(screen, img->res,
+ DRM_API_HANDLE_TYPE_KMS,
+ EGL_TRUE, out);
+ case EGL_DRM_KMS_HANDLE_MESA:
+ return drm_get_handle(screen, img->res,
+ DRM_API_HANDLE_TYPE_KMS,
+ EGL_FALSE, out);
+ case EGL_DRM_SHARED_HANDLE_MESA:
+ return drm_get_handle(screen, img->res,
+ DRM_API_HANDLE_TYPE_SHARED,
+ EGL_FALSE, out);
+ default:
+ return _eglGetImageAttribMESA(drv, dpy, image, attrib, out);
+ }
+}
+#endif /* EGL_MESA_get_image_attrib */
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index d7e7b2b..07eb71b 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -726,6 +726,48 @@ static struct native_display_modeset kms_display_modeset = {
.program = kms_display_program
};
+static EGLBoolean
+kms_get_drm_attrib(struct native_display *ndpy,
+ struct pipe_resource *res,
+ EGLenum attrib, EGLint *out)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ struct winsys_handle whandle;
+ boolean ret;
+
+ memset(&whandle, 0, sizeof(whandle));
+
+ switch(attrib) {
+ case EGL_DRM_STRIDE_MESA:
+ /* check which type to use */
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ ret = kdpy->base.screen->resource_get_handle(
+ kdpy->base.screen, res, &whandle);
+ if (ret)
+ *out = whandle.stride;
+ return ret;
+
+ case EGL_DRM_KMS_HANDLE_MESA:
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ ret = kdpy->base.screen->resource_get_handle(
+ kdpy->base.screen, res, &whandle);
+ if (ret)
+ *out = whandle.handle;
+ return ret;
+
+ case EGL_DRM_SHARED_HANDLE_MESA:
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ ret = kdpy->base.screen->resource_get_handle(
+ kdpy->base.screen, res, &whandle);
+ if (ret)
+ *out = whandle.handle;
+ return ret;
+
+ default:
+ return EGL_FALSE;
+ }
+}
+
static struct native_display *
kms_create_display(EGLNativeDisplayType dpy,
struct native_event_handler *event_handler,
@@ -776,6 +818,7 @@ kms_create_display(EGLNativeDisplayType dpy,
kdpy->base.destroy = kms_display_destroy;
kdpy->base.get_param = kms_display_get_param;
kdpy->base.get_configs = kms_display_get_configs;
+ kdpy->base.get_drm_attrib = kms_get_drm_attrib;
kdpy->base.modeset = &kms_display_modeset;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 3f802dd..4ed8367 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -740,6 +740,48 @@ dri2_display_hash_table_compare(void *key1, void *key2)
return (key1 - key2);
}
+static EGLBoolean
+dri2_get_drm_attrib(struct native_display *ndpy,
+ struct pipe_resource *res,
+ EGLenum attrib, EGLint *out)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ struct winsys_handle whandle;
+ boolean ret;
+
+ memset(&whandle, 0, sizeof(whandle));
+
+ switch(attrib) {
+ case EGL_DRM_STRIDE_MESA:
+ /* check which type to use */
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ ret = dri2dpy->base.screen->resource_get_handle(
+ dri2dpy->base.screen, res, &whandle);
+ if (ret)
+ *out = whandle.stride;
+ return ret;
+
+ case EGL_DRM_KMS_HANDLE_MESA:
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ ret = dri2dpy->base.screen->resource_get_handle(
+ dri2dpy->base.screen, res, &whandle);
+ if (ret)
+ *out = whandle.handle;
+ return ret;
+
+ case EGL_DRM_SHARED_HANDLE_MESA:
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ ret = dri2dpy->base.screen->resource_get_handle(
+ dri2dpy->base.screen, res, &whandle);
+ if (ret)
+ *out = whandle.handle;
+ return ret;
+
+ default:
+ return EGL_FALSE;
+ }
+}
+
struct native_display *
x11_create_dri2_display(EGLNativeDisplayType dpy,
struct native_event_handler *event_handler,
@@ -789,6 +831,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy,
dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
+ dri2dpy->base.get_drm_attrib = dri2_get_drm_attrib;
return &dri2dpy->base;
}
--
1.7.0.4
More information about the mesa-dev
mailing list