mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 13:38:06 +02:00
egl_dri2: add swrast
This enables the egl_dri2 driver to load swrast driver for software rendering. It could be used when hardware dri2 drivers are not available, such as in VM. Signed-off-by: Haitao Feng <haitao.feng@intel.com>
This commit is contained in:
parent
231bf886da
commit
f55d027ac2
5 changed files with 395 additions and 52 deletions
|
|
@ -276,6 +276,17 @@ static struct dri2_extension_match dri2_core_extensions[] = {
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dri2_extension_match swrast_driver_extensions[] = {
|
||||||
|
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) },
|
||||||
|
{ __DRI_SWRAST, 2, offsetof(struct dri2_egl_display, swrast) },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dri2_extension_match swrast_core_extensions[] = {
|
||||||
|
{ __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static EGLBoolean
|
static EGLBoolean
|
||||||
dri2_bind_extensions(struct dri2_egl_display *dri2_dpy,
|
dri2_bind_extensions(struct dri2_egl_display *dri2_dpy,
|
||||||
struct dri2_extension_match *matches,
|
struct dri2_extension_match *matches,
|
||||||
|
|
@ -363,9 +374,16 @@ dri2_load_driver(_EGLDisplay *disp)
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) {
|
if (strcmp(dri2_dpy->driver_name, "swrast") == 0) {
|
||||||
dlclose(dri2_dpy->driver);
|
if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) {
|
||||||
return EGL_FALSE;
|
dlclose(dri2_dpy->driver);
|
||||||
|
return EGL_FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) {
|
||||||
|
dlclose(dri2_dpy->driver);
|
||||||
|
return EGL_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
|
|
@ -379,9 +397,17 @@ dri2_create_screen(_EGLDisplay *disp)
|
||||||
unsigned int api_mask;
|
unsigned int api_mask;
|
||||||
|
|
||||||
dri2_dpy = disp->DriverData;
|
dri2_dpy = disp->DriverData;
|
||||||
dri2_dpy->dri_screen =
|
|
||||||
dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
|
if (dri2_dpy->dri2) {
|
||||||
&dri2_dpy->driver_configs, disp);
|
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) {
|
if (dri2_dpy->dri_screen == NULL) {
|
||||||
_eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
|
_eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
|
||||||
|
|
@ -389,13 +415,28 @@ dri2_create_screen(_EGLDisplay *disp)
|
||||||
}
|
}
|
||||||
|
|
||||||
extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
|
extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
|
||||||
if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
|
|
||||||
goto cleanup_dri_screen;
|
|
||||||
|
|
||||||
if (dri2_dpy->dri2->base.version >= 2)
|
if (dri2_dpy->dri2) {
|
||||||
api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
|
if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
|
||||||
else
|
goto cleanup_dri_screen;
|
||||||
api_mask = 1 << __DRI_API_OPENGL;
|
} 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);
|
||||||
|
else
|
||||||
|
api_mask = 1 << __DRI_API_OPENGL;
|
||||||
|
} else {
|
||||||
|
assert(dri2_dpy->swrast);
|
||||||
|
if (dri2_dpy->swrast->base.version >= 2)
|
||||||
|
api_mask = 1 << __DRI_API_OPENGL | 1 << __DRI_API_GLES | 1 << __DRI_API_GLES2;
|
||||||
|
else
|
||||||
|
api_mask = 1 << __DRI_API_OPENGL;
|
||||||
|
}
|
||||||
|
|
||||||
disp->ClientAPIs = 0;
|
disp->ClientAPIs = 0;
|
||||||
if (api_mask & (1 <<__DRI_API_OPENGL))
|
if (api_mask & (1 <<__DRI_API_OPENGL))
|
||||||
|
|
@ -405,10 +446,19 @@ dri2_create_screen(_EGLDisplay *disp)
|
||||||
if (api_mask & (1 << __DRI_API_GLES2))
|
if (api_mask & (1 << __DRI_API_GLES2))
|
||||||
disp->ClientAPIs |= EGL_OPENGL_ES2_BIT;
|
disp->ClientAPIs |= EGL_OPENGL_ES2_BIT;
|
||||||
|
|
||||||
if (dri2_dpy->dri2->base.version >= 2) {
|
if (dri2_dpy->dri2) {
|
||||||
disp->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
|
if (dri2_dpy->dri2->base.version >= 2) {
|
||||||
disp->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
|
disp->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
|
||||||
disp->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
|
disp->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
|
||||||
|
disp->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(dri2_dpy->swrast);
|
||||||
|
if (dri2_dpy->swrast->base.version >= 2) {
|
||||||
|
disp->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
|
||||||
|
disp->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
|
||||||
|
disp->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
|
|
@ -465,7 +515,8 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
_eglCleanupDisplay(disp);
|
_eglCleanupDisplay(disp);
|
||||||
|
|
||||||
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
|
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
|
||||||
close(dri2_dpy->fd);
|
if (dri2_dpy->fd)
|
||||||
|
close(dri2_dpy->fd);
|
||||||
dlclose(dri2_dpy->driver);
|
dlclose(dri2_dpy->driver);
|
||||||
if (disp->PlatformDisplay == NULL)
|
if (disp->PlatformDisplay == NULL)
|
||||||
xcb_disconnect(dri2_dpy->conn);
|
xcb_disconnect(dri2_dpy->conn);
|
||||||
|
|
@ -539,23 +590,45 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
|
||||||
else
|
else
|
||||||
dri_config = NULL;
|
dri_config = NULL;
|
||||||
|
|
||||||
if (dri2_dpy->dri2->base.version >= 2) {
|
if (dri2_dpy->dri2) {
|
||||||
dri2_ctx->dri_context =
|
if (dri2_dpy->dri2->base.version >= 2) {
|
||||||
dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen,
|
dri2_ctx->dri_context =
|
||||||
api,
|
dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen,
|
||||||
dri_config,
|
api,
|
||||||
dri2_ctx_shared ?
|
dri_config,
|
||||||
dri2_ctx_shared->dri_context : NULL,
|
dri2_ctx_shared ?
|
||||||
dri2_ctx);
|
dri2_ctx_shared->dri_context : NULL,
|
||||||
} else if (api == __DRI_API_OPENGL) {
|
dri2_ctx);
|
||||||
dri2_ctx->dri_context =
|
} else if (api == __DRI_API_OPENGL) {
|
||||||
dri2_dpy->dri2->createNewContext(dri2_dpy->dri_screen,
|
dri2_ctx->dri_context =
|
||||||
dri_config,
|
dri2_dpy->dri2->createNewContext(dri2_dpy->dri_screen,
|
||||||
dri2_ctx_shared ?
|
dri_config,
|
||||||
dri2_ctx_shared->dri_context : NULL,
|
dri2_ctx_shared ?
|
||||||
dri2_ctx);
|
dri2_ctx_shared->dri_context : NULL,
|
||||||
|
dri2_ctx);
|
||||||
|
} else {
|
||||||
|
/* fail */
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* fail */
|
assert(dri2_dpy->swrast);
|
||||||
|
if (dri2_dpy->swrast->base.version >= 2) {
|
||||||
|
dri2_ctx->dri_context =
|
||||||
|
dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen,
|
||||||
|
api,
|
||||||
|
dri_config,
|
||||||
|
dri2_ctx_shared ?
|
||||||
|
dri2_ctx_shared->dri_context : NULL,
|
||||||
|
dri2_ctx);
|
||||||
|
} else if (api == __DRI_API_OPENGL) {
|
||||||
|
dri2_ctx->dri_context =
|
||||||
|
dri2_dpy->core->createNewContext(dri2_dpy->dri_screen,
|
||||||
|
dri_config,
|
||||||
|
dri2_ctx_shared ?
|
||||||
|
dri2_ctx_shared->dri_context : NULL,
|
||||||
|
dri2_ctx);
|
||||||
|
} else {
|
||||||
|
/* fail */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dri2_ctx->dri_context)
|
if (!dri2_ctx->dri_context)
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ struct dri2_egl_display
|
||||||
void *driver;
|
void *driver;
|
||||||
__DRIcoreExtension *core;
|
__DRIcoreExtension *core;
|
||||||
__DRIdri2Extension *dri2;
|
__DRIdri2Extension *dri2;
|
||||||
|
__DRIswrastExtension *swrast;
|
||||||
__DRI2flushExtension *flush;
|
__DRI2flushExtension *flush;
|
||||||
__DRItexBufferExtension *tex_buffer;
|
__DRItexBufferExtension *tex_buffer;
|
||||||
__DRIimageExtension *image;
|
__DRIimageExtension *image;
|
||||||
|
|
@ -79,7 +80,8 @@ struct dri2_egl_display
|
||||||
char *device_name;
|
char *device_name;
|
||||||
char *driver_name;
|
char *driver_name;
|
||||||
|
|
||||||
__DRIdri2LoaderExtension dri2_loader_extension;
|
__DRIdri2LoaderExtension dri2_loader_extension;
|
||||||
|
__DRIswrastLoaderExtension swrast_loader_extension;
|
||||||
const __DRIextension *extensions[3];
|
const __DRIextension *extensions[3];
|
||||||
#ifdef HAVE_WAYLAND_PLATFORM
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
struct wl_egl_display *wl_dpy;
|
struct wl_egl_display *wl_dpy;
|
||||||
|
|
@ -118,6 +120,12 @@ struct dri2_egl_surface
|
||||||
xcb_xfixes_region_t region;
|
xcb_xfixes_region_t region;
|
||||||
int have_fake_front;
|
int have_fake_front;
|
||||||
int swap_interval;
|
int swap_interval;
|
||||||
|
|
||||||
|
int depth;
|
||||||
|
int bytes_per_pixel;
|
||||||
|
xcb_gcontext_t gc;
|
||||||
|
xcb_gcontext_t swapgc;
|
||||||
|
|
||||||
enum dri2_surface_type type;
|
enum dri2_surface_type type;
|
||||||
#ifdef HAVE_WAYLAND_PLATFORM
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
struct wl_egl_window *wl_win;
|
struct wl_egl_window *wl_win;
|
||||||
|
|
|
||||||
|
|
@ -639,6 +639,8 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
if (!dri2_dpy)
|
if (!dri2_dpy)
|
||||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||||
|
|
||||||
|
memset(dri2_dpy, 0, sizeof *dri2_dpy);
|
||||||
|
|
||||||
disp->DriverData = (void *) dri2_dpy;
|
disp->DriverData = (void *) dri2_dpy;
|
||||||
dri2_dpy->fd = (int) disp->PlatformDisplay;
|
dri2_dpy->fd = (int) disp->PlatformDisplay;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -599,6 +599,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
if (!dri2_dpy)
|
if (!dri2_dpy)
|
||||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||||
|
|
||||||
|
memset(dri2_dpy, 0, sizeof *dri2_dpy);
|
||||||
|
|
||||||
disp->DriverData = (void *) dri2_dpy;
|
disp->DriverData = (void *) dri2_dpy;
|
||||||
dri2_dpy->wl_dpy = disp->PlatformDisplay;
|
dri2_dpy->wl_dpy = disp->PlatformDisplay;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,137 @@
|
||||||
|
|
||||||
#include "egl_dri2.h"
|
#include "egl_dri2.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
swrastCreateDrawable(struct dri2_egl_display * dri2_dpy,
|
||||||
|
struct dri2_egl_surface * dri2_surf,
|
||||||
|
int depth)
|
||||||
|
{
|
||||||
|
uint32_t mask;
|
||||||
|
const uint32_t function = GXcopy;
|
||||||
|
uint32_t valgc[2];
|
||||||
|
|
||||||
|
/* create GC's */
|
||||||
|
dri2_surf->gc = xcb_generate_id(dri2_dpy->conn);
|
||||||
|
mask = XCB_GC_FUNCTION;
|
||||||
|
xcb_create_gc(dri2_dpy->conn, dri2_surf->gc, dri2_surf->drawable, mask, &function);
|
||||||
|
|
||||||
|
dri2_surf->swapgc = xcb_generate_id(dri2_dpy->conn);
|
||||||
|
mask = XCB_GC_FUNCTION | XCB_GC_GRAPHICS_EXPOSURES;
|
||||||
|
valgc[0] = function;
|
||||||
|
valgc[1] = False;
|
||||||
|
xcb_create_gc(dri2_dpy->conn, dri2_surf->swapgc, dri2_surf->drawable, mask, valgc);
|
||||||
|
dri2_surf->depth = depth;
|
||||||
|
switch (depth) {
|
||||||
|
case 32:
|
||||||
|
case 24:
|
||||||
|
dri2_surf->bytes_per_pixel = 4;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
dri2_surf->bytes_per_pixel = 2;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
dri2_surf->bytes_per_pixel = 1;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
dri2_surf->bytes_per_pixel = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_eglLog(_EGL_WARNING, "unsupported depth %d", depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swrastDestroyDrawable(struct dri2_egl_display * dri2_dpy,
|
||||||
|
struct dri2_egl_surface * dri2_surf)
|
||||||
|
{
|
||||||
|
xcb_free_gc(dri2_dpy->conn, dri2_surf->gc);
|
||||||
|
xcb_free_gc(dri2_dpy->conn, dri2_surf->swapgc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swrastGetDrawableInfo(__DRIdrawable * draw,
|
||||||
|
int *x, int *y, int *w, int *h,
|
||||||
|
void *loaderPrivate)
|
||||||
|
{
|
||||||
|
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||||
|
|
||||||
|
xcb_get_geometry_cookie_t cookie;
|
||||||
|
xcb_get_geometry_reply_t *reply;
|
||||||
|
xcb_generic_error_t *error;
|
||||||
|
|
||||||
|
*w = *h = 0;
|
||||||
|
cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
|
||||||
|
reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
|
||||||
|
if (reply == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (error != NULL) {
|
||||||
|
_eglLog(_EGL_WARNING, "error in xcb_get_geometry");
|
||||||
|
free(error);
|
||||||
|
} else {
|
||||||
|
*w = reply->width;
|
||||||
|
*h = reply->height;
|
||||||
|
}
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swrastPutImage(__DRIdrawable * draw, int op,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
char *data, void *loaderPrivate)
|
||||||
|
{
|
||||||
|
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||||
|
|
||||||
|
xcb_gcontext_t gc;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case __DRI_SWRAST_IMAGE_OP_DRAW:
|
||||||
|
gc = dri2_surf->gc;
|
||||||
|
break;
|
||||||
|
case __DRI_SWRAST_IMAGE_OP_SWAP:
|
||||||
|
gc = dri2_surf->swapgc;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_put_image(dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, dri2_surf->drawable,
|
||||||
|
gc, w, h, x, y, 0, dri2_surf->depth,
|
||||||
|
w*h*dri2_surf->bytes_per_pixel, (const uint8_t *)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swrastGetImage(__DRIdrawable * read,
|
||||||
|
int x, int y, int w, int h,
|
||||||
|
char *data, void *loaderPrivate)
|
||||||
|
{
|
||||||
|
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||||
|
|
||||||
|
xcb_get_image_cookie_t cookie;
|
||||||
|
xcb_get_image_reply_t *reply;
|
||||||
|
xcb_generic_error_t *error;
|
||||||
|
|
||||||
|
cookie = xcb_get_image (dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
|
||||||
|
dri2_surf->drawable, x, y, w, h, ~0);
|
||||||
|
reply = xcb_get_image_reply (dri2_dpy->conn, cookie, &error);
|
||||||
|
if (reply == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (error != NULL) {
|
||||||
|
_eglLog(_EGL_WARNING, "error in xcb_get_image");
|
||||||
|
free(error);
|
||||||
|
} else {
|
||||||
|
uint32_t bytes = xcb_get_image_data_length(reply);
|
||||||
|
uint8_t *idata = xcb_get_image_data(reply);
|
||||||
|
memcpy(data, idata, bytes);
|
||||||
|
}
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
|
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
|
||||||
*/
|
*/
|
||||||
|
|
@ -77,18 +208,31 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
|
||||||
dri2_surf->drawable = window;
|
dri2_surf->drawable = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
dri2_surf->dri_drawable =
|
if (dri2_dpy->dri2) {
|
||||||
(*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
|
dri2_surf->dri_drawable =
|
||||||
type == EGL_WINDOW_BIT ?
|
(*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
|
||||||
dri2_conf->dri_double_config :
|
type == EGL_WINDOW_BIT ?
|
||||||
dri2_conf->dri_single_config,
|
dri2_conf->dri_double_config :
|
||||||
dri2_surf);
|
dri2_conf->dri_single_config,
|
||||||
|
dri2_surf);
|
||||||
|
} else {
|
||||||
|
assert(dri2_dpy->swrast);
|
||||||
|
dri2_surf->dri_drawable =
|
||||||
|
(*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
|
||||||
|
dri2_conf->dri_double_config,
|
||||||
|
dri2_surf);
|
||||||
|
}
|
||||||
|
|
||||||
if (dri2_surf->dri_drawable == NULL) {
|
if (dri2_surf->dri_drawable == NULL) {
|
||||||
_eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
|
_eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
|
||||||
goto cleanup_pixmap;
|
goto cleanup_pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable);
|
if (dri2_dpy->dri2) {
|
||||||
|
xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable);
|
||||||
|
} else {
|
||||||
|
swrastCreateDrawable(dri2_dpy, dri2_surf, _eglGetConfigKey(conf, EGL_DEPTH_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
if (type != EGL_PBUFFER_BIT) {
|
if (type != EGL_PBUFFER_BIT) {
|
||||||
cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
|
cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
|
||||||
|
|
@ -159,7 +303,12 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
|
||||||
|
|
||||||
(*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
|
(*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
|
||||||
|
|
||||||
xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable);
|
if (dri2_dpy->dri2) {
|
||||||
|
xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable);
|
||||||
|
} else {
|
||||||
|
assert(dri2_dpy->swrast);
|
||||||
|
swrastDestroyDrawable(dri2_dpy, dri2_surf);
|
||||||
|
}
|
||||||
|
|
||||||
if (surf->Type == EGL_PBUFFER_BIT)
|
if (surf->Type == EGL_PBUFFER_BIT)
|
||||||
xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable);
|
xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable);
|
||||||
|
|
@ -351,7 +500,7 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
|
||||||
xfixes_query_cookie, &error);
|
xfixes_query_cookie, &error);
|
||||||
if (xfixes_query == NULL ||
|
if (xfixes_query == NULL ||
|
||||||
error != NULL || xfixes_query->major_version < 2) {
|
error != NULL || xfixes_query->major_version < 2) {
|
||||||
_eglLog(_EGL_FATAL, "DRI2: failed to query xfixes version");
|
_eglLog(_EGL_WARNING, "DRI2: failed to query xfixes version");
|
||||||
free(error);
|
free(error);
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +509,7 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
|
||||||
dri2_query =
|
dri2_query =
|
||||||
xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error);
|
xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error);
|
||||||
if (dri2_query == NULL || error != NULL) {
|
if (dri2_query == NULL || error != NULL) {
|
||||||
_eglLog(_EGL_FATAL, "DRI2: failed to query version");
|
_eglLog(_EGL_WARNING, "DRI2: failed to query version");
|
||||||
free(error);
|
free(error);
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -371,7 +520,7 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
|
||||||
connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL);
|
connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL);
|
||||||
if (connect == NULL ||
|
if (connect == NULL ||
|
||||||
connect->driver_name_length + connect->device_name_length == 0) {
|
connect->driver_name_length + connect->device_name_length == 0) {
|
||||||
_eglLog(_EGL_FATAL, "DRI2: failed to authenticate");
|
_eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,7 +552,7 @@ dri2_authenticate(struct dri2_egl_display *dri2_dpy)
|
||||||
drm_magic_t magic;
|
drm_magic_t magic;
|
||||||
|
|
||||||
if (drmGetMagic(dri2_dpy->fd, &magic)) {
|
if (drmGetMagic(dri2_dpy->fd, &magic)) {
|
||||||
_eglLog(_EGL_FATAL, "DRI2: failed to get drm magic");
|
_eglLog(_EGL_WARNING, "DRI2: failed to get drm magic");
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,7 +562,7 @@ dri2_authenticate(struct dri2_egl_display *dri2_dpy)
|
||||||
authenticate =
|
authenticate =
|
||||||
xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
|
xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
|
||||||
if (authenticate == NULL || !authenticate->authenticated) {
|
if (authenticate == NULL || !authenticate->authenticated) {
|
||||||
_eglLog(_EGL_FATAL, "DRI2: failed to authenticate");
|
_eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
|
||||||
free(authenticate);
|
free(authenticate);
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -525,9 +674,17 @@ dri2_copy_region(_EGLDriver *drv, _EGLDisplay *disp,
|
||||||
static EGLBoolean
|
static EGLBoolean
|
||||||
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
|
dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
|
||||||
{
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
|
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
|
||||||
|
|
||||||
return dri2_copy_region(drv, disp, draw, dri2_surf->region);
|
if (dri2_dpy->dri2) {
|
||||||
|
return dri2_copy_region(drv, disp, draw, dri2_surf->region);
|
||||||
|
} else {
|
||||||
|
assert(dri2_dpy->swrast);
|
||||||
|
|
||||||
|
dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
|
||||||
|
return EGL_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static EGLBoolean
|
static EGLBoolean
|
||||||
|
|
@ -690,8 +847,88 @@ dri2_x11_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLBoolean
|
static EGLBoolean
|
||||||
dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
|
dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy;
|
||||||
|
|
||||||
|
drv->API.CreateWindowSurface = dri2_create_window_surface;
|
||||||
|
drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
|
||||||
|
drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
|
||||||
|
drv->API.DestroySurface = dri2_destroy_surface;
|
||||||
|
drv->API.SwapBuffers = dri2_swap_buffers;
|
||||||
|
drv->API.CopyBuffers = dri2_copy_buffers;
|
||||||
|
|
||||||
|
drv->API.SwapBuffersRegionNOK = NULL;
|
||||||
|
drv->API.CreateImageKHR = NULL;
|
||||||
|
drv->API.DestroyImageKHR = NULL;
|
||||||
|
drv->API.CreateDRMImageMESA = NULL;
|
||||||
|
drv->API.ExportDRMImageMESA = NULL;
|
||||||
|
|
||||||
|
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;
|
||||||
|
if (disp->PlatformDisplay == NULL) {
|
||||||
|
dri2_dpy->conn = xcb_connect(0, 0);
|
||||||
|
} else {
|
||||||
|
dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xcb_connection_has_error(dri2_dpy->conn)) {
|
||||||
|
_eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
|
||||||
|
goto cleanup_dpy;
|
||||||
|
}
|
||||||
|
|
||||||
|
dri2_dpy->driver_name = dri2_strndup("swrast", strlen("swrast"));
|
||||||
|
|
||||||
|
if (!dri2_load_driver(disp))
|
||||||
|
goto cleanup_conn;
|
||||||
|
|
||||||
|
dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
|
||||||
|
dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
|
||||||
|
dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
|
||||||
|
dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
|
||||||
|
dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
|
||||||
|
|
||||||
|
dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
|
||||||
|
dri2_dpy->extensions[1] = NULL;
|
||||||
|
dri2_dpy->extensions[2] = NULL;
|
||||||
|
|
||||||
|
if (!dri2_create_screen(disp))
|
||||||
|
goto cleanup_driver;
|
||||||
|
|
||||||
|
if (dri2_dpy->conn) {
|
||||||
|
if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
|
||||||
|
goto cleanup_configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we're supporting EGL 1.4 */
|
||||||
|
disp->VersionMajor = 1;
|
||||||
|
disp->VersionMinor = 4;
|
||||||
|
|
||||||
|
return EGL_TRUE;
|
||||||
|
|
||||||
|
cleanup_configs:
|
||||||
|
_eglCleanupDisplay(disp);
|
||||||
|
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
|
||||||
|
cleanup_driver:
|
||||||
|
dlclose(dri2_dpy->driver);
|
||||||
|
cleanup_conn:
|
||||||
|
if (disp->PlatformDisplay == NULL)
|
||||||
|
xcb_disconnect(dri2_dpy->conn);
|
||||||
|
cleanup_dpy:
|
||||||
|
free(dri2_dpy);
|
||||||
|
|
||||||
|
return EGL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static EGLBoolean
|
||||||
|
dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
{
|
{
|
||||||
struct dri2_egl_display *dri2_dpy;
|
struct dri2_egl_display *dri2_dpy;
|
||||||
|
|
||||||
|
|
@ -708,6 +945,8 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
if (!dri2_dpy)
|
if (!dri2_dpy)
|
||||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||||
|
|
||||||
|
memset(dri2_dpy, 0, sizeof *dri2_dpy);
|
||||||
|
|
||||||
disp->DriverData = (void *) dri2_dpy;
|
disp->DriverData = (void *) dri2_dpy;
|
||||||
if (disp->PlatformDisplay == NULL) {
|
if (disp->PlatformDisplay == NULL) {
|
||||||
dri2_dpy->conn = xcb_connect(0, 0);
|
dri2_dpy->conn = xcb_connect(0, 0);
|
||||||
|
|
@ -797,3 +1036,22 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
|
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLBoolean
|
||||||
|
dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
|
{
|
||||||
|
EGLBoolean initialized = EGL_TRUE;
|
||||||
|
|
||||||
|
int x11_dri2_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
|
||||||
|
|
||||||
|
if (x11_dri2_accel) {
|
||||||
|
if (!dri2_initialize_x11_dri2(drv, disp)) {
|
||||||
|
initialized = dri2_initialize_x11_swrast(drv, disp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initialized = dri2_initialize_x11_swrast(drv, disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue