summaryrefslogtreecommitdiff
path: root/src/egl/drivers
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2008-09-11 16:05:15 +0100
committerKeith Whitwell <keith@tungstengraphics.com>2008-09-11 16:05:15 +0100
commit0397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1 (patch)
tree732c93d74ed806942a13bf15575a61aa4f001253 /src/egl/drivers
parent80af50b35b5a4e8890e15b28940576f8a1ac1476 (diff)
parente6887a5752774c18cf527477fdd3e57e4893ff3b (diff)
Merge branch 'gallium-0.1' into gallium-0.2
A first attempt at moving gallium onto a branch directly off master... It will be interesting to see how much work this takes to get running. Have resolved the conflicts semi-arbitarily, not compiled or tested. Conflicts: .gitignore Makefile configs/config.mgw configs/darwin configs/darwin-x86ppc configs/default configs/freebsd-dri configs/linux-dri configs/linux-dri-xcb configs/linux-fbdev configs/linux-static configs/linux-x86-64-static configs/linux-x86-static doxygen/Makefile include/GL/gl.h progs/demos/Makefile progs/demos/descrip.mms progs/demos/texenv.c progs/egl/.gitignore progs/egl/Makefile progs/glsl/.gitignore progs/glsl/Makefile progs/glsl/convolutions.c progs/samples/Makefile.mgw progs/tests/.gitignore progs/trivial/.gitignore progs/trivial/point-param.c progs/trivial/tri.c progs/xdemos/.gitignore progs/xdemos/glthreads.c src/egl/drivers/demo/Makefile src/egl/drivers/dri/Makefile src/egl/main/Makefile src/glu/Makefile src/glu/sgi/Makefile src/glu/sgi/Makefile.mgw src/glut/glx/Makefile.mgw src/glut/os2/WarpWin.cpp src/glut/os2/glut_cindex.cpp src/glut/os2/glut_gamemode.cpp src/glut/os2/glut_win.cpp src/glut/os2/glut_winmisc.cpp src/glut/os2/os2_glx.cpp src/glut/os2/os2_menu.cpp src/glut/os2/os2_winproc.cpp src/glw/Makefile src/glx/x11/dri_glx.c src/glx/x11/glxext.c src/mesa/Makefile src/mesa/Makefile.mgw src/mesa/descrip.mms src/mesa/drivers/beos/Makefile src/mesa/drivers/common/descrip.mms src/mesa/drivers/common/driverfuncs.c src/mesa/drivers/directfb/Makefile src/mesa/drivers/dri/Makefile.template src/mesa/drivers/dri/common/dri_bufmgr.c src/mesa/drivers/dri/common/dri_bufmgr.h src/mesa/drivers/dri/common/dri_util.c src/mesa/drivers/dri/common/extension_helper.h src/mesa/drivers/dri/common/mmio.h src/mesa/drivers/dri/common/utils.c src/mesa/drivers/dri/common/utils.h src/mesa/drivers/dri/glcore/Makefile src/mesa/drivers/dri/i810/i810screen.c src/mesa/drivers/dri/i915/intel_ioctl.c src/mesa/drivers/dri/i915/intel_ioctl.h src/mesa/drivers/dri/i915/intel_screen.c src/mesa/drivers/dri/i915/server/i830_common.h src/mesa/drivers/dri/i915/server/i830_dri.h src/mesa/drivers/dri/i965/intel_screen.c src/mesa/drivers/dri/i965/server/i830_common.h src/mesa/drivers/dri/i965/server/i830_dri.h src/mesa/drivers/dri/mach64/mach64_screen.c src/mesa/drivers/dri/nouveau/nouveau_context.h src/mesa/drivers/dri/nouveau/nouveau_fifo.c src/mesa/drivers/dri/nouveau/nouveau_fifo.h src/mesa/drivers/dri/nouveau/nouveau_screen.c src/mesa/drivers/dri/nouveau/nouveau_screen.h src/mesa/drivers/dri/r128/r128_tex.h src/mesa/drivers/dri/savage/savageioctl.h src/mesa/drivers/fbdev/Makefile src/mesa/drivers/osmesa/Makefile src/mesa/drivers/osmesa/descrip.mms src/mesa/drivers/x11/Makefile src/mesa/drivers/x11/descrip.mms src/mesa/drivers/x11/xm_dd.c src/mesa/glapi/glapi.c src/mesa/glapi/glthread.c src/mesa/main/api_validate.c src/mesa/main/attrib.c src/mesa/main/bufferobj.c src/mesa/main/bufferobj.h src/mesa/main/buffers.c src/mesa/main/config.h src/mesa/main/context.c src/mesa/main/descrip.mms src/mesa/main/drawpix.c src/mesa/main/enums.c src/mesa/main/fbobject.c src/mesa/main/glheader.h src/mesa/main/imports.c src/mesa/main/mipmap.c src/mesa/main/mm.c src/mesa/main/mm.h src/mesa/main/mtypes.h src/mesa/main/points.c src/mesa/main/sources src/mesa/main/state.c src/mesa/main/texcompress_fxt1.c src/mesa/main/texenvprogram.c src/mesa/main/texobj.c src/mesa/main/texstate.c src/mesa/main/texstore.c src/mesa/math/descrip.mms src/mesa/shader/arbprogram.c src/mesa/shader/descrip.mms src/mesa/shader/prog_execute.c src/mesa/shader/prog_statevars.c src/mesa/shader/prog_statevars.h src/mesa/shader/prog_uniform.c src/mesa/shader/program.c src/mesa/shader/program.h src/mesa/shader/shader_api.c src/mesa/shader/slang/descrip.mms src/mesa/shader/slang/library/slang_vertex_builtin_gc.h src/mesa/sources src/mesa/swrast/descrip.mms src/mesa/swrast/s_drawpix.c src/mesa/swrast/s_fragprog.c src/mesa/swrast/s_readpix.c src/mesa/swrast/s_span.c src/mesa/swrast_setup/descrip.mms src/mesa/tnl/descrip.mms src/mesa/tnl/t_context.h src/mesa/tnl/t_vp_build.c src/mesa/tnl/tnl.h src/mesa/vbo/descrip.mms src/mesa/vbo/vbo_context.c src/mesa/vbo/vbo_exec_array.c src/mesa/x86-64/xform4.S src/mesa/x86/rtasm/x86sse.c src/mesa/x86/rtasm/x86sse.h windows/VC6/progs/glut/glut.dsp windows/VC7/mesa/gdi/gdi.vcproj windows/VC7/mesa/glu/glu.vcproj windows/VC7/mesa/mesa.sln windows/VC7/mesa/mesa/mesa.vcproj windows/VC7/mesa/osmesa/osmesa.vcproj windows/VC7/progs/glut/glut.vcproj windows/VC8/mesa/gdi/gdi.vcproj windows/VC8/mesa/glu/glu.vcproj windows/VC8/mesa/mesa.sln windows/VC8/mesa/mesa/mesa.vcproj windows/VC8/progs/glut/glut.vcproj
Diffstat (limited to 'src/egl/drivers')
-rw-r--r--src/egl/drivers/Makefile25
-rw-r--r--src/egl/drivers/demo/demo.c34
-rw-r--r--src/egl/drivers/dri/Makefile7
-rw-r--r--src/egl/drivers/dri/egldri.c98
-rw-r--r--src/egl/drivers/dri/egldri.h9
-rw-r--r--src/egl/drivers/xdri/Makefile69
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c912
7 files changed, 1118 insertions, 36 deletions
diff --git a/src/egl/drivers/Makefile b/src/egl/drivers/Makefile
new file mode 100644
index 0000000000..f0538f563f
--- /dev/null
+++ b/src/egl/drivers/Makefile
@@ -0,0 +1,25 @@
+# src/egl/drivers/Makefile
+
+TOP = ../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(EGL_DRIVERS_DIRS)
+
+
+default: subdirs
+
+
+subdirs:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir ; $(MAKE)) || exit 1 ; \
+ fi \
+ done
+
+
+clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir ; $(MAKE) clean) ; \
+ fi \
+ done
diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c
index 45545755c0..1750e976b8 100644
--- a/src/egl/drivers/demo/demo.c
+++ b/src/egl/drivers/demo/demo.c
@@ -21,7 +21,7 @@
typedef struct demo_driver
{
_EGLDriver Base; /* base class/object */
- GLuint DemoStuff;
+ unsigned DemoStuff;
} DemoDriver;
#define DEMO_DRIVER(D) ((DemoDriver *) (D))
@@ -33,7 +33,7 @@ typedef struct demo_driver
typedef struct demo_surface
{
_EGLSurface Base; /* base class/object */
- GLuint DemoStuff;
+ unsigned DemoStuff;
} DemoSurface;
@@ -43,7 +43,7 @@ typedef struct demo_surface
typedef struct demo_context
{
_EGLContext Base; /* base class/object */
- GLuint DemoStuff;
+ unsigned DemoStuff;
} DemoContext;
@@ -67,22 +67,22 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
/* Create the display's visual configs - silly example */
for (i = 0; i < 4; i++) {
- _EGLConfig config;
- _eglInitConfig(&config, i + 1);
- _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8);
- _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8);
- _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8);
- _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8);
- _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32);
+ _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
+ _eglInitConfig(config, i + 1);
+ _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
if (i & 1) {
- _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 32);
+ _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 32);
}
if (i & 2) {
- _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
}
- _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE,
+ _eglSetConfigAttrib(config, EGL_SURFACE_TYPE,
(EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
- _eglAddConfig(disp, &config);
+ _eglAddConfig(disp, config);
}
drv->Initialized = EGL_TRUE;
@@ -152,9 +152,9 @@ demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
- assert(c->Base.Handle);
+ assert(_eglGetContextHandle(&c->Base));
- return c->Base.Handle;
+ return _eglGetContextHandle(&c->Base);
}
@@ -286,7 +286,7 @@ demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea
* plug in API functions.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy)
+_eglMain(_EGLDisplay *dpy, const char *args)
{
DemoDriver *demo;
diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile
index af0c40fe2b..3bd6b524ec 100644
--- a/src/egl/drivers/dri/Makefile
+++ b/src/egl/drivers/dri/Makefile
@@ -29,6 +29,8 @@ SOURCES = egldri.c
OBJECTS = $(SOURCES:.c=.o)
+DRM_LIB = `pkg-config --libs libdrm`
+
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
@@ -44,7 +46,7 @@ library: $(TOP)/$(LIB_DIR)/libEGLdri.so
$(TOP)/$(LIB_DIR)/libEGLdri.so: $(OBJECTS)
$(MKLIB) -o EGLdri -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major 1 -minor 0 \
- -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS)
+ -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS) $(LIBS)
clean:
@@ -53,9 +55,10 @@ clean:
depend: $(SOURCES) $(HEADERS)
@ echo "running $(MKDEP)"
+ @ rm -f depend
@ touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
- $(SOURCES) $(HEADERS) > /dev/null
+ $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null
include depend
# DO NOT DELETE
diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c
index cab0be2bd1..57661cc3ab 100644
--- a/src/egl/drivers/dri/egldri.c
+++ b/src/egl/drivers/dri/egldri.c
@@ -1,5 +1,6 @@
/**
- * Generic EGL driver for DRI.
+ * Generic EGL driver for DRI. This is basically an "adaptor" driver
+ * that allows libEGL to load/use regular DRI drivers.
*
* This file contains all the code needed to interface DRI-based drivers
* with libEGL.
@@ -23,6 +24,7 @@
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
+#include "eglconfigutil.h"
#include "eglsurface.h"
#include "eglscreen.h"
#include "eglglobals.h"
@@ -32,18 +34,72 @@
#include "egldri.h"
const char *sysfs = "/sys/class";
-#define None 0
+
static const int empty_attribute_list[1] = { None };
+
+/**
+ * Given a card number, return the name of the DRI driver to use.
+ * This generally means reading the contents of
+ * /sys/class/drm/cardX/dri_library_name, where X is the card number
+ */
+static EGLBoolean
+driver_name_from_card_number(int card, char *driverName, int maxDriverName)
+{
+ char path[2000];
+ FILE *f;
+ int length;
+
+ snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", sysfs, card);
+
+ f = fopen(path, "r");
+ if (!f)
+ return EGL_FALSE;
+
+ fgets(driverName, maxDriverName, f);
+ fclose(f);
+
+ if ((length = strlen(driverName)) > 1) {
+ /* remove the trailing newline from sysfs */
+ driverName[length - 1] = '\0';
+ strncat(driverName, "_dri", maxDriverName);
+ return EGL_TRUE;
+ }
+ else {
+ return EGL_FALSE;
+ }
+}
+
+
+
/**
* The bootstrap function.
* Return a new driDriver object and plug in API functions.
* This function, in turn, loads a specific DRI driver (ex: r200_dri.so).
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy)
+_eglMain(_EGLDisplay *dpy, const char *args)
{
+#if 1
+ const int card = args ? atoi(args) : 0;
+ _EGLDriver *driver = NULL;
+ char driverName[1000];
+
+ if (!driver_name_from_card_number(card, driverName, sizeof(driverName))) {
+ _eglLog(_EGL_WARNING,
+ "Unable to determine driver name for card %d\n", card);
+ return NULL;
+ }
+
+ _eglLog(_EGL_DEBUG, "Driver name: %s\n", driverName);
+
+ driver = _eglOpenDriver(dpy, driverName, args);
+
+ return driver;
+
+#else
+
int length;
char path[NAME_MAX];
struct dirent *dirent;
@@ -58,14 +114,19 @@ _eglMain(_EGLDisplay *dpy)
_eglLog(_EGL_WARNING, "%s DRM devices not found.", path);
return EGL_FALSE;
}
+
+ /* loop over dir entries looking for cardX where "X" is in the
+ * dpy->DriverName ":X" string.
+ */
while ((dirent = readdir(dir))) {
if (strncmp(&dirent->d_name[0], "card", 4) != 0)
continue;
- if (strcmp(&dirent->d_name[4], &dpy->Name[1]) != 0)
+ if (strcmp(&dirent->d_name[4], &driverName[1]) != 0)
continue;
- snprintf(path, sizeof(path), "%s/drm/card%s/dri_library_name", sysfs, &dpy->Name[1]);
+ snprintf(path, sizeof(path), "%s/drm/card%s/dri_library_name",
+ sysfs, &driverName[1]);
_eglLog(_EGL_INFO, "Opening %s", path);
#if 1
file = fopen(path, "r");
@@ -89,6 +150,7 @@ _eglMain(_EGLDisplay *dpy)
closedir(dir);
return driver;
+#endif
}
@@ -141,7 +203,7 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
- return c->Base.Handle;
+ return _eglGetContextHandle(&c->Base);
}
@@ -152,13 +214,15 @@ _eglDRIMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw,
driDisplay *disp = Lookup_driDisplay(dpy);
driContext *ctx = Lookup_driContext(context);
EGLBoolean b;
+ __DRIid drawBuf = (__DRIid) draw;
+ __DRIid readBuf = (__DRIid) read;
b = _eglMakeCurrent(drv, dpy, draw, read, context);
if (!b)
return EGL_FALSE;
if (ctx) {
- ctx->driContext.bindContext(disp, 0, read, draw, &ctx->driContext);
+ ctx->driContext.bindContext(disp, 0, drawBuf, readBuf, &ctx->driContext);
}
else {
/* what's this??? */
@@ -190,7 +254,7 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
#if 0
GLcontext *ctx = NULL; /* this _should_ be OK */
#endif
- GLvisual visMode;
+ __GLcontextModes visMode;
_EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
assert(conf); /* bad config should be caught earlier */
_eglConfigToContextModesRec(conf, &visMode);
@@ -267,7 +331,8 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
_EGLConfig *config = _eglLookupConfig(drv, dpy, cfg);
driDisplay *disp = Lookup_driDisplay(dpy);
driSurface *surface;
- GLvisual visMode;
+ __GLcontextModes visMode;
+ __DRIid drawBuf;
surface = (driSurface *) calloc(1, sizeof(*surface));
if (!surface) {
@@ -292,8 +357,10 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
/* convert EGLConfig to GLvisual */
_eglConfigToContextModesRec(config, &visMode);
+ drawBuf = (__DRIid) _eglGetSurfaceHandle(&surface->Base);
+
/* Create a new DRI drawable */
- if (!disp->driScreen.createNewDrawable(disp, &visMode, surface->Base.Handle,
+ if (!disp->driScreen.createNewDrawable(disp, &visMode, drawBuf,
&surface->drawable, GLX_WINDOW_BIT,
empty_attribute_list)) {
_eglRemoveSurface(&surface->Base);
@@ -715,7 +782,7 @@ __eglGetDrawableInfo(__DRInativeDisplay * ndpy, int screen, __DRIid drawable,
{
__DRIscreen *pDRIScreen;
__DRIscreenPrivate *psp;
- driSurface *surf = Lookup_driSurface(drawable);
+ driSurface *surf = Lookup_driSurface((EGLSurface) drawable);
pDRIScreen = __eglFindDRIScreen(ndpy, screen);
@@ -1019,8 +1086,10 @@ _eglDRICreateDisplay(driDisplay *dpy, __DRIframebuffer *framebuffer)
api_ver,
& interface_methods,
NULL);
- if (!dpy->driScreen.private)
+ if (!dpy->driScreen.private) {
+ _eglLog(_EGL_WARNING, "egldri.c: DRI create new screen failed");
return EGL_FALSE;
+ }
DRM_UNLOCK( dpy->drmFD, dpy->pSAREA, dpy->serverContext );
@@ -1080,6 +1149,7 @@ _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy,
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
driDisplay *display;
+ const char *driverName = (const char *) disp->NativeDisplay;
assert(disp);
@@ -1088,13 +1158,13 @@ _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy,
*/
display = calloc(1, sizeof(*display));
display->Base = *disp;
- _eglHashInsert(_eglGlobal.Displays, disp->Handle, display);
+ _eglSaveDisplay(&display->Base);
free(disp);
*major = 1;
*minor = 0;
- sscanf(&disp->Name[1], "%d", &display->minor);
+ sscanf(driverName + 1, "%d", &display->minor);
drv->Initialized = EGL_TRUE;
return EGL_TRUE;
diff --git a/src/egl/drivers/dri/egldri.h b/src/egl/drivers/dri/egldri.h
index 34b12d64fc..54a9a4ea26 100644
--- a/src/egl/drivers/dri/egldri.h
+++ b/src/egl/drivers/dri/egldri.h
@@ -1,11 +1,14 @@
#ifndef EGLDRI_INCLUDED
#define EGLDRI_INCLUDED
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
#include "egldisplay.h"
#include "eglscreen.h"
#include "eglsurface.h"
#include "eglcontext.h"
-#include "mtypes.h"
+
#include "dri_util.h"
#include "drm_sarea.h"
@@ -14,7 +17,7 @@
*/
typedef struct dri_display
{
- _EGLDisplay Base; /* base class/object */
+ _EGLDisplay Base; /**< base class */
void *pFB;
int drmFD; /**< \brief DRM device file descriptor */
int minor;
@@ -32,7 +35,7 @@ typedef struct dri_display
unsigned long FBStart; /**< \brief physical address of the framebuffer */
void *driverClientMsg;
int driverClientMsgSize;
- int chipset;
+ unsigned chipset;
void *driverPrivate;
drm_magic_t magic;
diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile
new file mode 100644
index 0000000000..252d00b6c2
--- /dev/null
+++ b/src/egl/drivers/xdri/Makefile
@@ -0,0 +1,69 @@
+# 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 \
+ -I/usr/include/drm \
+ -I$(TOP)/include \
+ -I$(TOP)/include/GL/internal \
+ -I$(TOP)/src/mesa/glapi \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/egl/main \
+ -I$(TOP)/src/glx/x11
+
+SOURCES = egl_xdri.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+DRM_LIB = `pkg-config --libs libdrm`
+
+MISC_LIBS = -ldl -lXext -lGL
+
+
+.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 \
+ -install $(TOP)/$(LIB_DIR) \
+ $(OBJECTS) $(DRM_LIB) $(MISC_LIBS)
+
+
+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/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
new file mode 100644
index 0000000000..3681d9879a
--- /dev/null
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -0,0 +1,912 @@
+/**************************************************************************
+ *
+ * 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 <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "dlfcn.h"
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include "xf86dri.h"
+#include "glxclient.h"
+#include "dri_util.h"
+#include "drm_sarea.h"
+
+#define _EGL_PLATFORM_X
+
+#include "eglconfig.h"
+#include "eglcontext.h"
+#include "egldisplay.h"
+#include "egldriver.h"
+#include "eglglobals.h"
+#include "eglhash.h"
+#include "egllog.h"
+#include "eglsurface.h"
+
+
+
+#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
+
+
+/** subclass of _EGLDriver */
+struct xdri_egl_driver
+{
+ _EGLDriver Base; /**< base class */
+
+ const char *dri_driver_name; /**< name of DRI driver to load */
+ void *dri_driver_handle; /**< returned by dlopen(dri_driver_name) */
+
+ __GLXdisplayPrivate *glx_priv;
+
+
+ /* XXX we're not actually using these at this time: */
+ int chipset;
+ int minor;
+ int drmFD;
+
+ __DRIframebuffer framebuffer;
+ drm_handle_t hSAREA;
+ drmAddress pSAREA;
+ char *busID;
+ drm_magic_t magic;
+};
+
+
+/** subclass of _EGLContext */
+struct xdri_egl_context
+{
+ _EGLContext Base; /**< base class */
+
+ __DRIcontext driContext;
+};
+
+
+/** subclass of _EGLSurface */
+struct xdri_egl_surface
+{
+ _EGLSurface Base; /**< base class */
+
+ __DRIid driDrawable; /**< DRI surface */
+ drm_drawable_t hDrawable;
+};
+
+
+/** subclass of _EGLConfig */
+struct xdri_egl_config
+{
+ _EGLConfig Base; /**< base class */
+
+ const __GLcontextModes *mode; /**< corresponding GLX mode */
+};
+
+
+
+/** cast wrapper */
+static struct xdri_egl_driver *
+xdri_egl_driver(_EGLDriver *drv)
+{
+ return (struct xdri_egl_driver *) drv;
+}
+
+
+/** Map EGLSurface handle to xdri_egl_surface object */
+static struct xdri_egl_surface *
+lookup_surface(EGLSurface surf)
+{
+ _EGLSurface *surface = _eglLookupSurface(surf);
+ return (struct xdri_egl_surface *) surface;
+}
+
+
+/** Map EGLContext handle to xdri_egl_context object */
+static struct xdri_egl_context *
+lookup_context(EGLContext c)
+{
+ _EGLContext *context = _eglLookupContext(c);
+ return (struct xdri_egl_context *) context;
+}
+
+
+/** Map EGLConfig handle to xdri_egl_config object */
+static struct xdri_egl_config *
+lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+{
+ _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
+ return (struct xdri_egl_config *) conf;
+}
+
+
+
+/** 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;
+}
+
+
+/**
+ * Produce a set of EGL configs.
+ * Note that we get the list of GLcontextModes from the GLX library.
+ * This dependency on GLX lib will be removed someday.
+ */
+static void
+create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
+{
+ static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
+ EGL_OPENGL_ES2_BIT |
+ EGL_OPENVG_BIT |
+ EGL_OPENGL_BIT);
+ __GLXscreenConfigs *scrn = glx_priv->screenConfigs;
+ const __GLcontextModes *m;
+ int id = 1;
+
+ for (m = scrn->configs; m; m = m->next) {
+ /* EGL requires double-buffered configs */
+ 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);
+ /* XXX only window rendering allowed ATM */
+ 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);
+ }
+ }
+}
+
+
+/**
+ * Called via __DRIinterfaceMethods object
+ */
+static __DRIfuncPtr
+dri_get_proc_address(const char * proc_name)
+{
+ return NULL;
+}
+
+
+static void
+dri_context_modes_destroy(__GLcontextModes *modes)
+{
+ _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
+
+ while (modes) {
+ __GLcontextModes * const next = modes->next;
+ free(modes);
+ modes = next;
+ }
+}
+
+
+/**
+ * Create a linked list of 'count' GLcontextModes.
+ * These are used during the client/server visual negotiation phase,
+ * then discarded.
+ */
+static __GLcontextModes *
+dri_context_modes_create(unsigned count, size_t minimum_size)
+{
+ /* This code copied from libGLX, and modified */
+ const size_t size = (minimum_size > sizeof(__GLcontextModes))
+ ? minimum_size : sizeof(__GLcontextModes);
+ __GLcontextModes * head = NULL;
+ __GLcontextModes ** next;
+ unsigned i;
+
+ next = & head;
+ for (i = 0 ; i < count ; i++) {
+ *next = (__GLcontextModes *) calloc(1, size);
+ if (*next == NULL) {
+ dri_context_modes_destroy(head);
+ head = NULL;
+ break;
+ }
+
+ (*next)->doubleBufferMode = 1;
+ (*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 = 0;
+ (*next)->yInverted = GLX_DONT_CARE;
+
+ next = & ((*next)->next);
+ }
+
+ return head;
+}
+
+
+static __DRIscreen *
+dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn)
+{
+ __GLXdisplayPrivate *priv = __glXInitialize(ndpy);
+ __GLXscreenConfigs *scrnConf = priv->screenConfigs;
+ return &scrnConf->driScreen;
+}
+
+
+static GLboolean
+dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw)
+{
+ return EGL_TRUE;
+}
+
+
+static GLboolean
+dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID,
+ void * contextID, drm_context_t * hw_context)
+{
+ assert(configID >= 0);
+ return XF86DRICreateContextWithConfig(ndpy, screenNum,
+ configID, contextID, hw_context);
+}
+
+
+static GLboolean
+dri_destroy_context(__DRInativeDisplay * ndpy, int screen, __DRIid context)
+{
+ return XF86DRIDestroyContext(ndpy, screen, context);
+}
+
+
+static GLboolean
+dri_create_drawable(__DRInativeDisplay * ndpy, int screen,
+ __DRIid drawable, drm_drawable_t * hHWDrawable)
+{
+ _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
+
+ /* Create DRI drawable for given window ID (drawable) */
+ if (!XF86DRICreateDrawable(ndpy, screen, drawable, hHWDrawable))
+ return EGL_FALSE;
+
+ return EGL_TRUE;
+}
+
+
+static GLboolean
+dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable)
+{
+ _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
+ return XF86DRIDestroyDrawable(ndpy, screen, drawable);
+}
+
+
+static GLboolean
+dri_get_drawable_info(__DRInativeDisplay *ndpy, int scrn,
+ __DRIid draw, unsigned int * index, unsigned int * stamp,
+ int * x, int * y, int * width, int * height,
+ int * numClipRects, drm_clip_rect_t ** pClipRects,
+ int * backX, int * backY,
+ int * numBackClipRects,
+ drm_clip_rect_t ** pBackClipRects)
+{
+ _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
+
+ if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp,
+ x, y, width, height,
+ numClipRects, pClipRects,
+ backX, backY,
+ numBackClipRects, pBackClipRects)) {
+ return EGL_FALSE;
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Table of functions exported by the loader to the driver.
+ */
+static const __DRIinterfaceMethods interface_methods = {
+ dri_get_proc_address,
+
+ dri_context_modes_create,
+ dri_context_modes_destroy,
+
+ dri_find_dri_screen,
+ dri_window_exists,
+
+ dri_create_context,
+ dri_destroy_context,
+
+ dri_create_drawable,
+ dri_destroy_drawable,
+ dri_get_drawable_info,
+
+ NULL,/*__eglGetUST,*/
+ NULL,/*__eglGetMSCRate,*/
+};
+
+
+
+static EGLBoolean
+init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp)
+{
+ __DRIversion ddx_version;
+ __DRIversion dri_version;
+ __DRIversion drm_version;
+ drmVersionPtr version;
+ drm_handle_t hFB;
+ int newlyopened;
+ int status;
+ int scrn = DefaultScreen(disp->Xdpy);
+
+#if 0
+ createNewScreen = (PFNCREATENEWSCREENFUNC)
+ dlsym(xdri_drv->dri_driver_handle, createNewScreenName);
+ if (!createNewScreen) {
+ _eglLog(_EGL_WARNING, "XDRI: Couldn't find %s function in the driver.",
+ createNewScreenName);
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: Found %s", createNewScreenName);
+ }
+#endif
+
+ /*
+ * Get the DRI X extension version.
+ */
+ dri_version.major = 4;
+ dri_version.minor = 0;
+ dri_version.patch = 0;
+
+ if (!XF86DRIOpenConnection(disp->Xdpy, scrn,
+ &xdri_drv->hSAREA, &xdri_drv->busID)) {
+ _eglLog(_EGL_WARNING, "XF86DRIOpenConnection failed");
+ }
+
+ xdri_drv->drmFD = drmOpenOnce(NULL, xdri_drv->busID, &newlyopened);
+ if (xdri_drv->drmFD < 0) {
+ perror("drmOpenOnce failed: ");
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: drmOpenOnce returned %d", xdri_drv->drmFD);
+ }
+
+
+ if (drmGetMagic(xdri_drv->drmFD, &xdri_drv->magic)) {
+ perror("drmGetMagic failed: ");
+ return EGL_FALSE;
+ }
+
+ version = drmGetVersion(xdri_drv->drmFD);
+ if (version) {
+ drm_version.major = version->version_major;
+ drm_version.minor = version->version_minor;
+ drm_version.patch = version->version_patchlevel;
+ drmFreeVersion(version);
+ _eglLog(_EGL_DEBUG, "XDRI: Got DRM version %d.%d.%d",
+ drm_version.major,
+ drm_version.minor,
+ drm_version.patch);
+ }
+ else {
+ drm_version.major = -1;
+ drm_version.minor = -1;
+ drm_version.patch = -1;
+ _eglLog(_EGL_WARNING, "XDRI: drmGetVersion() failed");
+ return EGL_FALSE;
+ }
+
+ /* Authenticate w/ server.
+ */
+ if (!XF86DRIAuthConnection(disp->Xdpy, scrn, xdri_drv->magic)) {
+ _eglLog(_EGL_WARNING, "XDRI: XF86DRIAuthConnection() failed");
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: XF86DRIAuthConnection() success");
+ }
+
+ /* Get ddx version.
+ */
+ {
+ char *driverName;
+
+ /*
+ * Get device name (like "tdfx") and the ddx version
+ * numbers. We'll check the version in each DRI driver's
+ * "createNewScreen" function.
+ */
+ if (!XF86DRIGetClientDriverName(disp->Xdpy, scrn,
+ &ddx_version.major,
+ &ddx_version.minor,
+ &ddx_version.patch,
+ &driverName)) {
+ _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetClientDriverName failed");
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetClientDriverName returned %s", driverName);
+ }
+ }
+
+ /* Get framebuffer info.
+ */
+ {
+ int junk;
+ if (!XF86DRIGetDeviceInfo(disp->Xdpy, scrn,
+ &hFB,
+ &junk,
+ &xdri_drv->framebuffer.size,
+ &xdri_drv->framebuffer.stride,
+ &xdri_drv->framebuffer.dev_priv_size,
+ &xdri_drv->framebuffer.dev_priv)) {
+ _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetDeviceInfo() failed");
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetDeviceInfo() success");
+ }
+ xdri_drv->framebuffer.width = DisplayWidth(disp->Xdpy, scrn);
+ xdri_drv->framebuffer.height = DisplayHeight(disp->Xdpy, scrn);
+ }
+
+ /* Map the framebuffer region. (this may not be needed)
+ */
+ status = drmMap(xdri_drv->drmFD, hFB, xdri_drv->framebuffer.size,
+ (drmAddressPtr) &xdri_drv->framebuffer.base);
+ if (status != 0) {
+ _eglLog(_EGL_WARNING, "XDRI: drmMap(framebuffer) failed");
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: drmMap(framebuffer) success");
+ }
+
+ /* Map the SAREA region.
+ */
+ status = drmMap(xdri_drv->drmFD, xdri_drv->hSAREA, SAREA_MAX, &xdri_drv->pSAREA);
+ if (status != 0) {
+ _eglLog(_EGL_WARNING, "XDRI: drmMap(sarea) failed");
+ return EGL_FALSE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: drmMap(sarea) success");
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Load the DRI driver named by "xdri_drv->dri_driver_name".
+ * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle".
+ *
+ * Later, we'll call dlsym(createNewScreenName) to get a pointer to
+ * the driver's createNewScreen() function which is the bootstrap function.
+ *
+ * \return EGL_TRUE for success, EGL_FALSE for failure
+ */
+static EGLBoolean
+load_dri_driver(struct xdri_egl_driver *xdri_drv)
+{
+ char filename[100];
+ int flags = RTLD_NOW;
+
+ /* try "egl_xxx_dri.so" first */
+ snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name);
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
+ xdri_drv->dri_driver_handle = dlopen(filename, flags);
+ if (xdri_drv->dri_driver_handle) {
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
+ return EGL_TRUE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror());
+ }
+
+ /* try regular "xxx_dri.so" next */
+ snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name);
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
+ xdri_drv->dri_driver_handle = dlopen(filename, flags);
+ if (xdri_drv->dri_driver_handle) {
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
+ return EGL_TRUE;
+ }
+
+ _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror());
+ return EGL_FALSE;
+}
+
+
+/**
+ * Called via eglInitialize(), xdri_drv->API.Initialize().
+ */
+static EGLBoolean
+xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
+ EGLint *minor, EGLint *major)
+{
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ static char name[100];
+
+ _eglLog(_EGL_DEBUG, "XDRI: eglInitialize");
+
+ if (!disp->Xdpy) {
+ disp->Xdpy = XOpenDisplay(NULL);
+ if (!disp->Xdpy) {
+ _eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed");
+ return EGL_FALSE;
+ }
+ }
+
+#if 0
+ /* choose the DRI driver to load */
+ xdri_drv->dri_driver_name = _eglChooseDRMDriver(0);
+ if (!load_dri_driver(xdri_drv))
+ return EGL_FALSE;
+#else
+ (void) load_dri_driver;
+#endif
+
+#if 0
+ if (!init_drm(xdri_drv, disp))
+ return EGL_FALSE;
+#else
+ (void) init_drm;
+#endif
+
+ /*
+ * NOTE: this call to __glXInitialize() bootstraps the whole GLX/DRI
+ * interface, loads the DRI driver, etc.
+ * This replaces the load_dri_driver() and init_drm() code above.
+ */
+ xdri_drv->glx_priv = __glXInitialize(disp->Xdpy);
+
+ create_configs(disp, xdri_drv->glx_priv);
+
+ xdri_drv->Base.Initialized = EGL_TRUE;
+
+ snprintf(name, sizeof(name), "X/DRI:%s", xdri_drv->dri_driver_name);
+ xdri_drv->Base.Name = name;
+
+ /* 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_driver *xdri_drv = xdri_egl_driver(drv);
+
+ _eglLog(_EGL_DEBUG, "XDRI: eglTerminate");
+
+ _eglLog(_EGL_DEBUG, "XDRI: Closing %s", xdri_drv->dri_driver_name);
+#if 0
+ dlclose(xdri_drv->dri_driver_handle);
+#endif
+ xdri_drv->dri_driver_handle = NULL;
+
+ free((void*) xdri_drv->dri_driver_name);
+
+ return EGL_TRUE;
+}
+
+
+/*
+ * Called from eglGetProcAddress() via drv->API.GetProcAddress().
+ */
+static _EGLProc
+xdri_eglGetProcAddress(const char *procname)
+{
+#if 0
+ _EGLDriver *drv = NULL;
+
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/
+ _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname);
+ return proc;
+#elif 1
+ /* This is a bit of a hack to get at the gallium/Mesa state tracker
+ * function st_get_proc_address(). This will probably change at
+ * some point.
+ */
+ _EGLProc (*st_get_proc_addr)(const char *procname);
+ st_get_proc_addr = dlsym(NULL, "st_get_proc_address");
+ if (st_get_proc_addr) {
+ return st_get_proc_addr(procname);
+ }
+ return NULL;
+#else
+ return NULL;
+#endif
+}
+
+
+/**
+ * Called via eglCreateContext(), drv->API.CreateContext().
+ */
+static EGLContext
+xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ EGLContext share_list, const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
+ void *shared = NULL;
+ int renderType = GLX_RGBA_BIT;
+
+ struct xdri_egl_context *xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
+ if (!xdri_ctx)
+ return EGL_NO_CONTEXT;
+
+ if (!_eglInitContext(drv, dpy, &xdri_ctx->Base, config, attrib_list)) {
+ free(xdri_ctx);
+ return EGL_NO_CONTEXT;
+ }
+
+ assert(xdri_config);
+
+ {
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
+ xdri_ctx->driContext.private =
+ scrnConf->driScreen.createNewContext(disp->Xdpy,
+ xdri_config->mode, renderType,
+ shared, &xdri_ctx->driContext);
+ }
+
+ if (!xdri_ctx->driContext.private) {
+ _eglLog(_EGL_DEBUG, "driScreen.createNewContext failed");
+ free(xdri_ctx);
+ return EGL_NO_CONTEXT;
+ }
+
+ xdri_ctx->driContext.mode = xdri_config->mode;
+
+ return _eglGetContextHandle(&xdri_ctx->Base);
+}
+
+
+/**
+ * Called via eglMakeCurrent(), drv->API.MakeCurrent().
+ */
+static EGLBoolean
+xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
+ EGLSurface r, EGLContext context)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct xdri_egl_context *xdri_ctx = lookup_context(context);
+ struct xdri_egl_surface *xdri_draw = lookup_surface(d);
+ struct xdri_egl_surface *xdri_read = lookup_surface(r);
+ __DRIid draw = xdri_draw ? xdri_draw->driDrawable : 0;
+ __DRIid read = xdri_read ? xdri_read->driDrawable : 0;
+ int scrn = DefaultScreen(disp->Xdpy);
+
+ if (!_eglMakeCurrent(drv, dpy, d, r, context))
+ return EGL_FALSE;
+
+
+ if (xdri_ctx &&
+ !xdri_ctx->driContext.bindContext(disp->Xdpy, scrn, draw, read,
+ &xdri_ctx->driContext)) {
+ return EGL_FALSE;
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
+ */
+static EGLSurface
+xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ NativeWindowType window, const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct xdri_egl_surface *xdri_surf;
+ int scrn = DefaultScreen(disp->Xdpy);
+ uint width, height;
+
+ xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
+ if (!xdri_surf)
+ return EGL_NO_SURFACE;
+
+ if (!_eglInitSurface(drv, dpy, &xdri_surf->Base, EGL_WINDOW_BIT,
+ config, attrib_list)) {
+ free(xdri_surf);
+ return EGL_FALSE;
+ }
+
+ if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) {
+ free(xdri_surf);
+ return EGL_FALSE;
+ }
+
+ xdri_surf->driDrawable = window;
+
+ _eglSaveSurface(&xdri_surf->Base);
+
+ get_drawable_size(disp->Xdpy, window, &width, &height);
+ xdri_surf->Base.Width = width;
+ xdri_surf->Base.Height = height;
+
+ _eglLog(_EGL_DEBUG,
+ "XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d",
+ (int) window, _eglGetSurfaceHandle(&xdri_surf->Base),
+ (int) xdri_surf->hDrawable);
+
+ return _eglGetSurfaceHandle(&xdri_surf->Base);
+}
+
+
+static EGLBoolean
+xdri_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+{
+ struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
+ if (xdri_surf) {
+ _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
+ if (xdri_surf->Base.IsBound) {
+ xdri_surf->Base.DeletePending = EGL_TRUE;
+ }
+ else {
+ /*
+ st_unreference_framebuffer(&surf->Framebuffer);
+ */
+ free(xdri_surf);
+ }
+ return EGL_TRUE;
+ }
+ else {
+ _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
+ return EGL_FALSE;
+ }
+}
+
+
+static EGLBoolean
+xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+
+ _eglLog(_EGL_DEBUG, "XDRI: EGL SwapBuffers");
+
+ /* error checking step: */
+ if (!_eglSwapBuffers(drv, dpy, draw))
+ return EGL_FALSE;
+
+ {
+ struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
+ __DRIscreen *psc = &scrnConf->driScreen;
+ __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy,
+ xdri_surf->driDrawable,
+ psc->private);
+
+ if (pdraw)
+ pdraw->swapBuffers(disp->Xdpy, pdraw->private);
+ else
+ _eglLog(_EGL_WARNING, "pdraw is null in SwapBuffers");
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * This is the main entrypoint into the driver, called by libEGL.
+ * Create a new _EGLDriver object and init its dispatch table.
+ */
+_EGLDriver *
+_eglMain(_EGLDisplay *disp, const char *args)
+{
+ struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver);
+ if (!xdri_drv)
+ return NULL;
+
+ /* Tell libGL to prefer the EGL drivers over regular DRI drivers */
+ __glXPreferEGL(1);
+
+ _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.MakeCurrent = xdri_eglMakeCurrent;
+ xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface;
+ xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface;
+ xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
+
+ xdri_drv->Base.ClientAPIsMask = (EGL_OPENGL_BIT |
+ EGL_OPENGL_ES_BIT |
+ EGL_OPENGL_ES2_BIT |
+ EGL_OPENVG_BIT);
+ xdri_drv->Base.Name = "X/DRI";
+
+ _eglLog(_EGL_DEBUG, "XDRI: main(%s)", args);
+
+ return &xdri_drv->Base;
+}