Fix software GL to provide a list of supported fbconfigs like the DRI case.

This commit is contained in:
Kristian Høgsberg 2007-10-19 16:21:54 -04:00
parent 74e84b8d89
commit 89c6108531
2 changed files with 126 additions and 103 deletions

View File

@ -70,7 +70,7 @@ struct __GLXMESAdrawable {
XMesaBuffer xm_buf;
};
static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid);
static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID);
static void
@ -141,7 +141,7 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
glxPriv->base.resize = __glXMesaDrawableResize;
glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers;
xm_vis = find_mesa_visual(screen, modes->visualID);
xm_vis = find_mesa_visual(screen, modes->fbconfigID);
if (xm_vis == NULL) {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
modes->visualID);
@ -155,6 +155,11 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0);
}
if (glxPriv->xm_buf == NULL) {
xfree(glxPriv);
return NULL;
}
return &glxPriv->base;
}
@ -235,7 +240,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen,
context->base.copy = __glXMesaContextCopy;
context->base.forceCurrent = __glXMesaContextForceCurrent;
xm_vis = find_mesa_visual(screen, modes->visualID);
xm_vis = find_mesa_visual(screen, modes->fbconfigID);
if (!xm_vis) {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
modes->visualID);
@ -274,107 +279,122 @@ __glXMesaScreenDestroy(__GLXscreen *screen)
}
static XMesaVisual
find_mesa_visual(__GLXscreen *screen, VisualID vid)
find_mesa_visual(__GLXscreen *screen, XID fbconfigID)
{
__GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
const __GLcontextModes *modes;
unsigned i = 0;
for ( modes = screen->fbconfigs ; modes != NULL ; modes = modes->next ) {
if ( modes->visualID == vid ) {
break;
}
for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) {
if (modes->fbconfigID == fbconfigID)
return mesaScreen->xm_vis[i];
i++;
}
return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL;
return NULL;
}
static void init_screen_visuals(__GLXMESAscreen *screen)
const static int numBack = 2;
const static int numDepth = 2;
const static int numStencil = 2;
static __GLcontextModes *
createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen,
VisualPtr visual, __GLcontextModes *config)
{
ScreenPtr pScreen = screen->base.pScreen;
__GLcontextModes *modes;
XMesaVisual *pXMesaVisual;
int *used;
int num_vis, j, size;
int back, depth, stencil;
/* Alloc space for the list of XMesa visuals */
size = screen->base.numVisuals * sizeof(XMesaVisual);
pXMesaVisual = (XMesaVisual *) xalloc(size);
memset(pXMesaVisual, 0, size);
/* FIXME: Ok, I'm making all this up... anybody has a better idea? */
/* FIXME: Change 'used' to be a array of bits (rather than of ints),
* FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less
* FIXME: than 64 or 128 the stack array can be used instead of calling
* FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to
* FIXME: array of bytes instead of ints!
*/
used = (int *) xalloc(pScreen->numVisuals * sizeof(int));
memset(used, 0, pScreen->numVisuals * sizeof(int));
for (back = numBack - 1; back >= 0; back--)
for (depth = 0; depth < numDepth; depth++)
for (stencil = 0; stencil < numStencil; stencil++) {
config->visualType = _gl_convert_from_x_visual_type(visual->class);
config->xRenderable = GL_TRUE;
config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
config->rgbMode = (visual->class >= TrueColor);
config->colorIndexMode = !config->rgbMode;
config->renderType =
(config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
config->doubleBufferMode = back;
config->haveDepthBuffer = depth;
config->depthBits = depth ? visual->nplanes : 0;
config->haveStencilBuffer = stencil;
config->stencilBits = stencil ? visual->bitsPerRGBValue : 0;
config->haveAccumBuffer = 0;
num_vis = 0;
for ( modes = screen->base.fbconfigs; modes != NULL; modes = modes->next ) {
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
const int nplanes = (modes->rgbBits - modes->alphaBits);
const VisualPtr pVis = pScreen->visuals;
config->redBits = Ones(visual->redMask);
config->greenBits = Ones(visual->greenMask);
config->blueBits = Ones(visual->blueMask);
config->alphaBits = 0;
config->redMask = visual->redMask;
config->greenMask = visual->greenMask;
config->blueMask = visual->blueMask;
config->alphaMask = 0;
config->rgbBits = config->rgbMode ? visual->nplanes : 0;
config->indexBits = config->colorIndexMode ? visual->nplanes : 0;
config = config->next;
}
for (j = 0; j < pScreen->numVisuals; j++) {
if (pVis[j].class == vis_class &&
pVis[j].nplanes == nplanes &&
pVis[j].redMask == modes->redMask &&
pVis[j].greenMask == modes->greenMask &&
pVis[j].blueMask == modes->blueMask &&
!used[j]) {
return config;
}
/* Create the XMesa visual */
assert(num_vis < screen->base.numVisuals);
pXMesaVisual[num_vis] =
XMesaCreateVisual(pScreen,
&pVis[j],
modes->rgbMode,
(modes->alphaBits > 0),
modes->doubleBufferMode,
modes->stereoMode,
GL_TRUE, /* ximage_flag */
modes->depthBits,
modes->stencilBits,
modes->accumRedBits,
modes->accumGreenBits,
modes->accumBlueBits,
modes->accumAlphaBits,
modes->samples,
modes->level,
modes->visualRating);
/* Set the VisualID */
modes->visualID = pVis[j].vid;
static void
createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
{
__GLcontextModes *configs;
int i;
/* Mark this visual used */
used[j] = 1;
/* We assume here that each existing visual correspond to a
* different visual class. Note, this runs before COMPOSITE adds
* its visual, so it's not entirely crazy. */
pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil;
pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs,
sizeof *configs);
configs = pGlxScreen->fbconfigs;
for (i = 0; i < pScreen->numVisuals; i++)
configs = createFBConfigsForVisual(pGlxScreen, pScreen,
&pScreen->visuals[i], configs);
}
static void
createMesaVisuals(__GLXMESAscreen *pMesaScreen)
{
__GLcontextModes *config;
ScreenPtr pScreen;
VisualPtr visual;
int i, j;
i = 0;
pScreen = pMesaScreen->base.pScreen;
pMesaScreen->xm_vis =
xcalloc(pMesaScreen->base.numFBConfigs, sizeof (XMesaVisual));
for (config = pMesaScreen->base.fbconfigs; config != NULL; config = config->next) {
for (j = 0; j < pScreen->numVisuals; j++)
if (pScreen->visuals[j].vid == config->visualID) {
visual = &pScreen->visuals[j];
break;
}
}
if ( j == pScreen->numVisuals ) {
ErrorF("No matching visual for __GLcontextMode with "
"visual class = %d (%d), nplanes = %u\n",
vis_class,
modes->visualType,
(modes->rgbBits - modes->alphaBits) );
}
else if ( modes->visualID == -1 ) {
FatalError( "Matching visual found, but visualID still -1!\n" );
}
num_vis++;
pMesaScreen->xm_vis[i++] =
XMesaCreateVisual(pScreen,
visual,
config->rgbMode,
(config->alphaBits > 0),
config->doubleBufferMode,
config->stereoMode,
GL_TRUE, /* ximage_flag */
config->depthBits,
config->stencilBits,
config->accumRedBits,
config->accumGreenBits,
config->accumBlueBits,
config->accumAlphaBits,
config->samples,
config->level,
config->visualRating);
}
xfree(used);
screen->num_vis = num_vis;
screen->xm_vis = pXMesaVisual;
assert(screen->num_vis <= screen->base.numVisuals);
}
static __GLXscreen *
@ -386,19 +406,22 @@ __glXMesaScreenProbe(ScreenPtr pScreen)
if (screen == NULL)
return NULL;
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
createFBConfigs(&screen->base, pScreen);
__glXScreenInit(&screen->base, pScreen);
/* Now that GLX has created the corresponding X visual, create the mesa visuals. */
createMesaVisuals(screen);
screen->base.destroy = __glXMesaScreenDestroy;
screen->base.createContext = __glXMesaScreenCreateContext;
screen->base.createDrawable = __glXMesaScreenCreateDrawable;
screen->base.pScreen = pScreen;
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
init_screen_visuals(screen);
return &screen->base;
}

View File

@ -469,8 +469,6 @@ addFullSet(__GLXscreen *pGlxScreen)
return;
}
ErrorF("addFullSet, setting numVisuals to %d\n", pGlxScreen->numFBConfigs);
pGlxScreen->numVisuals = pGlxScreen->numFBConfigs;
for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) {
pGlxScreen->visuals[i] = config;
@ -500,10 +498,24 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
glxGeneration = serverGeneration;
}
pGlxScreen->pScreen = pScreen;
pGlxScreen->GLextensions = xstrdup(GLServerExtensions);
pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName);
pGlxScreen->GLXversion = xstrdup(GLXServerVersion);
pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions);
pGlxScreen->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = glxPositionWindow;
pGlxScreen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = glxCloseScreen;
i = 0;
for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
m->fbconfigID = FakeClientID(0);
m->visualID = findVisualForConfig(pScreen, m);
ErrorF("mapping fbconfig id 0x%02lx to visual id 0x%02lx\n",
m->fbconfigID, m->visualID);
i++;
}
pGlxScreen->numFBConfigs = i;
@ -526,18 +538,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
break;
}
pGlxScreen->pScreen = pScreen;
pGlxScreen->GLextensions = xstrdup(GLServerExtensions);
pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName);
pGlxScreen->GLXversion = xstrdup(GLXServerVersion);
pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions);
pGlxScreen->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = glxPositionWindow;
pGlxScreen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = glxCloseScreen;
pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) pGlxScreen;
}