summaryrefslogtreecommitdiffstats
path: root/src/glx/x11/dri_glx.c
diff options
context:
space:
mode:
authorKristian Høgsberg <[email protected]>2008-03-26 19:26:59 -0400
committerKristian Høgsberg <[email protected]>2008-03-31 16:51:26 -0400
commite82dd8c6e1fa2fff5b960de26961080ba5e9651d (patch)
tree1bd230661a032b1ab539998f947573de1acaf80d /src/glx/x11/dri_glx.c
parent63d8a8417d68365cd10c11178516378411c09f87 (diff)
DRI interface changes and DRI2 direct rendering support.
Add DRI2 direct rendering support to libGL and add DRI2 client side protocol code. Extend the GLX 1.3 create drawable functions in glx_pbuffer.c to call into the DRI driver when possible. Introduce __DRIconfig, opaque struct that represents a DRI driver configuration. Get's rid of the open coded __GLcontextModes in the DRI driver interface and the context modes create and destroy functions that the loader was requires to provide. glcore.h is no longer part of the DRI driver interface. The DRI config is GL binding agnostic, that is, not specific to GLX, EGL or other bindings. The core API is now also an extension, and the driver exports a list of extensions as the symbol __driDriverExtensions, which the loader must dlsym() for. The list of extension will always include the DRI core extension, which allows creating and manipulating DRI screens, drawables and contexts. The DRI legacy extension, when available, provides alternative entry points for creating the DRI objects that work with the XF86DRI infrastructure. Change DRI2 client code to not use drm drawables or contexts. We never used drm_drawable_t's and the only use for drm_context_t was as a unique identifier when taking the lock. We now just allocate a unique lock ID out of the DRILock sarea block. Once we get rid of the lock entirely, we can drop this hack. Change the interface between dri_util.c and the drivers, so that the drivers now export the DriverAPI struct as driDriverAPI instead of the InitScreen entry point. This lets us avoid dlsym()'ing for the DRI2 init screen function to see if DRI2 is supported by the driver.
Diffstat (limited to 'src/glx/x11/dri_glx.c')
-rw-r--r--src/glx/x11/dri_glx.c398
1 files changed, 304 insertions, 94 deletions
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index 514c082f6cd..31ade0da2a3 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -52,7 +52,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <sys/mman.h>
#include "xf86drm.h"
-
#ifndef RTLD_NOW
#define RTLD_NOW 0
#endif
@@ -62,6 +61,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
struct __GLXDRIdisplayPrivateRec {
__GLXDRIdisplay base;
@@ -76,8 +76,14 @@ struct __GLXDRIdisplayPrivateRec {
struct __GLXDRIcontextPrivateRec {
__GLXDRIcontext base;
- __DRIcontext driContext;
+ __DRIcontext *driContext;
XID hwContextID;
+ __GLXscreenConfigs *psc;
+};
+
+struct __GLXDRIconfigPrivateRec {
+ __GLcontextModes modes;
+ const __DRIconfig *driConfig;
};
#ifndef DEFAULT_DRIVER_DIR
@@ -98,10 +104,12 @@ static void InfoMessageF(const char *f, ...)
}
}
+extern void ErrorMessageF(const char *f, ...);
+
/**
* Print error to stderr, unless LIBGL_DEBUG=="quiet".
*/
-static void ErrorMessageF(const char *f, ...)
+_X_HIDDEN void ErrorMessageF(const char *f, ...)
{
va_list args;
const char *env;
@@ -114,16 +122,7 @@ static void ErrorMessageF(const char *f, ...)
}
}
-
-/**
- * Versioned name of the expected \c __driCreateNewScreen function.
- *
- * The version of the last incompatible loader/driver inteface change is
- * appended to the name of the \c __driCreateNewScreen function. This
- * prevents loaders from trying to load drivers that are too old.
- */
-static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING;
-
+extern void *driOpenDriver(const char *driverName);
/**
* Try to \c dlopen the named driver.
@@ -137,7 +136,7 @@ static const char createNewScreenName[] = __DRI_CREATE_NEW_SCREEN_STRING;
* \returns
* A handle from \c dlopen, or \c NULL if driver file not found.
*/
-static void *OpenDriver(const char *driverName)
+_X_HIDDEN void *driOpenDriver(const char *driverName)
{
void *glhandle, *handle;
const char *libPaths, *p, *next;
@@ -244,7 +243,7 @@ static void *driGetDriver(Display *dpy, int scrNum)
void *ret;
if (GetDriverName(dpy, scrNum, &driverName)) {
- ret = OpenDriver(driverName);
+ ret = driOpenDriver(driverName);
if (driverName)
Xfree(driverName);
return ret;
@@ -287,17 +286,22 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
*
* Note: The driver remains opened after this function returns.
*/
-PUBLIC const char *glXGetDriverConfig (const char *driverName) {
- void *handle = OpenDriver (driverName);
+PUBLIC const char *glXGetDriverConfig (const char *driverName)
+{
+ void *handle = driOpenDriver (driverName);
if (handle)
return dlsym (handle, "__driConfigOptions");
else
return NULL;
}
-static void
-filter_modes( __GLcontextModes ** server_modes,
- const __GLcontextModes * driver_modes )
+extern void
+driFilterModes(__GLcontextModes ** server_modes,
+ const __GLcontextModes * driver_modes);
+
+_X_HIDDEN void
+driFilterModes(__GLcontextModes ** server_modes,
+ const __GLcontextModes * driver_modes)
{
__GLcontextModes * m;
__GLcontextModes ** prev_next;
@@ -349,6 +353,7 @@ filter_modes( __GLcontextModes ** server_modes,
}
#ifdef XDAMAGE_1_1_INTERFACE
+
static GLboolean has_damage_post(Display *dpy)
{
static GLboolean inited = GL_FALSE;
@@ -369,20 +374,18 @@ static GLboolean has_damage_post(Display *dpy)
return has_damage;
}
-#endif /* XDAMAGE_1_1_INTERFACE */
static void __glXReportDamage(__DRIdrawable *driDraw,
int x, int y,
drm_clip_rect_t *rects, int num_rects,
- GLboolean front_buffer)
+ GLboolean front_buffer,
+ void *loaderPrivate)
{
-#ifdef XDAMAGE_1_1_INTERFACE
XRectangle *xrects;
XserverRegion region;
int i;
int x_off, y_off;
- __GLXDRIdrawable *glxDraw =
- containerOf(driDraw, __GLXDRIdrawable, driDrawable);
+ __GLXDRIdrawable *glxDraw = loaderPrivate;
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
Drawable drawable;
@@ -397,7 +400,7 @@ static void __glXReportDamage(__DRIdrawable *driDraw,
} else{
x_off = 0;
y_off = 0;
- drawable = glxDraw->drawable;
+ drawable = glxDraw->xDrawable;
}
xrects = malloc(sizeof(XRectangle) * num_rects);
@@ -414,19 +417,25 @@ static void __glXReportDamage(__DRIdrawable *driDraw,
free(xrects);
XDamageAdd(dpy, drawable, region);
XFixesDestroyRegion(dpy, region);
-#endif
}
+static const __DRIdamageExtension damageExtension = {
+ { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
+ __glXReportDamage,
+};
+
+#endif
+
static GLboolean
__glXDRIGetDrawableInfo(__DRIdrawable *drawable,
unsigned int *index, unsigned int *stamp,
int *X, int *Y, int *W, int *H,
int *numClipRects, drm_clip_rect_t ** pClipRects,
int *backX, int *backY,
- int *numBackClipRects, drm_clip_rect_t **pBackClipRects)
+ int *numBackClipRects, drm_clip_rect_t **pBackClipRects,
+ void *loaderPrivate)
{
- __GLXDRIdrawable *glxDraw =
- containerOf(drawable, __GLXDRIdrawable, driDrawable);
+ __GLXDRIdrawable *glxDraw = loaderPrivate;
__GLXscreenConfigs *psc = glxDraw->psc;
Display *dpy = psc->dpy;
@@ -437,17 +446,7 @@ __glXDRIGetDrawableInfo(__DRIdrawable *drawable,
numBackClipRects, pBackClipRects);
}
-
-/**
- * Table of functions exported by the loader to the driver.
- */
-static const __DRIcontextModesExtension contextModesExtension = {
- { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION },
- _gl_context_modes_create,
- _gl_context_modes_destroy,
-};
-
-static const __DRIsystemTimeExtension systemTimeExtension = {
+_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
__glXGetUST,
__driGetMscRateOML,
@@ -458,19 +457,189 @@ static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
__glXDRIGetDrawableInfo
};
-static const __DRIdamageExtension damageExtension = {
- { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
- __glXReportDamage,
-};
-
static const __DRIextension *loader_extensions[] = {
- &contextModesExtension.base,
&systemTimeExtension.base,
&getDrawableInfoExtension.base,
+
+#ifdef XDAMAGE_1_1_INTERFACE
&damageExtension.base,
+#endif
+
NULL
};
+#define __ATTRIB(attrib, field) \
+ { attrib, offsetof(__GLcontextModes, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
+ __ATTRIB(__DRI_ATTRIB_LEVEL, level),
+ __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
+ __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
+ __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
+ __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
+ __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
+ __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
+ __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
+ __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
+ __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
+ __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
+#if 0
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
+ __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
+ __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
+ __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
+#endif
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
+#if 0
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
+ __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
+#endif
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static int
+scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value)
+{
+ unsigned int driValue;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+ if (attribMap[i].attrib == attrib) {
+ driValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
+ return driValue == value;
+ }
+
+ return GL_TRUE; /* Is a non-existing attribute equal to value? */
+}
+
+static int
+driConfigEqual(const __DRIcoreExtension *core,
+ __GLcontextModes *modes, const __DRIconfig *driConfig)
+{
+ unsigned int attrib, value, glxValue;
+ int i;
+
+ i = 0;
+ while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
+ switch (attrib) {
+ case __DRI_ATTRIB_RENDER_TYPE:
+ glxValue = 0;
+ if (value & __DRI_ATTRIB_RGBA_BIT) {
+ glxValue |= GLX_RGBA_BIT;
+ } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
+ glxValue |= GLX_COLOR_INDEX_BIT;
+ }
+ if (glxValue != modes->renderType)
+ return GL_FALSE;
+ break;
+
+ case __DRI_ATTRIB_CONFIG_CAVEAT:
+ if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
+ glxValue = GLX_NON_CONFORMANT_CONFIG;
+ else if (value & __DRI_ATTRIB_SLOW_BIT)
+ glxValue = GLX_SLOW_CONFIG;
+ else
+ glxValue = GLX_NONE;
+ if (glxValue != modes->visualRating)
+ return GL_FALSE;
+ break;
+
+#if 0
+ /* The X server doesn't send these, so ignore them for now. */
+ case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
+ glxValue = 0;
+ if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
+ glxValue |= GLX_TEXTURE_1D_BIT_EXT;
+ if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
+ glxValue |= GLX_TEXTURE_2D_BIT_EXT;
+ if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
+ glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
+ if (glxValue != modes->bindToTextureTargets)
+ return GL_FALSE;
+ break;
+#endif
+
+ default:
+ if (!scalarEqual(modes, attrib, value))
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+static __GLcontextModes *
+createDriMode(const __DRIcoreExtension *core,
+ __GLcontextModes *modes, const __DRIconfig **driConfigs)
+{
+ __GLXDRIconfigPrivate *config;
+ int i;
+
+ for (i = 0; driConfigs[i]; i++) {
+ if (driConfigEqual(core, modes, driConfigs[i]))
+ break;
+ }
+
+ if (driConfigs[i] == NULL)
+ return NULL;
+
+ config = Xmalloc(sizeof *config);
+ if (config == NULL)
+ return NULL;
+
+ config->modes = *modes;
+ config->driConfig = driConfigs[i];
+
+ return &config->modes;
+}
+
+extern __GLcontextModes *
+driConvertConfigs(const __DRIcoreExtension *core,
+ __GLcontextModes *modes, const __DRIconfig **configs);
+
+_X_HIDDEN __GLcontextModes *
+driConvertConfigs(const __DRIcoreExtension *core,
+ __GLcontextModes *modes, const __DRIconfig **configs)
+{
+ __GLcontextModes head, *tail, *m;
+
+ tail = &head;
+ head.next = NULL;
+ for (m = modes; m; m = m->next) {
+ tail->next = createDriMode(core, m, configs);
+ if (tail->next == NULL) {
+ /* no matching dri config for m */
+ continue;
+ }
+
+
+ tail = tail->next;
+ }
+
+ _gl_context_modes_destroy(modes);
+
+ return head.next;
+}
/**
* Perform the required libGL-side initialization and call the client-side
@@ -491,8 +660,7 @@ static const __DRIextension *loader_extensions[] = {
*/
static void *
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
- __GLXDRIdisplayPrivate * driDpy,
- PFNCREATENEWSCREENFUNC createNewScreen)
+ __GLXDRIdisplayPrivate * driDpy)
{
void *psp = NULL;
#ifndef GLX_USE_APPLEGL
@@ -507,12 +675,12 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
int status;
const char * err_msg;
const char * err_extra;
+ const __DRIconfig **driver_configs;
dri_version.major = driDpy->driMajor;
dri_version.minor = driDpy->driMinor;
dri_version.patch = driDpy->driPatch;
-
err_msg = "XF86DRIOpenConnection";
err_extra = NULL;
@@ -608,12 +776,9 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
err_extra = strerror( -status );
if ( status == 0 ) {
- __GLcontextModes * driver_modes = NULL;
-
err_msg = "InitDriver";
err_extra = NULL;
- psp = (*createNewScreen)(scrn,
- &psc->__driScreen,
+ psp = (*psc->legacy->createNewScreen)(scrn,
& ddx_version,
& dri_version,
& drm_version,
@@ -621,11 +786,17 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
pSAREA,
fd,
loader_extensions,
- & driver_modes );
-
- filter_modes(&psc->configs, driver_modes);
- filter_modes(&psc->visuals, driver_modes);
- _gl_context_modes_destroy(driver_modes);
+ & driver_configs,
+ psc);
+
+ psc->configs =
+ driConvertConfigs(psc->core,
+ psc->configs,
+ driver_configs);
+ psc->visuals =
+ driConvertConfigs(psc->core,
+ psc->visuals,
+ driver_configs);
}
}
}
@@ -674,7 +845,7 @@ static void driDestroyContext(__GLXDRIcontext *context,
{
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- (*pcp->driContext.destroyContext)(&pcp->driContext);
+ (*psc->core->destroyContext)(pcp->driContext);
XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
}
@@ -683,17 +854,19 @@ static Bool driBindContext(__GLXDRIcontext *context,
__GLXDRIdrawable *draw, __GLXDRIdrawable *read)
{
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- return (*pcp->driContext.bindContext)(&pcp->driContext,
- &draw->driDrawable,
- &read->driDrawable);
+ return (*core->bindContext)(pcp->driContext,
+ draw->driDrawable,
+ read->driDrawable);
}
static void driUnbindContext(__GLXDRIcontext *context)
{
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- (*pcp->driContext.unbindContext)(&pcp->driContext);
+ (*core->unbindContext)(pcp->driContext);
}
static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
@@ -704,17 +877,19 @@ static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
__GLXDRIcontextPrivate *pcp, *pcp_shared;
drm_context_t hwContext;
__DRIcontext *shared = NULL;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
if (psc && psc->driScreen) {
if (shareList) {
pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
- shared = &pcp_shared->driContext;
+ shared = pcp_shared->driContext;
}
pcp = Xmalloc(sizeof *pcp);
if (pcp == NULL)
return NULL;
+ pcp->psc = psc;
if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
mode->visualID,
&pcp->hwContextID, &hwContext)) {
@@ -722,13 +897,14 @@ static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
return NULL;
}
- pcp->driContext.private =
- (*psc->__driScreen.createNewContext)(&psc->__driScreen,
- mode, renderType,
- shared,
- hwContext,
- &pcp->driContext);
- if (pcp->driContext.private == NULL) {
+ pcp->driContext =
+ (*psc->legacy->createNewContext)(psc->__driScreen,
+ config->driConfig,
+ renderType,
+ shared,
+ hwContext,
+ pcp);
+ if (pcp->driContext == NULL) {
XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
Xfree(pcp);
return NULL;
@@ -748,18 +924,24 @@ static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
{
__GLXscreenConfigs *psc = pdraw->psc;
- (*pdraw->driDrawable.destroyDrawable)(&pdraw->driDrawable);
+ (*psc->core->destroyDrawable)(pdraw->driDrawable);
XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
Xfree(pdraw);
}
static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
+ XID xDrawable,
GLXDrawable drawable,
- GLXContext gc)
+ const __GLcontextModes *modes)
{
__GLXDRIdrawable *pdraw;
drm_drawable_t hwDrawable;
void *empty_attribute_list = NULL;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+
+ /* Old dri can't handle GLX 1.3+ drawable constructors. */
+ if (xDrawable != drawable)
+ return NULL;
pdraw = Xmalloc(sizeof(*pdraw));
if (!pdraw)
@@ -772,16 +954,15 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
return NULL;
/* Create a new drawable */
- pdraw->driDrawable.private =
- (*psc->__driScreen.createNewDrawable)(&psc->__driScreen,
- gc->mode,
- &pdraw->driDrawable,
- hwDrawable,
- GLX_WINDOW_BIT,
- 0,
- empty_attribute_list);
-
- if (!pdraw->driDrawable.private) {
+ pdraw->driDrawable =
+ (*psc->legacy->createNewDrawable)(psc->__driScreen,
+ config->driConfig,
+ hwDrawable,
+ GLX_WINDOW_BIT,
+ empty_attribute_list,
+ pdraw);
+
+ if (!pdraw->driDrawable) {
XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
Xfree(pdraw);
return NULL;
@@ -795,19 +976,23 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
static void driDestroyScreen(__GLXscreenConfigs *psc)
{
/* Free the direct rendering per screen data */
- if (psc->__driScreen.private)
- (*psc->__driScreen.destroyScreen)(&psc->__driScreen);
- psc->__driScreen.private = NULL;
+ if (psc->__driScreen)
+ (*psc->core->destroyScreen)(psc->__driScreen);
+ psc->__driScreen = NULL;
if (psc->driver)
dlclose(psc->driver);
}
+void
+driBindExtensions(__GLXscreenConfigs *psc);
+
static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
__GLXdisplayPrivate *priv)
{
- PFNCREATENEWSCREENFUNC createNewScreen;
__GLXDRIdisplayPrivate *pdp;
__GLXDRIscreen *psp;
+ const __DRIextension **extensions;
+ int i;
psp = Xmalloc(sizeof *psp);
if (psp == NULL)
@@ -817,15 +1002,40 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
psc->ext_list_first_time = GL_TRUE;
psc->driver = driGetDriver(priv->dpy, screen);
- createNewScreen = dlsym(psc->driver, createNewScreenName);
- if (createNewScreen == NULL)
+ if (psc->driver == NULL) {
+ Xfree(psp);
+ return NULL;
+ }
+
+ extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
+ Xfree(psp);
return NULL;
+ }
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
+ psc->core = (__DRIcoreExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
+ psc->legacy = (__DRIlegacyExtension *) extensions[i];
+ }
+
+ if (psc->core == NULL || psc->legacy == NULL) {
+ Xfree(psp);
+ return NULL;
+ }
+
pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
- psc->__driScreen.private =
- CallCreateNewScreen(psc->dpy, screen, psc, pdp, createNewScreen);
- if (psc->__driScreen.private != NULL)
- __glXScrEnableDRIExtension(psc);
+ psc->__driScreen =
+ CallCreateNewScreen(psc->dpy, screen, psc, pdp);
+ if (psc->__driScreen == NULL) {
+ dlclose(psc->driver);
+ Xfree(psp);
+ return NULL;
+ }
+
+ driBindExtensions(psc);
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;