From e5fc4c81ce5aa261e330977f1a672838cd186cdb Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Mon, 30 May 2011 10:50:52 +0200 Subject: [PATCH] egl_dri2: Hookup gbm as drm platform --- configure.ac | 3 ++ src/egl/drivers/dri2/Makefile | 2 + src/egl/drivers/dri2/egl_dri2.c | 76 +++++++++++++++------------- src/egl/drivers/dri2/egl_dri2.h | 11 +++++ src/egl/drivers/dri2/platform_drm.c | 99 +++++++++++++++++++++++++++---------- src/egl/main/Makefile | 4 ++ 6 files changed, 134 insertions(+), 61 deletions(-) diff --git a/configure.ac b/configure.ac index dbf8fe5..c94c5fa 100644 --- a/configure.ac +++ b/configure.ac @@ -1653,6 +1653,9 @@ yes) WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS" GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/wayland" fi + if test "$plat" = "drm" && test "x$enable_gbm" = no; then + AC_MSG_ERROR([EGL platform drm needs gbm]) + fi done EGL_PLATFORMS="$egl_platforms" ;; diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile index f8ff82b..65d35b3 100644 --- a/src/egl/drivers/dri2/Makefile +++ b/src/egl/drivers/dri2/Makefile @@ -10,6 +10,8 @@ EGL_INCLUDES = \ -I$(TOP)/include \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/mapi \ + -I$(TOP)/src/gbm/main \ + -I$(TOP)/src/gbm/backends/dri \ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ $(LIBUDEV_CFLAGS) \ $(LIBDRM_CFLAGS) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index d430145..cad1737 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -244,7 +244,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, return conf; } -static __DRIimage * +__DRIimage * dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) { _EGLDisplay *disp = data; @@ -433,42 +433,12 @@ dri2_load_driver_swrast(_EGLDisplay *disp) return EGL_TRUE; } -EGLBoolean -dri2_create_screen(_EGLDisplay *disp) +void +dri2_setup_screen(_EGLDisplay *disp) { - const __DRIextension **extensions; - struct dri2_egl_display *dri2_dpy; + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); unsigned int api_mask; - dri2_dpy = disp->DriverData; - - if (dri2_dpy->dri2) { - dri2_dpy->dri_screen = - dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, - &dri2_dpy->driver_configs, disp); - } else { - assert(dri2_dpy->swrast); - dri2_dpy->dri_screen = - dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, - &dri2_dpy->driver_configs, disp); - } - - if (dri2_dpy->dri_screen == NULL) { - _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); - return EGL_FALSE; - } - - extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); - - if (dri2_dpy->dri2) { - if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) - goto cleanup_dri_screen; - } else { - assert(dri2_dpy->swrast); - if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) - goto cleanup_dri_screen; - } - if (dri2_dpy->dri2) { if (dri2_dpy->dri2->base.version >= 2) api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); @@ -510,6 +480,44 @@ dri2_create_screen(_EGLDisplay *disp) disp->Extensions.KHR_image_base = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; } +} + +EGLBoolean +dri2_create_screen(_EGLDisplay *disp) +{ + const __DRIextension **extensions; + struct dri2_egl_display *dri2_dpy; + + dri2_dpy = disp->DriverData; + + if (dri2_dpy->dri2) { + dri2_dpy->dri_screen = + dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, + &dri2_dpy->driver_configs, disp); + } else { + assert(dri2_dpy->swrast); + dri2_dpy->dri_screen = + dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, + &dri2_dpy->driver_configs, disp); + } + + if (dri2_dpy->dri_screen == NULL) { + _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); + return EGL_FALSE; + } + + extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); + + if (dri2_dpy->dri2) { + if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) + goto cleanup_dri_screen; + } else { + assert(dri2_dpy->swrast); + if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) + goto cleanup_dri_screen; + } + + dri2_setup_screen(disp); return EGL_TRUE; diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 1844b6c..cd52d42 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -44,6 +44,8 @@ #include #include +#include + #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" @@ -79,6 +81,8 @@ struct dri2_egl_display __DRIimageExtension *image; int fd; + struct gbm_dri_device *gbm_dri; + char *device_name; char *driver_name; @@ -185,12 +189,19 @@ extern const __DRIuseInvalidateExtension use_invalidate; EGLBoolean dri2_load_driver(_EGLDisplay *disp); +/* Helper for platforms not using dri2_create_screen */ +void +dri2_setup_screen(_EGLDisplay *disp); + EGLBoolean dri2_load_driver_swrast(_EGLDisplay *disp); EGLBoolean dri2_create_screen(_EGLDisplay *disp); +__DRIimage * +dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data); + struct dri2_egl_config * dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, int depth, EGLint surface_type, const EGLint *attr_list); diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 27846de..579baf9 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -33,6 +33,50 @@ #include "egl_dri2.h" +static _EGLImage * +dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer); + struct dri2_egl_image *dri2_img; + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap"); + return NULL; + } + + if (!_eglInitImage(&dri2_img->base, disp)) { + free(dri2_img); + return NULL; + } + + dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img); + if (dri2_img->dri_image == NULL) { + free(dri2_img); + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap"); + return NULL; + } + + return &dri2_img->base; +} + +static _EGLImage * +dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, + _EGLContext *ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + (void) drv; + + switch (target) { + case EGL_NATIVE_PIXMAP_KHR: + return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list); + default: + return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); + } +} + static int dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id) { @@ -45,57 +89,58 @@ EGLBoolean dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy; + struct gbm_device *gbm; int i; dri2_dpy = malloc(sizeof *dri2_dpy); if (!dri2_dpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - + memset(dri2_dpy, 0, sizeof *dri2_dpy); disp->DriverData = (void *) dri2_dpy; - dri2_dpy->fd = (int) (intptr_t) disp->PlatformDisplay; - dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd); - if (dri2_dpy->driver_name == NULL) - return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name"); + gbm = (struct gbm_device *) disp->PlatformDisplay; + if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) { + free(dri2_dpy); + return EGL_FALSE; + } - dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd); - if (dri2_dpy->device_name == NULL) { - _eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name"); - goto cleanup_driver_name; + dri2_dpy->gbm_dri = gbm_dri_device(gbm); + if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) { + free(dri2_dpy); + return EGL_FALSE; } - if (!dri2_load_driver(disp)) - goto cleanup_device_name; + dri2_dpy->fd = gbm_device_get_fd(gbm); + dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd); + dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name; + + dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen; + dri2_dpy->core = dri2_dpy->gbm_dri->core; + dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2; + dri2_dpy->image = dri2_dpy->gbm_dri->image; + dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs; - dri2_dpy->extensions[0] = &image_lookup_extension.base; - dri2_dpy->extensions[1] = &use_invalidate.base; - dri2_dpy->extensions[2] = NULL; + dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image; + dri2_dpy->gbm_dri->lookup_user_data = disp; - if (!dri2_create_screen(disp)) - goto cleanup_driver; + dri2_setup_screen(disp); for (i = 0; dri2_dpy->driver_configs[i]; i++) - dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0, NULL); + dri2_add_config(disp, dri2_dpy->driver_configs[i], + i + 1, 0, 0, NULL); + + drv->API.CreateImageKHR = dri2_drm_create_image_khr; #ifdef HAVE_WAYLAND_PLATFORM disp->Extensions.WL_bind_wayland_display = EGL_TRUE; #endif dri2_dpy->authenticate = dri2_drm_authenticate; - + /* we're supporting EGL 1.4 */ disp->VersionMajor = 1; disp->VersionMinor = 4; return EGL_TRUE; - - cleanup_driver: - dlclose(dri2_dpy->driver); - cleanup_device_name: - free(dri2_dpy->device_name); - cleanup_driver_name: - free(dri2_dpy->driver_name); - - return EGL_FALSE; } diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index 6c4a392..775fbbe 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -61,9 +61,13 @@ LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a ifneq ($(findstring x11, $(EGL_PLATFORMS)),) EGL_LIB_DEPS += $(XCB_DRI2_LIBS) endif +ifneq ($(findstring drm, $(EGL_PLATFORMS)),) +EGL_LIB_DEPS += -lgbm +endif EGL_LIB_DEPS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS) endif + ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a endif -- 2.7.4