libGL: Consolidate DRI initialization in dri_glx.c
Move a lot of code over from glx_ext.c.
This commit is contained in:
parent
db7fc63110
commit
890d44e54f
|
@ -48,6 +48,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include "dri_glx.h"
|
#include "dri_glx.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include "glcontextmodes.h"
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include "xf86drm.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef RTLD_NOW
|
#ifndef RTLD_NOW
|
||||||
#define RTLD_NOW 0
|
#define RTLD_NOW 0
|
||||||
|
@ -383,6 +387,409 @@ PUBLIC const char *glXGetDriverConfig (const char *driverName) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_modes( __GLcontextModes ** server_modes,
|
||||||
|
const __GLcontextModes * driver_modes )
|
||||||
|
{
|
||||||
|
__GLcontextModes * m;
|
||||||
|
__GLcontextModes ** prev_next;
|
||||||
|
const __GLcontextModes * check;
|
||||||
|
|
||||||
|
if (driver_modes == NULL) {
|
||||||
|
fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For each mode in server_modes, check to see if a matching mode exists
|
||||||
|
* in driver_modes. If not, then the mode is not available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
prev_next = server_modes;
|
||||||
|
for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
|
||||||
|
GLboolean do_delete = GL_TRUE;
|
||||||
|
|
||||||
|
for ( check = driver_modes ; check != NULL ; check = check->next ) {
|
||||||
|
if ( _gl_context_modes_are_same( m, check ) ) {
|
||||||
|
do_delete = GL_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The 3D has to support all the modes that match the GLX visuals
|
||||||
|
* sent from the X server.
|
||||||
|
*/
|
||||||
|
if ( do_delete && (m->visualID != 0) ) {
|
||||||
|
do_delete = GL_FALSE;
|
||||||
|
|
||||||
|
/* don't warn for this visual (Novell #247471 / X.Org #6689) */
|
||||||
|
if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) {
|
||||||
|
fprintf(stderr, "libGL warning: 3D driver claims to not "
|
||||||
|
"support visual 0x%02x\n", m->visualID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( do_delete ) {
|
||||||
|
*prev_next = m->next;
|
||||||
|
|
||||||
|
m->next = NULL;
|
||||||
|
_gl_context_modes_destroy( m );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prev_next = & m->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef XDAMAGE_1_1_INTERFACE
|
||||||
|
static GLboolean has_damage_post(Display *dpy)
|
||||||
|
{
|
||||||
|
static GLboolean inited = GL_FALSE;
|
||||||
|
static GLboolean has_damage;
|
||||||
|
|
||||||
|
if (!inited) {
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
if (XDamageQueryVersion(dpy, &major, &minor) &&
|
||||||
|
major == 1 && minor >= 1)
|
||||||
|
{
|
||||||
|
has_damage = GL_TRUE;
|
||||||
|
} else {
|
||||||
|
has_damage = GL_FALSE;
|
||||||
|
}
|
||||||
|
inited = GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
#ifdef XDAMAGE_1_1_INTERFACE
|
||||||
|
XRectangle *xrects;
|
||||||
|
XserverRegion region;
|
||||||
|
int i;
|
||||||
|
int x_off, y_off;
|
||||||
|
__GLXdrawable *glxDraw =
|
||||||
|
containerOf(driDraw, __GLXdrawable, driDrawable);
|
||||||
|
__GLXscreenConfigs *psc = glxDraw->psc;
|
||||||
|
Display *dpy = psc->dpy;
|
||||||
|
Drawable drawable;
|
||||||
|
|
||||||
|
if (!has_damage_post(dpy))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (front_buffer) {
|
||||||
|
x_off = x;
|
||||||
|
y_off = y;
|
||||||
|
drawable = RootWindow(dpy, psc->scr);
|
||||||
|
} else{
|
||||||
|
x_off = 0;
|
||||||
|
y_off = 0;
|
||||||
|
drawable = glxDraw->drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
xrects = malloc(sizeof(XRectangle) * num_rects);
|
||||||
|
if (xrects == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rects; i++) {
|
||||||
|
xrects[i].x = rects[i].x1 + x_off;
|
||||||
|
xrects[i].y = rects[i].y1 + y_off;
|
||||||
|
xrects[i].width = rects[i].x2 - rects[i].x1;
|
||||||
|
xrects[i].height = rects[i].y2 - rects[i].y1;
|
||||||
|
}
|
||||||
|
region = XFixesCreateRegion(dpy, xrects, num_rects);
|
||||||
|
free(xrects);
|
||||||
|
XDamageAdd(dpy, drawable, region);
|
||||||
|
XFixesDestroyRegion(dpy, region);
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
__GLXdrawable *glxDraw =
|
||||||
|
containerOf(drawable, __GLXdrawable, driDrawable);
|
||||||
|
__GLXscreenConfigs *psc = glxDraw->psc;
|
||||||
|
Display *dpy = psc->dpy;
|
||||||
|
|
||||||
|
return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
|
||||||
|
index, stamp, X, Y, W, H,
|
||||||
|
numClipRects, pClipRects,
|
||||||
|
backX, backY,
|
||||||
|
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 = {
|
||||||
|
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
|
||||||
|
__glXGetUST,
|
||||||
|
__driGetMscRateOML,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
|
||||||
|
{ __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
|
||||||
|
__glXDRIGetDrawableInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
static const __DRIdamageExtension damageExtension = {
|
||||||
|
{ __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
|
||||||
|
__glXReportDamage,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const __DRIextension *loader_extensions[] = {
|
||||||
|
&contextModesExtension.base,
|
||||||
|
&systemTimeExtension.base,
|
||||||
|
&getDrawableInfoExtension.base,
|
||||||
|
&damageExtension.base,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the required libGL-side initialization and call the client-side
|
||||||
|
* driver's \c __driCreateNewScreen function.
|
||||||
|
*
|
||||||
|
* \param dpy Display pointer.
|
||||||
|
* \param scrn Screen number on the display.
|
||||||
|
* \param psc DRI screen information.
|
||||||
|
* \param driDpy DRI display information.
|
||||||
|
* \param createNewScreen Pointer to the client-side driver's
|
||||||
|
* \c __driCreateNewScreen function.
|
||||||
|
* \returns A pointer to the \c __DRIscreenPrivate structure returned by
|
||||||
|
* the client-side driver on success, or \c NULL on failure.
|
||||||
|
*
|
||||||
|
* \todo This function needs to be modified to remove context-modes from the
|
||||||
|
* list stored in the \c __GLXscreenConfigsRec to match the list
|
||||||
|
* returned by the client-side driver.
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
|
||||||
|
__DRIdisplay * driDpy,
|
||||||
|
PFNCREATENEWSCREENFUNC createNewScreen)
|
||||||
|
{
|
||||||
|
__DRIscreenPrivate *psp = NULL;
|
||||||
|
#ifndef GLX_USE_APPLEGL
|
||||||
|
drm_handle_t hSAREA;
|
||||||
|
drmAddress pSAREA = MAP_FAILED;
|
||||||
|
char *BusID;
|
||||||
|
__DRIversion ddx_version;
|
||||||
|
__DRIversion dri_version;
|
||||||
|
__DRIversion drm_version;
|
||||||
|
__DRIframebuffer framebuffer;
|
||||||
|
int fd = -1;
|
||||||
|
int status;
|
||||||
|
const char * err_msg;
|
||||||
|
const char * err_extra;
|
||||||
|
|
||||||
|
dri_version.major = driDpy->private->driMajor;
|
||||||
|
dri_version.minor = driDpy->private->driMinor;
|
||||||
|
dri_version.patch = driDpy->private->driPatch;
|
||||||
|
|
||||||
|
|
||||||
|
err_msg = "XF86DRIOpenConnection";
|
||||||
|
err_extra = NULL;
|
||||||
|
|
||||||
|
framebuffer.base = MAP_FAILED;
|
||||||
|
framebuffer.dev_priv = NULL;
|
||||||
|
|
||||||
|
if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
|
||||||
|
int newlyopened;
|
||||||
|
fd = drmOpenOnce(NULL,BusID, &newlyopened);
|
||||||
|
Xfree(BusID); /* No longer needed */
|
||||||
|
|
||||||
|
err_msg = "open DRM";
|
||||||
|
err_extra = strerror( -fd );
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
drm_magic_t magic;
|
||||||
|
|
||||||
|
err_msg = "drmGetMagic";
|
||||||
|
err_extra = NULL;
|
||||||
|
|
||||||
|
if (!drmGetMagic(fd, &magic)) {
|
||||||
|
drmVersionPtr version = drmGetVersion(fd);
|
||||||
|
if (version) {
|
||||||
|
drm_version.major = version->version_major;
|
||||||
|
drm_version.minor = version->version_minor;
|
||||||
|
drm_version.patch = version->version_patchlevel;
|
||||||
|
drmFreeVersion(version);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
drm_version.major = -1;
|
||||||
|
drm_version.minor = -1;
|
||||||
|
drm_version.patch = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_msg = "XF86DRIAuthConnection";
|
||||||
|
if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
|
||||||
|
char *driverName;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get device name (like "tdfx") and the ddx version
|
||||||
|
* numbers. We'll check the version in each DRI driver's
|
||||||
|
* "createNewScreen" function.
|
||||||
|
*/
|
||||||
|
err_msg = "XF86DRIGetClientDriverName";
|
||||||
|
if (XF86DRIGetClientDriverName(dpy, scrn,
|
||||||
|
&ddx_version.major,
|
||||||
|
&ddx_version.minor,
|
||||||
|
&ddx_version.patch,
|
||||||
|
&driverName)) {
|
||||||
|
drm_handle_t hFB;
|
||||||
|
int junk;
|
||||||
|
|
||||||
|
/* No longer needed. */
|
||||||
|
Xfree( driverName );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get device-specific info. pDevPriv will point to a struct
|
||||||
|
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
|
||||||
|
* that has information about the screen size, depth, pitch,
|
||||||
|
* ancilliary buffers, DRM mmap handles, etc.
|
||||||
|
*/
|
||||||
|
err_msg = "XF86DRIGetDeviceInfo";
|
||||||
|
if (XF86DRIGetDeviceInfo(dpy, scrn,
|
||||||
|
&hFB,
|
||||||
|
&junk,
|
||||||
|
&framebuffer.size,
|
||||||
|
&framebuffer.stride,
|
||||||
|
&framebuffer.dev_priv_size,
|
||||||
|
&framebuffer.dev_priv)) {
|
||||||
|
framebuffer.width = DisplayWidth(dpy, scrn);
|
||||||
|
framebuffer.height = DisplayHeight(dpy, scrn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map the framebuffer region.
|
||||||
|
*/
|
||||||
|
status = drmMap(fd, hFB, framebuffer.size,
|
||||||
|
(drmAddressPtr)&framebuffer.base);
|
||||||
|
|
||||||
|
err_msg = "drmMap of framebuffer";
|
||||||
|
err_extra = strerror( -status );
|
||||||
|
|
||||||
|
if ( status == 0 ) {
|
||||||
|
/*
|
||||||
|
* Map the SAREA region. Further mmap regions
|
||||||
|
* may be setup in each DRI driver's
|
||||||
|
* "createNewScreen" function.
|
||||||
|
*/
|
||||||
|
status = drmMap(fd, hSAREA, SAREA_MAX,
|
||||||
|
&pSAREA);
|
||||||
|
|
||||||
|
err_msg = "drmMap of sarea";
|
||||||
|
err_extra = strerror( -status );
|
||||||
|
|
||||||
|
if ( status == 0 ) {
|
||||||
|
__GLcontextModes * driver_modes = NULL;
|
||||||
|
|
||||||
|
err_msg = "InitDriver";
|
||||||
|
err_extra = NULL;
|
||||||
|
psp = (*createNewScreen)(scrn,
|
||||||
|
&psc->driScreen,
|
||||||
|
& ddx_version,
|
||||||
|
& dri_version,
|
||||||
|
& drm_version,
|
||||||
|
& framebuffer,
|
||||||
|
pSAREA,
|
||||||
|
fd,
|
||||||
|
loader_extensions,
|
||||||
|
& driver_modes );
|
||||||
|
|
||||||
|
filter_modes(&psc->configs, driver_modes);
|
||||||
|
filter_modes(&psc->visuals, driver_modes);
|
||||||
|
_gl_context_modes_destroy(driver_modes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( psp == NULL ) {
|
||||||
|
if ( pSAREA != MAP_FAILED ) {
|
||||||
|
(void)drmUnmap(pSAREA, SAREA_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( framebuffer.base != MAP_FAILED ) {
|
||||||
|
(void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( framebuffer.dev_priv != NULL ) {
|
||||||
|
Xfree(framebuffer.dev_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fd >= 0 ) {
|
||||||
|
(void)drmCloseOnce(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)XF86DRICloseConnection(dpy, scrn);
|
||||||
|
|
||||||
|
if ( err_extra != NULL ) {
|
||||||
|
fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
|
||||||
|
err_extra);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "libGL error: %s failed\n", err_msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
|
||||||
|
}
|
||||||
|
#endif /* !GLX_USE_APPLEGL */
|
||||||
|
|
||||||
|
return psp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
driCreateScreen(__GLXscreenConfigs *psc, int screen,
|
||||||
|
__GLXdisplayPrivate *priv)
|
||||||
|
{
|
||||||
|
/* Create drawable hash */
|
||||||
|
psc->drawHash = __glxHashCreate();
|
||||||
|
if ( psc->drawHash == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Initialize per screen dynamic client GLX extensions */
|
||||||
|
psc->ext_list_first_time = GL_TRUE;
|
||||||
|
/* Initialize the direct rendering per screen data and functions */
|
||||||
|
if (priv->driDisplay.private != NULL) {
|
||||||
|
/* FIXME: Should it be some sort of an error if createNewScreen[i]
|
||||||
|
* FIXME: is NULL?
|
||||||
|
*/
|
||||||
|
if (priv->driDisplay.createNewScreen &&
|
||||||
|
priv->driDisplay.createNewScreen[screen]) {
|
||||||
|
|
||||||
|
psc->driScreen.private =
|
||||||
|
CallCreateNewScreen(psc->dpy, screen, psc,
|
||||||
|
& priv->driDisplay,
|
||||||
|
priv->driDisplay.createNewScreen[screen] );
|
||||||
|
if (psc->driScreen.private != NULL)
|
||||||
|
__glXScrEnableDRIExtension(psc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Called from __glXFreeDisplayPrivate.
|
/* Called from __glXFreeDisplayPrivate.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -128,6 +128,8 @@ struct __DRIdriverRec {
|
||||||
** dependent methods.
|
** dependent methods.
|
||||||
*/
|
*/
|
||||||
extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp);
|
extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp);
|
||||||
|
extern void driCreateScreen(__GLXscreenConfigs *psc, int screen,
|
||||||
|
__GLXdisplayPrivate *priv);
|
||||||
|
|
||||||
extern __DRIdriver *driGetDriver(Display *dpy, int scrNum);
|
extern __DRIdriver *driGetDriver(Display *dpy, int scrNum);
|
||||||
|
|
||||||
|
|
|
@ -633,385 +633,6 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
|
||||||
config->haveStencilBuffer = (config->stencilBits > 0);
|
config->haveStencilBuffer = (config->stencilBits > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef GLX_DIRECT_RENDERING
|
|
||||||
static void
|
|
||||||
filter_modes( __GLcontextModes ** server_modes,
|
|
||||||
const __GLcontextModes * driver_modes )
|
|
||||||
{
|
|
||||||
__GLcontextModes * m;
|
|
||||||
__GLcontextModes ** prev_next;
|
|
||||||
const __GLcontextModes * check;
|
|
||||||
|
|
||||||
if (driver_modes == NULL) {
|
|
||||||
fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For each mode in server_modes, check to see if a matching mode exists
|
|
||||||
* in driver_modes. If not, then the mode is not available.
|
|
||||||
*/
|
|
||||||
|
|
||||||
prev_next = server_modes;
|
|
||||||
for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
|
|
||||||
GLboolean do_delete = GL_TRUE;
|
|
||||||
|
|
||||||
for ( check = driver_modes ; check != NULL ; check = check->next ) {
|
|
||||||
if ( _gl_context_modes_are_same( m, check ) ) {
|
|
||||||
do_delete = GL_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The 3D has to support all the modes that match the GLX visuals
|
|
||||||
* sent from the X server.
|
|
||||||
*/
|
|
||||||
if ( do_delete && (m->visualID != 0) ) {
|
|
||||||
do_delete = GL_FALSE;
|
|
||||||
|
|
||||||
/* don't warn for this visual (Novell #247471 / X.Org #6689) */
|
|
||||||
if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) {
|
|
||||||
fprintf(stderr, "libGL warning: 3D driver claims to not "
|
|
||||||
"support visual 0x%02x\n", m->visualID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( do_delete ) {
|
|
||||||
*prev_next = m->next;
|
|
||||||
|
|
||||||
m->next = NULL;
|
|
||||||
_gl_context_modes_destroy( m );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prev_next = & m->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef XDAMAGE_1_1_INTERFACE
|
|
||||||
static GLboolean has_damage_post(Display *dpy)
|
|
||||||
{
|
|
||||||
static GLboolean inited = GL_FALSE;
|
|
||||||
static GLboolean has_damage;
|
|
||||||
|
|
||||||
if (!inited) {
|
|
||||||
int major, minor;
|
|
||||||
|
|
||||||
if (XDamageQueryVersion(dpy, &major, &minor) &&
|
|
||||||
major == 1 && minor >= 1)
|
|
||||||
{
|
|
||||||
has_damage = GL_TRUE;
|
|
||||||
} else {
|
|
||||||
has_damage = GL_FALSE;
|
|
||||||
}
|
|
||||||
inited = GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
#ifdef XDAMAGE_1_1_INTERFACE
|
|
||||||
XRectangle *xrects;
|
|
||||||
XserverRegion region;
|
|
||||||
int i;
|
|
||||||
int x_off, y_off;
|
|
||||||
__GLXdrawable *glxDraw =
|
|
||||||
containerOf(driDraw, __GLXdrawable, driDrawable);
|
|
||||||
__GLXscreenConfigs *psc = glxDraw->psc;
|
|
||||||
Display *dpy = psc->dpy;
|
|
||||||
Drawable drawable;
|
|
||||||
|
|
||||||
if (!has_damage_post(dpy))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (front_buffer) {
|
|
||||||
x_off = x;
|
|
||||||
y_off = y;
|
|
||||||
drawable = RootWindow(dpy, psc->scr);
|
|
||||||
} else{
|
|
||||||
x_off = 0;
|
|
||||||
y_off = 0;
|
|
||||||
drawable = glxDraw->drawable;
|
|
||||||
}
|
|
||||||
|
|
||||||
xrects = malloc(sizeof(XRectangle) * num_rects);
|
|
||||||
if (xrects == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < num_rects; i++) {
|
|
||||||
xrects[i].x = rects[i].x1 + x_off;
|
|
||||||
xrects[i].y = rects[i].y1 + y_off;
|
|
||||||
xrects[i].width = rects[i].x2 - rects[i].x1;
|
|
||||||
xrects[i].height = rects[i].y2 - rects[i].y1;
|
|
||||||
}
|
|
||||||
region = XFixesCreateRegion(dpy, xrects, num_rects);
|
|
||||||
free(xrects);
|
|
||||||
XDamageAdd(dpy, drawable, region);
|
|
||||||
XFixesDestroyRegion(dpy, region);
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
__GLXdrawable *glxDraw =
|
|
||||||
containerOf(drawable, __GLXdrawable, driDrawable);
|
|
||||||
__GLXscreenConfigs *psc = glxDraw->psc;
|
|
||||||
Display *dpy = psc->dpy;
|
|
||||||
|
|
||||||
return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
|
|
||||||
index, stamp, X, Y, W, H,
|
|
||||||
numClipRects, pClipRects,
|
|
||||||
backX, backY,
|
|
||||||
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 = {
|
|
||||||
{ __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
|
|
||||||
__glXGetUST,
|
|
||||||
__driGetMscRateOML,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
|
|
||||||
{ __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
|
|
||||||
__glXDRIGetDrawableInfo
|
|
||||||
};
|
|
||||||
|
|
||||||
static const __DRIdamageExtension damageExtension = {
|
|
||||||
{ __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
|
|
||||||
__glXReportDamage,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const __DRIextension *loader_extensions[] = {
|
|
||||||
&contextModesExtension.base,
|
|
||||||
&systemTimeExtension.base,
|
|
||||||
&getDrawableInfoExtension.base,
|
|
||||||
&damageExtension.base,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform the required libGL-side initialization and call the client-side
|
|
||||||
* driver's \c __driCreateNewScreen function.
|
|
||||||
*
|
|
||||||
* \param dpy Display pointer.
|
|
||||||
* \param scrn Screen number on the display.
|
|
||||||
* \param psc DRI screen information.
|
|
||||||
* \param driDpy DRI display information.
|
|
||||||
* \param createNewScreen Pointer to the client-side driver's
|
|
||||||
* \c __driCreateNewScreen function.
|
|
||||||
* \returns A pointer to the \c __DRIscreenPrivate structure returned by
|
|
||||||
* the client-side driver on success, or \c NULL on failure.
|
|
||||||
*
|
|
||||||
* \todo This function needs to be modified to remove context-modes from the
|
|
||||||
* list stored in the \c __GLXscreenConfigsRec to match the list
|
|
||||||
* returned by the client-side driver.
|
|
||||||
*/
|
|
||||||
static void *
|
|
||||||
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
|
|
||||||
__DRIdisplay * driDpy,
|
|
||||||
PFNCREATENEWSCREENFUNC createNewScreen)
|
|
||||||
{
|
|
||||||
__DRIscreenPrivate *psp = NULL;
|
|
||||||
#ifndef GLX_USE_APPLEGL
|
|
||||||
drm_handle_t hSAREA;
|
|
||||||
drmAddress pSAREA = MAP_FAILED;
|
|
||||||
char *BusID;
|
|
||||||
__DRIversion ddx_version;
|
|
||||||
__DRIversion dri_version;
|
|
||||||
__DRIversion drm_version;
|
|
||||||
__DRIframebuffer framebuffer;
|
|
||||||
int fd = -1;
|
|
||||||
int status;
|
|
||||||
const char * err_msg;
|
|
||||||
const char * err_extra;
|
|
||||||
|
|
||||||
dri_version.major = driDpy->private->driMajor;
|
|
||||||
dri_version.minor = driDpy->private->driMinor;
|
|
||||||
dri_version.patch = driDpy->private->driPatch;
|
|
||||||
|
|
||||||
|
|
||||||
err_msg = "XF86DRIOpenConnection";
|
|
||||||
err_extra = NULL;
|
|
||||||
|
|
||||||
framebuffer.base = MAP_FAILED;
|
|
||||||
framebuffer.dev_priv = NULL;
|
|
||||||
|
|
||||||
if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
|
|
||||||
int newlyopened;
|
|
||||||
fd = drmOpenOnce(NULL,BusID, &newlyopened);
|
|
||||||
Xfree(BusID); /* No longer needed */
|
|
||||||
|
|
||||||
err_msg = "open DRM";
|
|
||||||
err_extra = strerror( -fd );
|
|
||||||
|
|
||||||
if (fd >= 0) {
|
|
||||||
drm_magic_t magic;
|
|
||||||
|
|
||||||
err_msg = "drmGetMagic";
|
|
||||||
err_extra = NULL;
|
|
||||||
|
|
||||||
if (!drmGetMagic(fd, &magic)) {
|
|
||||||
drmVersionPtr version = drmGetVersion(fd);
|
|
||||||
if (version) {
|
|
||||||
drm_version.major = version->version_major;
|
|
||||||
drm_version.minor = version->version_minor;
|
|
||||||
drm_version.patch = version->version_patchlevel;
|
|
||||||
drmFreeVersion(version);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
drm_version.major = -1;
|
|
||||||
drm_version.minor = -1;
|
|
||||||
drm_version.patch = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_msg = "XF86DRIAuthConnection";
|
|
||||||
if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
|
|
||||||
char *driverName;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get device name (like "tdfx") and the ddx version
|
|
||||||
* numbers. We'll check the version in each DRI driver's
|
|
||||||
* "createNewScreen" function.
|
|
||||||
*/
|
|
||||||
err_msg = "XF86DRIGetClientDriverName";
|
|
||||||
if (XF86DRIGetClientDriverName(dpy, scrn,
|
|
||||||
&ddx_version.major,
|
|
||||||
&ddx_version.minor,
|
|
||||||
&ddx_version.patch,
|
|
||||||
&driverName)) {
|
|
||||||
drm_handle_t hFB;
|
|
||||||
int junk;
|
|
||||||
|
|
||||||
/* No longer needed. */
|
|
||||||
Xfree( driverName );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get device-specific info. pDevPriv will point to a struct
|
|
||||||
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
|
|
||||||
* that has information about the screen size, depth, pitch,
|
|
||||||
* ancilliary buffers, DRM mmap handles, etc.
|
|
||||||
*/
|
|
||||||
err_msg = "XF86DRIGetDeviceInfo";
|
|
||||||
if (XF86DRIGetDeviceInfo(dpy, scrn,
|
|
||||||
&hFB,
|
|
||||||
&junk,
|
|
||||||
&framebuffer.size,
|
|
||||||
&framebuffer.stride,
|
|
||||||
&framebuffer.dev_priv_size,
|
|
||||||
&framebuffer.dev_priv)) {
|
|
||||||
framebuffer.width = DisplayWidth(dpy, scrn);
|
|
||||||
framebuffer.height = DisplayHeight(dpy, scrn);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map the framebuffer region.
|
|
||||||
*/
|
|
||||||
status = drmMap(fd, hFB, framebuffer.size,
|
|
||||||
(drmAddressPtr)&framebuffer.base);
|
|
||||||
|
|
||||||
err_msg = "drmMap of framebuffer";
|
|
||||||
err_extra = strerror( -status );
|
|
||||||
|
|
||||||
if ( status == 0 ) {
|
|
||||||
/*
|
|
||||||
* Map the SAREA region. Further mmap regions
|
|
||||||
* may be setup in each DRI driver's
|
|
||||||
* "createNewScreen" function.
|
|
||||||
*/
|
|
||||||
status = drmMap(fd, hSAREA, SAREA_MAX,
|
|
||||||
&pSAREA);
|
|
||||||
|
|
||||||
err_msg = "drmMap of sarea";
|
|
||||||
err_extra = strerror( -status );
|
|
||||||
|
|
||||||
if ( status == 0 ) {
|
|
||||||
__GLcontextModes * driver_modes = NULL;
|
|
||||||
|
|
||||||
err_msg = "InitDriver";
|
|
||||||
err_extra = NULL;
|
|
||||||
psp = (*createNewScreen)(scrn,
|
|
||||||
&psc->driScreen,
|
|
||||||
& ddx_version,
|
|
||||||
& dri_version,
|
|
||||||
& drm_version,
|
|
||||||
& framebuffer,
|
|
||||||
pSAREA,
|
|
||||||
fd,
|
|
||||||
loader_extensions,
|
|
||||||
& driver_modes );
|
|
||||||
|
|
||||||
filter_modes(&psc->configs, driver_modes);
|
|
||||||
filter_modes(&psc->visuals, driver_modes);
|
|
||||||
_gl_context_modes_destroy(driver_modes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( psp == NULL ) {
|
|
||||||
if ( pSAREA != MAP_FAILED ) {
|
|
||||||
(void)drmUnmap(pSAREA, SAREA_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( framebuffer.base != MAP_FAILED ) {
|
|
||||||
(void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( framebuffer.dev_priv != NULL ) {
|
|
||||||
Xfree(framebuffer.dev_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fd >= 0 ) {
|
|
||||||
(void)drmCloseOnce(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)XF86DRICloseConnection(dpy, scrn);
|
|
||||||
|
|
||||||
if ( err_extra != NULL ) {
|
|
||||||
fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
|
|
||||||
err_extra);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "libGL error: %s failed\n", err_msg );
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
|
|
||||||
}
|
|
||||||
#endif /* !GLX_USE_APPLEGL */
|
|
||||||
|
|
||||||
return psp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GLX_DIRECT_RENDERING */
|
|
||||||
|
|
||||||
static __GLcontextModes *
|
static __GLcontextModes *
|
||||||
createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
|
createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
|
||||||
int screen, GLboolean tagged_only)
|
int screen, GLboolean tagged_only)
|
||||||
|
@ -1167,35 +788,10 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
|
||||||
getVisualConfigs(dpy, priv, i);
|
getVisualConfigs(dpy, priv, i);
|
||||||
getFBConfigs(dpy, priv, i);
|
getFBConfigs(dpy, priv, i);
|
||||||
|
|
||||||
#ifdef GLX_DIRECT_RENDERING
|
|
||||||
psc->scr = i;
|
psc->scr = i;
|
||||||
psc->dpy = dpy;
|
psc->dpy = dpy;
|
||||||
/* Create drawable hash */
|
#ifdef GLX_DIRECT_RENDERING
|
||||||
psc->drawHash = __glxHashCreate();
|
driCreateScreen(psc, i, priv);
|
||||||
if ( psc->drawHash == NULL ) {
|
|
||||||
SyncHandle();
|
|
||||||
FreeScreenConfigs(priv);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize per screen dynamic client GLX extensions */
|
|
||||||
psc->ext_list_first_time = GL_TRUE;
|
|
||||||
/* Initialize the direct rendering per screen data and functions */
|
|
||||||
if (priv->driDisplay.private != NULL) {
|
|
||||||
/* FIXME: Should it be some sort of an error if createNewScreen[i]
|
|
||||||
* FIXME: is NULL?
|
|
||||||
*/
|
|
||||||
if (priv->driDisplay.createNewScreen &&
|
|
||||||
priv->driDisplay.createNewScreen[i]) {
|
|
||||||
|
|
||||||
psc->driScreen.private =
|
|
||||||
CallCreateNewScreen(dpy, i, psc,
|
|
||||||
& priv->driDisplay,
|
|
||||||
priv->driDisplay.createNewScreen[i] );
|
|
||||||
if (psc->driScreen.private != NULL)
|
|
||||||
__glXScrEnableDRIExtension(psc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
SyncHandle();
|
SyncHandle();
|
||||||
|
|
Loading…
Reference in New Issue