egl_dri2: Hookup gbm as drm platform

This commit is contained in:
Benjamin Franzke
2011-05-30 10:50:52 +02:00
parent 48d4a001b3
commit e5fc4c81ce
6 changed files with 135 additions and 62 deletions

View File

@@ -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"
;;

View File

@@ -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)

View File

@@ -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;

View File

@@ -44,6 +44,8 @@
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
#include <gbm_driint.h>
#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);

View File

@@ -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");
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;
gbm = (struct gbm_device *) disp->PlatformDisplay;
if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
free(dri2_dpy);
return EGL_FALSE;
}
if (!dri2_load_driver(disp))
goto cleanup_device_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;
}
dri2_dpy->extensions[0] = &image_lookup_extension.base;
dri2_dpy->extensions[1] = &use_invalidate.base;
dri2_dpy->extensions[2] = NULL;
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;
if (!dri2_create_screen(disp))
goto cleanup_driver;
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->gbm_dri->lookup_image = dri2_lookup_egl_image;
dri2_dpy->gbm_dri->lookup_user_data = disp;
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;
}

View File

@@ -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