diff options
Diffstat (limited to 'src/egl/drivers/xdri')
-rw-r--r-- | src/egl/drivers/xdri/Makefile | 78 | ||||
-rw-r--r-- | src/egl/drivers/xdri/driinit.c | 67 | ||||
-rw-r--r-- | src/egl/drivers/xdri/driinit.h | 9 | ||||
-rw-r--r-- | src/egl/drivers/xdri/egl_xdri.c | 784 | ||||
-rw-r--r-- | src/egl/drivers/xdri/glxinit.c | 626 | ||||
-rw-r--r-- | src/egl/drivers/xdri/glxinit.h | 14 |
6 files changed, 1578 insertions, 0 deletions
diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile new file mode 100644 index 0000000000..4c1fc9071c --- /dev/null +++ b/src/egl/drivers/xdri/Makefile @@ -0,0 +1,78 @@ +# src/egl/drivers/xdri/Makefile + +# Build XEGL DRI driver loader library: egl_xdri.so + + +TOP = ../../../.. +include $(TOP)/configs/current + + +DRIVER_NAME = egl_xdri.so + + +INCLUDE_DIRS = \ + -I. \ + -I/usr/include \ + $(shell pkg-config --cflags-only-I libdrm) \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/glx/x11 + +HEADERS = glxinit.h driinit.h +SOURCES = egl_xdri.c glxinit.c driinit.c + +DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c +DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES)) + +SOURCES += $(DRI_SOURCES) + +OBJECTS = $(SOURCES:.c=.o) + +DRM_LIB = `pkg-config --libs libdrm` + +CFLAGS += -DGLX_DIRECT_RENDERING + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + +.PHONY: library + + +default: depend library Makefile + + +library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) + + +# Make the egl_xdri.so library +$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) + $(TOP)/bin/mklib -o $(DRIVER_NAME) \ + -noprefix \ + -major 1 -minor 0 \ + -L$(TOP)/$(LIB_DIR) \ + -install $(TOP)/$(LIB_DIR) \ + $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS) + +install: + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) + +clean: + rm -f *.o + rm -f *.so + rm -f depend depend.bak + + +depend: $(SOURCES) $(HEADERS) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ + $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null + +include depend +# DO NOT DELETE diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c new file mode 100644 index 0000000000..12da1bcd24 --- /dev/null +++ b/src/egl/drivers/xdri/driinit.c @@ -0,0 +1,67 @@ +/** + * DRI initialization. The DRI loaders are defined in src/glx/x11/. + */ + +#include <sys/time.h> + +#include "glxclient.h" +#include "driinit.h" + +/* for __DRI_SYSTEM_TIME extension */ +_X_HIDDEN int +__glXGetUST(int64_t * ust) +{ + struct timeval tv; + + if (ust == NULL) { + return -EFAULT; + } + + if (gettimeofday(&tv, NULL) == 0) { + ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; + return 0; + } + else { + return -errno; + } +} + +_X_HIDDEN GLboolean +__driGetMscRateOML(__DRIdrawable * draw, + int32_t * numerator, int32_t * denominator, void *private) +{ + return GL_FALSE; +} + +/* ignore glx extensions */ +_X_HIDDEN void +__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) +{ +} + +_X_HIDDEN __GLXDRIdisplay * +__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version) +{ + __GLXDRIdisplay *driDisplay; + int ver = 0; + + /* try DRI2 first */ + driDisplay = dri2CreateDisplay(dpyPriv->dpy); + if (driDisplay) { + /* fill in the required field */ + dpyPriv->dri2Display = driDisplay; + ver = 2; + } + else { + /* try DRI */ + driDisplay = driCreateDisplay(dpyPriv->dpy); + if (driDisplay) { + dpyPriv->driDisplay = driDisplay; + ver = 1; + } + } + + if (version) + *version = ver; + return driDisplay; +} diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h new file mode 100644 index 0000000000..6ea05cebef --- /dev/null +++ b/src/egl/drivers/xdri/driinit.h @@ -0,0 +1,9 @@ +#ifndef DRIINIT_INCLUDED +#define DRIINIT_INCLUDED + +#include "glxclient.h" + +extern __GLXDRIdisplay * +__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version); + +#endif /* DRIINIT_INCLUDED */ diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c new file mode 100644 index 0000000000..9793e4f8b4 --- /dev/null +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -0,0 +1,784 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Code to interface a DRI driver to libEGL. + * Note that unlike previous DRI/EGL interfaces, this one is meant to + * be used _with_ X. Applications will use eglCreateWindowSurface() + * to render into X-created windows. + * + * This is an EGL driver that, in turn, loads a regular DRI driver. + * There are some dependencies on code in libGL, but those could be + * removed with some effort. + * + * Authors: Brian Paul + */ + +#include <assert.h> +#include <stdlib.h> +#include <X11/Xlib.h> + +#include "glxinit.h" +#include "driinit.h" +#include "glapi/glapi.h" /* for glapi functions */ + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "egllog.h" +#include "eglsurface.h" +#include "eglimage.h" + +#include "EGL/internal/eglimage_dri.h" + +#define MAX_DEPTH 32 +#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) + +/** subclass of _EGLDriver */ +struct xdri_egl_driver +{ + _EGLDriver Base; /**< base class */ + void (*FlushCurrentContext)(void); +}; + + +/** driver data of _EGLDisplay */ +struct xdri_egl_display +{ + Display *dpy; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplay *driDisplay; + + __GLXscreenConfigs *psc; + EGLint scr; + + const __GLcontextModes *imageConfigs[MAX_DEPTH + 1]; +}; + + +/** subclass of _EGLContext */ +struct xdri_egl_context +{ + _EGLContext Base; /**< base class */ + + /* just enough info to create dri contexts */ + GLXContext dummy_gc; + + __GLXDRIcontext *driContext; +}; + + +/** subclass of _EGLSurface */ +struct xdri_egl_surface +{ + _EGLSurface Base; /**< base class */ + + Drawable drawable; + __GLXDRIdrawable *driDrawable; +}; + + +/** subclass of _EGLImage */ +struct xdri_egl_image +{ + _EGLImage Base; /**< base class */ + + Drawable pixmap; + __GLXDRIdrawable *driDrawable; +}; + + +/** subclass of _EGLConfig */ +struct xdri_egl_config +{ + _EGLConfig Base; /**< base class */ + + const __GLcontextModes *mode; /**< corresponding GLX mode */ +}; + + + +/** cast wrapper */ +static INLINE struct xdri_egl_driver * +xdri_egl_driver(_EGLDriver *drv) +{ + return (struct xdri_egl_driver *) drv; +} + + +static INLINE struct xdri_egl_display * +lookup_display(_EGLDisplay *dpy) +{ + return (struct xdri_egl_display *) dpy->DriverData; +} + + +/** Map EGLSurface handle to xdri_egl_surface object */ +static INLINE struct xdri_egl_surface * +lookup_surface(_EGLSurface *surface) +{ + return (struct xdri_egl_surface *) surface; +} + + +/** Map EGLContext handle to xdri_egl_context object */ +static INLINE struct xdri_egl_context * +lookup_context(_EGLContext *context) +{ + return (struct xdri_egl_context *) context; +} + + +/** Map EGLConfig handle to xdri_egl_config object */ +static INLINE struct xdri_egl_config * +lookup_config(_EGLConfig *conf) +{ + return (struct xdri_egl_config *) conf; +} + + +/** Map EGLImage handle to xdri_egl_image object */ +static INLINE struct xdri_egl_image * +lookup_image(_EGLImage *img) +{ + return (struct xdri_egl_image *) img; +} + + +/** Get size of given window */ +static Status +get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} + + +#if EGL_KHR_image_base +/** Get depth of given window */ +static Status +get_drawable_depth(Display *dpy, Drawable d, uint *depth_ret) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *depth_ret = depth; + return stat; +} + + +/** + * The config of a pixmap must be guessed from its depth. Do the guess once + * for all depths. + */ +static void +find_image_configs(_EGLDisplay *dpy, const __GLcontextModes *modes) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + EGLint depth; + + for (depth = 0; depth < MAX_DEPTH + 1; depth++) { + const __GLcontextModes *m; + + for (m = modes; m; m = m->next) { + /* the depth of a pixmap might not include alpha */ + if (m->rgbBits != depth && (m->rgbBits - m->alphaBits) != depth) + continue; + if (!m->visualID) + continue; + + if (depth == 32) { + if (m->bindToTextureRgba) { + xdri_dpy->imageConfigs[depth] = m; + break; + } + } + + if (m->bindToTextureRgb) { + xdri_dpy->imageConfigs[depth] = m; + break; + } + } + + if (m) + _eglLog(_EGL_DEBUG, "Use mode 0x%02x for depth %d", + m->visualID, depth); + } +} +#endif /* EGL_KHR_image_base */ + + +/** + * Produce a set of EGL configs. + */ +static EGLint +create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) +{ + static const EGLint all_apis = (EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENVG_BIT | + EGL_OPENGL_BIT); + int id = first_id; + + for (; m; m = m->next) { + /* add double buffered visual */ + if (m->doubleBufferMode) { + struct xdri_egl_config *config = CALLOC_STRUCT(xdri_egl_config); + + _eglInitConfig(&config->Base, id++); + + SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, m->rgbBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, m->redBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_GREEN_SIZE, m->greenBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_BLUE_SIZE, m->blueBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_ALPHA_SIZE, m->alphaBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_DEPTH_SIZE, m->depthBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_STENCIL_SIZE, m->stencilBits); + SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLES, m->samples); + SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLE_BUFFERS, m->sampleBuffers); + SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, m->visualID); + SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_TYPE, m->visualType); + SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis); + SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis); + SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); + + /* XXX possibly other things to init... */ + + /* Ptr from EGL config to GLcontextMode. Used in CreateContext(). */ + config->mode = m; + + _eglAddConfig(disp, &config->Base); + } + } + + return id; +} + + +/** + * Called via eglInitialize(), xdri_dpy->API.Initialize(). + */ +static EGLBoolean +xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, + EGLint *minor, EGLint *major) +{ + struct xdri_egl_display *xdri_dpy; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplay *driDisplay; + __GLXscreenConfigs *psc; + EGLint first_id = 1; + int scr; + + xdri_dpy = CALLOC_STRUCT(xdri_egl_display); + if (!xdri_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + xdri_dpy->dpy = (Display *) dpy->NativeDisplay; + if (!xdri_dpy->dpy) { + xdri_dpy->dpy = XOpenDisplay(NULL); + if (!xdri_dpy->dpy) { + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); + } + } + + dpyPriv = __glXInitialize(xdri_dpy->dpy); + if (!dpyPriv) { + _eglLog(_EGL_WARNING, "failed to create GLX display"); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); + } + + driDisplay = __driCreateDisplay(dpyPriv, NULL); + if (!driDisplay) { + _eglLog(_EGL_WARNING, "failed to create DRI display"); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); + } + + scr = DefaultScreen(xdri_dpy->dpy); + psc = &dpyPriv->screenConfigs[scr]; + + xdri_dpy->dpyPriv = dpyPriv; + xdri_dpy->driDisplay = driDisplay; + xdri_dpy->psc = psc; + xdri_dpy->scr = scr; + + psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv); + if (!psc->driScreen) { + _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr); + free(xdri_dpy); + return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); + } + + /* add visuals and fbconfigs */ + first_id = create_configs(dpy, psc->visuals, first_id); + create_configs(dpy, psc->configs, first_id); + + dpy->DriverData = xdri_dpy; + dpy->ClientAPIsMask = (EGL_OPENGL_BIT | + EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENVG_BIT); + +#if EGL_KHR_image_base + /* must be called after DriverData is set */ + find_image_configs(dpy, psc->configs); + + dpy->Extensions.KHR_image = EGL_TRUE; + dpy->Extensions.KHR_image_base = EGL_TRUE; + dpy->Extensions.KHR_image_pixmap = EGL_TRUE; +#endif + + /* we're supporting EGL 1.4 */ + *minor = 1; + *major = 4; + + return EGL_TRUE; +} + + +/** + * Called via eglTerminate(), drv->API.Terminate(). + */ +static EGLBoolean +xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + __GLXscreenConfigs *psc; + + _eglReleaseDisplayResources(drv, dpy); + _eglCleanupDisplay(dpy); + + psc = xdri_dpy->psc; + if (psc->driver_configs) { + unsigned int i; + for (i = 0; psc->driver_configs[i]; i++) + free((__DRIconfig *) psc->driver_configs[i]); + free(psc->driver_configs); + psc->driver_configs = NULL; + } + if (psc->driScreen) { + psc->driScreen->destroyScreen(psc); + free(psc->driScreen); + psc->driScreen = NULL; + } + + xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay); + __glXRelease(xdri_dpy->dpyPriv); + + free(xdri_dpy); + dpy->DriverData = NULL; + + return EGL_TRUE; +} + + +/* + * Called from eglGetProcAddress() via drv->API.GetProcAddress(). + */ +static _EGLProc +xdri_eglGetProcAddress(const char *procname) +{ + /* the symbol is defined in libGL.so */ + return (_EGLProc) _glapi_get_proc_address(procname); +} + + +/** + * Called via eglCreateContext(), drv->API.CreateContext(). + */ +static _EGLContext * +xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + _EGLContext *share_list, const EGLint *attrib_list) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_config *xdri_config = lookup_config(conf); + struct xdri_egl_context *shared = lookup_context(share_list); + __GLXscreenConfigs *psc = xdri_dpy->psc; + int renderType = GLX_RGBA_BIT; + struct xdri_egl_context *xdri_ctx; + + xdri_ctx = CALLOC_STRUCT(xdri_egl_context); + if (!xdri_ctx) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); + return NULL; + } + + xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec); + if (!xdri_ctx->dummy_gc) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); + free(xdri_ctx); + return NULL; + } + + if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) { + free(xdri_ctx->dummy_gc); + free(xdri_ctx); + return NULL; + } + + xdri_ctx->driContext = + psc->driScreen->createContext(psc, + xdri_config->mode, + xdri_ctx->dummy_gc, + (shared) ? shared->dummy_gc : NULL, + renderType); + if (!xdri_ctx->driContext) { + free(xdri_ctx->dummy_gc); + free(xdri_ctx); + return NULL; + } + + /* fill in the required field */ + xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext; + + return &xdri_ctx->Base; +} + + +static EGLBoolean +xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_context *xdri_ctx = lookup_context(ctx); + + if (!_eglIsContextBound(ctx)) { + xdri_ctx->driContext->destroyContext(xdri_ctx->driContext, + xdri_dpy->psc, xdri_dpy->dpy); + free(xdri_ctx->dummy_gc); + free(xdri_ctx); + } + + return EGL_TRUE; +} + + +/** + * Called via eglMakeCurrent(), drv->API.MakeCurrent(). + */ +static EGLBoolean +xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, + _EGLSurface *r, _EGLContext *context) +{ + struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv); + struct xdri_egl_context *xdri_ctx = lookup_context(context); + struct xdri_egl_surface *draw = lookup_surface(d); + struct xdri_egl_surface *read = lookup_surface(r); + _EGLContext *old = _eglGetCurrentContext(); + + /* an unlinked context will be invalid after context switch */ + if (!_eglIsContextLinked(old)) + old = NULL; + + if (!_eglMakeCurrent(drv, dpy, d, r, context)) + return EGL_FALSE; + + /* flush before context switch */ + if (old && old != context && xdri_driver->FlushCurrentContext) + xdri_driver->FlushCurrentContext(); + + /* the symbol is defined in libGL.so */ + _glapi_check_multithread(); + + if (xdri_ctx) { + if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext, + draw->driDrawable, + read->driDrawable)) { + return EGL_FALSE; + } + } + else if (old) { + xdri_ctx = lookup_context(old); + xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); + } + + return EGL_TRUE; +} + + +/** + * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). + */ +static _EGLSurface * +xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + NativeWindowType window, const EGLint *attrib_list) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_config *xdri_config = lookup_config(conf); + struct xdri_egl_surface *xdri_surf; + uint width, height; + + xdri_surf = CALLOC_STRUCT(xdri_egl_surface); + if (!xdri_surf) { + _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + return NULL; + } + + if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT, + &xdri_config->Base, attrib_list)) { + free(xdri_surf); + return NULL; + } + + xdri_surf->driDrawable = + xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc, + (XID) window, + (GLXDrawable) window, + xdri_config->mode); + if (!xdri_surf->driDrawable) { + free(xdri_surf); + return NULL; + } + + xdri_surf->drawable = (Drawable) window; + + get_drawable_size(xdri_dpy->dpy, window, &width, &height); + xdri_surf->Base.Width = width; + xdri_surf->Base.Height = height; + + return &xdri_surf->Base; +} + + +/** + * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface(). + */ +static _EGLSurface * +xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + const EGLint *attrib_list) +{ + return NULL; +} + + + +static EGLBoolean +xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) +{ + struct xdri_egl_surface *xdri_surf = lookup_surface(surface); + + if (!_eglIsSurfaceBound(&xdri_surf->Base)) { + xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); + free(xdri_surf); + } + + return EGL_TRUE; +} + + +static EGLBoolean +xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + EGLint buffer) +{ + return EGL_FALSE; +} + + +static EGLBoolean +xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + EGLint buffer) +{ + return EGL_FALSE; +} + + +static EGLBoolean +xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) +{ + struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv); + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_surface *xdri_surf = lookup_surface(draw); + + /* swapBuffers does not flush commands */ + if (draw == _eglGetCurrentSurface(EGL_DRAW) && + xdri_driver->FlushCurrentContext) + xdri_driver->FlushCurrentContext(); + + xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable); + + return EGL_TRUE; +} + + +#if EGL_KHR_image_base + + +static _EGLImage * +xdri_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, + EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) +{ + struct xdri_egl_display *xdri_dpy = lookup_display(dpy); + struct xdri_egl_image *xdri_img; + __DRIEGLImage *driImage; + EGLint err = EGL_SUCCESS; + const __GLcontextModes *mode; + uint depth; + + xdri_img = CALLOC_STRUCT(xdri_egl_image); + if (!xdri_img) { + _eglError(EGL_BAD_ALLOC, "eglCreateImageKHR"); + return NULL; + } + + switch (target) { + case EGL_NATIVE_PIXMAP_KHR: + if (ctx) { + err = EGL_BAD_PARAMETER; + break; + } + xdri_img->pixmap = (Pixmap) buffer; + break; + default: + err = EGL_BAD_PARAMETER; + break; + } + + if (err != EGL_SUCCESS) { + _eglError(EGL_BAD_PARAMETER, "eglCreateImageKHR"); + free(xdri_img); + return NULL; + } + + if (!_eglInitImage(drv, &xdri_img->Base, attr_list)) { + free(xdri_img); + return NULL; + } + if (!get_drawable_depth(xdri_dpy->dpy, xdri_img->pixmap, &depth) || + depth > MAX_DEPTH) { + free(xdri_img); + return NULL; + } + mode = xdri_dpy->imageConfigs[depth]; + if (!mode) { + free(xdri_img); + return NULL; + } + + driImage = CALLOC_STRUCT(__DRIEGLImageRec); + if (!driImage) { + _eglError(EGL_BAD_ALLOC, "eglCreateImageKHR"); + free(xdri_img); + return NULL; + } + + xdri_img->driDrawable = + xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc, + (XID) xdri_img->pixmap, + (GLXDrawable) xdri_img->pixmap, + mode); + if (!xdri_img->driDrawable) { + free(driImage); + free(xdri_img); + return NULL; + } + + driImage->magic = __DRI_EGL_IMAGE_MAGIC; + driImage->drawable = xdri_img->driDrawable->driDrawable; + driImage->texture_format_rgba = (depth == 32 && mode->bindToTextureRgba); + driImage->level = 0; + + xdri_img->Base.ClientData = (void *) driImage; + + return &xdri_img->Base; +} + + +static EGLBoolean +xdri_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img) +{ + struct xdri_egl_image *xdri_img = lookup_image(img); + + free(xdri_img->Base.ClientData); + xdri_img->driDrawable->destroyDrawable(xdri_img->driDrawable); + free(xdri_img); + return EGL_TRUE; +} + + +#endif /* EGL_KHR_image_base */ + + +static void +xdri_Unload(_EGLDriver *drv) +{ + struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); + free(xdri_drv); +} + + +/** + * This is the main entrypoint into the driver, called by libEGL. + * Create a new _EGLDriver object and init its dispatch table. + */ +_EGLDriver * +_eglMain(const char *args) +{ + struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver); + if (!xdri_drv) + return NULL; + + _eglInitDriverFallbacks(&xdri_drv->Base); + xdri_drv->Base.API.Initialize = xdri_eglInitialize; + xdri_drv->Base.API.Terminate = xdri_eglTerminate; + + xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress; + + xdri_drv->Base.API.CreateContext = xdri_eglCreateContext; + xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext; + xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent; + xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface; + xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface; + xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface; + xdri_drv->Base.API.BindTexImage = xdri_eglBindTexImage; + xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage; + xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers; +#if EGL_KHR_image_base + xdri_drv->Base.API.CreateImageKHR = xdri_eglCreateImageKHR; + xdri_drv->Base.API.DestroyImageKHR = xdri_eglDestroyImageKHR; +#endif /* EGL_KHR_image_base */ + + xdri_drv->Base.Name = "X/DRI"; + xdri_drv->Base.Unload = xdri_Unload; + + /* we need a way to flush commands */ + xdri_drv->FlushCurrentContext = + (void (*)(void)) xdri_eglGetProcAddress("glFlush"); + + return &xdri_drv->Base; +} diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c new file mode 100644 index 0000000000..7775009394 --- /dev/null +++ b/src/egl/drivers/xdri/glxinit.c @@ -0,0 +1,626 @@ +/** + * GLX initialization. Code based on glxext.c, glx_query.c, and + * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI + * related code here. + * + */ + +#include <assert.h> +#include <X11/Xlib.h> +#include <X11/Xproto.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include <sys/time.h> + +#include "glxinit.h" + +typedef struct GLXGenericGetString +{ + CARD8 reqType; + CARD8 glxCode; + CARD16 length B16; + CARD32 for_whom B32; + CARD32 name B32; +} xGLXGenericGetStringReq; + +#define sz_xGLXGenericGetStringReq 12 +#define X_GLXGenericGetString 0 + +/* Extension required boiler plate */ + +static char *__glXExtensionName = GLX_EXTENSION_NAME; +static XExtensionInfo *__glXExtensionInfo = NULL; + +static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; +static +XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, + __glXExtensionName, &__glXExtensionHooks, + __GLX_NUMBER_EVENTS, NULL) + +static GLint +_gl_convert_from_x_visual_type(int visualType) +{ +#define NUM_VISUAL_TYPES 6 + static const int glx_visual_types[NUM_VISUAL_TYPES] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ((unsigned) visualType < NUM_VISUAL_TYPES) + ? glx_visual_types[visualType] : GLX_NONE; +} + +static __GLcontextModes * +_gl_context_modes_create(unsigned count, size_t minimum_size) +{ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes *base = NULL; + __GLcontextModes **next; + unsigned i; + + next = &base; + for (i = 0; i < count; i++) { + *next = (__GLcontextModes *) Xmalloc(size); + if (*next == NULL) { + _gl_context_modes_destroy(base); + base = NULL; + break; + } + + memset(*next, 0, size); + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = GLX_DONT_CARE; + (*next)->yInverted = GLX_DONT_CARE; + + next = &((*next)->next); + } + + return base; +} + +_X_HIDDEN void +_gl_context_modes_destroy(__GLcontextModes * modes) +{ + while (modes != NULL) { + __GLcontextModes *const next = modes->next; + + Xfree(modes); + modes = next; + } +} + +_X_HIDDEN char * +__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name) +{ + xGLXGenericGetStringReq *req; + xGLXSingleReply reply; + int length; + int numbytes; + char *buf; + CARD32 for_whom = screen; + CARD32 glxCode = X_GLXQueryServerString; + + + LockDisplay(dpy); + + + /* All of the GLX protocol requests for getting a string from the server + * look the same. The exact meaning of the for_whom field is usually + * either the screen number (for glXQueryServerString) or the context tag + * (for GLXSingle). + */ + + GetReq(GLXGenericGetString, req); + req->reqType = opcode; + req->glxCode = glxCode; + req->for_whom = for_whom; + req->name = name; + + _XReply(dpy, (xReply *) & reply, 0, False); + + length = reply.length * 4; + numbytes = reply.size; + + buf = (char *) Xmalloc(numbytes); + if (buf != NULL) { + _XRead(dpy, buf, numbytes); + length -= numbytes; + } + + _XEatData(dpy, length); + + UnlockDisplay(dpy); + SyncHandle(); + + return buf; +} + +/************************************************************************/ +/* +** Free the per screen configs data as well as the array of +** __glXScreenConfigs. +*/ +static void +FreeScreenConfigs(__GLXdisplayPrivate * priv) +{ + __GLXscreenConfigs *psc; + GLint i, screens; + + /* Free screen configuration information */ + psc = priv->screenConfigs; + screens = ScreenCount(priv->dpy); + for (i = 0; i < screens; i++, psc++) { + if (psc->configs) { + _gl_context_modes_destroy(psc->configs); + psc->configs = NULL; /* NOTE: just for paranoia */ + } + if (psc->visuals) { + _gl_context_modes_destroy(psc->visuals); + psc->visuals = NULL; /* NOTE: just for paranoia */ + } + Xfree((char *) psc->serverGLXexts); + } + XFree((char *) priv->screenConfigs); + priv->screenConfigs = NULL; +} + +/************************************************************************/ + +/* +** Query the version of the GLX extension. This procedure works even if +** the client extension is not completely set up. +*/ +static Bool +QueryVersion(Display * dpy, int opcode, int *major, int *minor) +{ + xGLXQueryVersionReq *req; + xGLXQueryVersionReply reply; + + /* Send the glXQueryVersion request */ + LockDisplay(dpy); + GetReq(GLXQueryVersion, req); + req->reqType = opcode; + req->glxCode = X_GLXQueryVersion; + req->majorVersion = GLX_MAJOR_VERSION; + req->minorVersion = GLX_MINOR_VERSION; + _XReply(dpy, (xReply *) & reply, 0, False); + UnlockDisplay(dpy); + SyncHandle(); + + if (reply.majorVersion != GLX_MAJOR_VERSION) { + /* + ** The server does not support the same major release as this + ** client. + */ + return GL_FALSE; + } + *major = reply.majorVersion; + *minor = min(reply.minorVersion, GLX_MINOR_VERSION); + return GL_TRUE; +} + +_X_HIDDEN void +__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, + const INT32 * bp, Bool tagged_only, + Bool fbconfig_style_tags) +{ + int i; + + if (!tagged_only) { + /* Copy in the first set of properties */ + config->visualID = *bp++; + + config->visualType = _gl_convert_from_x_visual_type(*bp++); + + config->rgbMode = *bp++; + + config->redBits = *bp++; + config->greenBits = *bp++; + config->blueBits = *bp++; + config->alphaBits = *bp++; + config->accumRedBits = *bp++; + config->accumGreenBits = *bp++; + config->accumBlueBits = *bp++; + config->accumAlphaBits = *bp++; + + config->doubleBufferMode = *bp++; + config->stereoMode = *bp++; + + config->rgbBits = *bp++; + config->depthBits = *bp++; + config->stencilBits = *bp++; + config->numAuxBuffers = *bp++; + config->level = *bp++; + + count -= __GLX_MIN_CONFIG_PROPS; + } + + /* + ** Additional properties may be in a list at the end + ** of the reply. They are in pairs of property type + ** and property value. + */ + +#define FETCH_OR_SET(tag) \ + config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1 + + for (i = 0; i < count; i += 2) { + switch (*bp++) { + case GLX_RGBA: + FETCH_OR_SET(rgbMode); + break; + case GLX_BUFFER_SIZE: + config->rgbBits = *bp++; + break; + case GLX_LEVEL: + config->level = *bp++; + break; + case GLX_DOUBLEBUFFER: + FETCH_OR_SET(doubleBufferMode); + break; + case GLX_STEREO: + FETCH_OR_SET(stereoMode); + break; + case GLX_AUX_BUFFERS: + config->numAuxBuffers = *bp++; + break; + case GLX_RED_SIZE: + config->redBits = *bp++; + break; + case GLX_GREEN_SIZE: + config->greenBits = *bp++; + break; + case GLX_BLUE_SIZE: + config->blueBits = *bp++; + break; + case GLX_ALPHA_SIZE: + config->alphaBits = *bp++; + break; + case GLX_DEPTH_SIZE: + config->depthBits = *bp++; + break; + case GLX_STENCIL_SIZE: + config->stencilBits = *bp++; + break; + case GLX_ACCUM_RED_SIZE: + config->accumRedBits = *bp++; + break; + case GLX_ACCUM_GREEN_SIZE: + config->accumGreenBits = *bp++; + break; + case GLX_ACCUM_BLUE_SIZE: + config->accumBlueBits = *bp++; + break; + case GLX_ACCUM_ALPHA_SIZE: + config->accumAlphaBits = *bp++; + break; + case GLX_VISUAL_CAVEAT_EXT: + config->visualRating = *bp++; + break; + case GLX_X_VISUAL_TYPE: + config->visualType = *bp++; + break; + case GLX_TRANSPARENT_TYPE: + config->transparentPixel = *bp++; + break; + case GLX_TRANSPARENT_INDEX_VALUE: + config->transparentIndex = *bp++; + break; + case GLX_TRANSPARENT_RED_VALUE: + config->transparentRed = *bp++; + break; + case GLX_TRANSPARENT_GREEN_VALUE: + config->transparentGreen = *bp++; + break; + case GLX_TRANSPARENT_BLUE_VALUE: + config->transparentBlue = *bp++; + break; + case GLX_TRANSPARENT_ALPHA_VALUE: + config->transparentAlpha = *bp++; + break; + case GLX_VISUAL_ID: + config->visualID = *bp++; + break; + case GLX_DRAWABLE_TYPE: + config->drawableType = *bp++; + break; + case GLX_RENDER_TYPE: + config->renderType = *bp++; + break; + case GLX_X_RENDERABLE: + config->xRenderable = *bp++; + break; + case GLX_FBCONFIG_ID: + config->fbconfigID = *bp++; + break; + case GLX_MAX_PBUFFER_WIDTH: + config->maxPbufferWidth = *bp++; + break; + case GLX_MAX_PBUFFER_HEIGHT: + config->maxPbufferHeight = *bp++; + break; + case GLX_MAX_PBUFFER_PIXELS: + config->maxPbufferPixels = *bp++; + break; + case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: + config->optimalPbufferWidth = *bp++; + break; + case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: + config->optimalPbufferHeight = *bp++; + break; + case GLX_VISUAL_SELECT_GROUP_SGIX: + config->visualSelectGroup = *bp++; + break; + case GLX_SWAP_METHOD_OML: + config->swapMethod = *bp++; + break; + case GLX_SAMPLE_BUFFERS_SGIS: + config->sampleBuffers = *bp++; + break; + case GLX_SAMPLES_SGIS: + config->samples = *bp++; + break; + case GLX_BIND_TO_TEXTURE_RGB_EXT: + config->bindToTextureRgb = *bp++; + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + config->bindToTextureRgba = *bp++; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + config->bindToMipmapTexture = *bp++; + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + config->bindToTextureTargets = *bp++; + break; + case GLX_Y_INVERTED_EXT: + config->yInverted = *bp++; + break; + case None: + i = count; + break; + default: + break; + } + } + + config->renderType = + (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + + config->haveAccumBuffer = ((config->accumRedBits + + config->accumGreenBits + + config->accumBlueBits + + config->accumAlphaBits) > 0); + config->haveDepthBuffer = (config->depthBits > 0); + config->haveStencilBuffer = (config->stencilBits > 0); +} + +static __GLcontextModes * +createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, + int screen, GLboolean tagged_only) +{ + INT32 buf[__GLX_TOTAL_CONFIG], *props; + unsigned prop_size; + __GLcontextModes *modes, *m; + int i; + + if (nprops == 0) + return NULL; + + /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ + + /* Check number of properties */ + if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) + return NULL; + + /* Allocate memory for our config structure */ + modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); + if (!modes) + return NULL; + + prop_size = nprops * __GLX_SIZE_INT32; + if (prop_size <= sizeof(buf)) + props = buf; + else + props = Xmalloc(prop_size); + + /* Read each config structure and convert it into our format */ + m = modes; + for (i = 0; i < nvisuals; i++) { + _XRead(dpy, (char *) props, prop_size); + /* Older X servers don't send this so we default it here. */ + m->drawableType = GLX_WINDOW_BIT; + __glXInitializeVisualConfigFromTags(m, nprops, props, + tagged_only, GL_TRUE); + m->screen = screen; + m = m->next; + } + + if (props != buf) + Xfree(props); + + return modes; +} + +static GLboolean +getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) +{ + xGLXGetVisualConfigsReq *req; + __GLXscreenConfigs *psc; + xGLXGetVisualConfigsReply reply; + + LockDisplay(dpy); + + psc = priv->screenConfigs + screen; + psc->visuals = NULL; + GetReq(GLXGetVisualConfigs, req); + req->reqType = priv->majorOpcode; + req->glxCode = X_GLXGetVisualConfigs; + req->screen = screen; + + if (!_XReply(dpy, (xReply *) & reply, 0, False)) + goto out; + + psc->visuals = createConfigsFromProperties(dpy, + reply.numVisuals, + reply.numProps, + screen, GL_FALSE); + + out: + UnlockDisplay(dpy); + return psc->visuals != NULL; +} + +static GLboolean +getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen) +{ + xGLXGetFBConfigsReq *fb_req; + xGLXGetFBConfigsSGIXReq *sgi_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXGetFBConfigsReply reply; + __GLXscreenConfigs *psc; + + psc = priv->screenConfigs + screen; + psc->serverGLXexts = + __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS); + + LockDisplay(dpy); + + psc->configs = NULL; + if (atof(priv->serverGLXversion) >= 1.3) { + GetReq(GLXGetFBConfigs, fb_req); + fb_req->reqType = priv->majorOpcode; + fb_req->glxCode = X_GLXGetFBConfigs; + fb_req->screen = screen; + } + else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) { + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXGetFBConfigsSGIXReq + + sz_xGLXVendorPrivateWithReplyReq, vpreq); + sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; + sgi_req->reqType = priv->majorOpcode; + sgi_req->glxCode = X_GLXVendorPrivateWithReply; + sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; + sgi_req->screen = screen; + } + else + goto out; + + if (!_XReply(dpy, (xReply *) & reply, 0, False)) + goto out; + + psc->configs = createConfigsFromProperties(dpy, + reply.numFBConfigs, + reply.numAttribs * 2, + screen, GL_TRUE); + + out: + UnlockDisplay(dpy); + return psc->configs != NULL; +} + +static GLboolean +AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) +{ + __GLXscreenConfigs *psc; + GLint i, screens; + + /* + ** First allocate memory for the array of per screen configs. + */ + screens = ScreenCount(dpy); + psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs)); + if (!psc) { + return GL_FALSE; + } + memset(psc, 0, screens * sizeof(__GLXscreenConfigs)); + priv->screenConfigs = psc; + + priv->serverGLXversion = + __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION); + if (priv->serverGLXversion == NULL) { + FreeScreenConfigs(priv); + return GL_FALSE; + } + + for (i = 0; i < screens; i++, psc++) { + getFBConfigs(dpy, priv, i); + getVisualConfigs(dpy, priv, i); + psc->scr = i; + psc->dpy = dpy; + } + + SyncHandle(); + + return GL_TRUE; +} + +_X_HIDDEN void +__glXRelease(__GLXdisplayPrivate *dpyPriv) +{ + FreeScreenConfigs(dpyPriv); + + if (dpyPriv->serverGLXvendor) { + Xfree((char *) dpyPriv->serverGLXvendor); + dpyPriv->serverGLXvendor = NULL; + } + if (dpyPriv->serverGLXversion) { + Xfree((char *) dpyPriv->serverGLXversion); + dpyPriv->serverGLXversion = NULL; + } + + Xfree(dpyPriv); +} + +_X_HIDDEN __GLXdisplayPrivate * +__glXInitialize(Display * dpy) +{ + XExtDisplayInfo *info = __glXFindDisplay(dpy); + __GLXdisplayPrivate *dpyPriv; + int major, minor; + + if (!XextHasExtension(info)) + return NULL; + + /* See if the versions are compatible */ + if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) + return NULL; + + dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); + if (!dpyPriv) + return NULL; + + /* + ** Init the display private and then read in the screen config + ** structures from the server. + */ + dpyPriv->majorOpcode = info->codes->major_opcode; + dpyPriv->majorVersion = major; + dpyPriv->minorVersion = minor; + dpyPriv->dpy = dpy; + + dpyPriv->serverGLXvendor = NULL; + dpyPriv->serverGLXversion = NULL; + + if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { + Xfree(dpyPriv); + return NULL; + } + + return dpyPriv; +} diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h new file mode 100644 index 0000000000..57206e627b --- /dev/null +++ b/src/egl/drivers/xdri/glxinit.h @@ -0,0 +1,14 @@ +#ifndef GLXINIT_INCLUDED +#define GLXINIT_INCLUDED + +#include <X11/Xlib.h> +#include "glxclient.h" + +/* this is used by DRI loaders */ +extern void +_gl_context_modes_destroy(__GLcontextModes * modes); + +extern void +__glXRelease(__GLXdisplayPrivate *dpyPriv); + +#endif /* GLXINIT_INCLUDED */ |