#include "tdfx_context.h"
#include "tdfx_lock.h"
#include "tdfx_vb.h"
+#include "tdfx_span.h"
#include "tdfx_tris.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "xmlpool.h"
+
+#include "utils.h"
#ifdef DEBUG_LOCKING
char *prevLockFile = 0;
#endif
#ifndef TDFX_DEBUG
-int TDFX_DEBUG = (0
-/* | DEBUG_ALWAYS_SYNC */
-/* | DEBUG_VERBOSE_API */
-/* | DEBUG_VERBOSE_MSG */
-/* | DEBUG_VERBOSE_LRU */
-/* | DEBUG_VERBOSE_DRI */
-/* | DEBUG_VERBOSE_IOCTL */
-/* | DEBUG_VERBOSE_2D */
- );
+int TDFX_DEBUG = 0;
#endif
+PUBLIC const char __driConfigOptions[] =
+DRI_CONF_BEGIN
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_NO_RAST(false)
+ DRI_CONF_SECTION_END
+DRI_CONF_END;
+
+static const __DRIextension *tdfxExtensions[] = {
+ &driReadDrawableExtension,
+};
+
+static const GLuint __driNConfigOptions = 1;
+extern const struct dri_extension card_extensions[];
+extern const struct dri_extension napalm_extensions[];
static GLboolean
tdfxCreateScreen( __DRIscreenPrivate *sPriv )
tdfxScreenPrivate *fxScreen;
TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv;
+ if (sPriv->devPrivSize != sizeof(TDFXDRIRec)) {
+ fprintf(stderr,"\nERROR! sizeof(TDFXDRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
/* Allocate the private area */
fxScreen = (tdfxScreenPrivate *) CALLOC( sizeof(tdfxScreenPrivate) );
if ( !fxScreen )
return GL_FALSE;
+ /* parse information in __driConfigOptions */
+ driParseOptionInfo (&fxScreen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
fxScreen->driScrnPriv = sPriv;
sPriv->private = (void *) fxScreen;
return GL_FALSE;
}
+ sPriv->extensions = tdfxExtensions;
+
return GL_TRUE;
}
{
tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private;
- if ( fxScreen ) {
- drmUnmap( fxScreen->regs.map, fxScreen->regs.size );
+ if (!fxScreen)
+ return;
- FREE( fxScreen );
- sPriv->private = NULL;
- }
+ drmUnmap( fxScreen->regs.map, fxScreen->regs.size );
+
+ /* free all option information */
+ driDestroyOptionInfo (&fxScreen->optionCache);
+
+ FREE( fxScreen );
+ sPriv->private = NULL;
}
tdfxInitDriver( __DRIscreenPrivate *sPriv )
{
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
- fprintf( stderr, "%s( %p )\n", __FUNCTION__, sPriv );
- }
-
- /* Check the DRI externsion version */
- if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) {
- __driUtilMessage( "tdfx DRI driver expected DRI version 4.0.x "
- "but got version %d.%d.%d",
- sPriv->driMajor, sPriv->driMinor, sPriv->driPatch );
- return GL_FALSE;
- }
-
- /* Check that the DDX driver version is compatible */
- if ( sPriv->ddxMajor != 1 ||
- sPriv->ddxMinor < 0 ) {
- __driUtilMessage(
- "3dfx DRI driver expected DDX driver version 1.0.x "
- "but got version %d.%d.%d",
- sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
- return GL_FALSE;
- }
-
- /* Check that the DRM driver version is compatible */
- if ( sPriv->drmMajor != 1 ||
- sPriv->drmMinor < 0 ) {
- __driUtilMessage(
- "3dfx DRI driver expected DRM driver version 1.0.x "
- "but got version %d.%d.%d",
- sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
- return GL_FALSE;
+ fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)sPriv );
}
if ( !tdfxCreateScreen( sPriv ) ) {
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
+ tdfxScreenPrivate *screen = (tdfxScreenPrivate *) driScrnPriv->private;
+
if (isPixmap) {
return GL_FALSE; /* not implemented */
}
else {
- driDrawPriv->driverPrivate = (void *)
- _mesa_create_framebuffer( mesaVis,
- GL_FALSE, /* software depth buffer? */
- mesaVis->stencilBits > 0,
+ struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+
+ {
+ driRenderbuffer *frontRb
+ = driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
+ screen->fbOffset, screen->width, driDrawPriv);
+ tdfxSetSpanFunctions(frontRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
+ }
+
+ if (mesaVis->doubleBufferMode) {
+ driRenderbuffer *backRb
+ = driNewRenderbuffer(GL_RGBA, NULL, screen->cpp,
+ screen->backOffset, screen->width,
+ driDrawPriv);
+ tdfxSetSpanFunctions(backRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+ backRb->backBuffer = GL_TRUE;
+ }
+
+ if (mesaVis->depthBits == 16) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, screen->cpp,
+ screen->depthOffset, screen->width,
+ driDrawPriv);
+ tdfxSetSpanFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+ else if (mesaVis->depthBits == 24) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT24, NULL, screen->cpp,
+ screen->depthOffset, screen->width,
+ driDrawPriv);
+ tdfxSetSpanFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+
+ if (mesaVis->stencilBits > 0) {
+ driRenderbuffer *stencilRb
+ = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL, screen->cpp,
+ screen->depthOffset, screen->width,
+ driDrawPriv);
+ tdfxSetSpanFunctions(stencilRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
+ }
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ GL_FALSE, /*swStencil,*/
mesaVis->accumRedBits > 0,
- GL_FALSE /* software alpha channel? */ );
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+ driDrawPriv->driverPrivate = (void *) fb;
+
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
- _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
}
GLframebuffer *mesaBuffer;
if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
- fprintf( stderr, "%s( %p )\n", __FUNCTION__, driDrawPriv );
+ fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)driDrawPriv );
}
mesaBuffer = (GLframebuffer *) driDrawPriv->driverPrivate;
return;
LOCK_HARDWARE( fxMesa );
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
printf("SwapBuf SetState 1\n");
+#endif
fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
}
}
if (ctx->DriverCtx != fxMesa) {
fxMesa = TDFX_CONTEXT(ctx);
fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
printf("SwapBuf SetState 2\n");
+#endif
fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
}
UNLOCK_HARDWARE( fxMesa );
}
-static GLboolean
-tdfxOpenCloseFullScreen(__DRIcontextPrivate *driContextPriv)
-{
- return GL_TRUE;
-}
-
-
static const struct __DriverAPIRec tdfxAPI = {
- .InitDriver = tdfxInitDriver,
.DestroyScreen = tdfxDestroyScreen,
.CreateContext = tdfxCreateContext,
.DestroyContext = tdfxDestroyContext,
.SwapBuffers = tdfxSwapBuffers,
.MakeCurrent = tdfxMakeCurrent,
.UnbindContext = tdfxUnbindContext,
- .OpenFullScreen = tdfxOpenCloseFullScreen,
- .CloseFullScreen = tdfxOpenCloseFullScreen,
.GetSwapInfo = NULL,
- .GetMSC = NULL,
+ .GetDrawableMSC = NULL,
.WaitForMSC = NULL,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
};
-/*
- * This is the bootstrap function for the driver.
- * The __driCreateScreen name is the symbol that libGL.so fetches.
- * Return: pointer to a __DRIscreenPrivate.
- */
-#ifndef _SOLO
-void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
- int numConfigs, __GLXvisualConfig *config)
+static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits,
+ unsigned depth_bits,
+ unsigned stencil_bits,
+ GLboolean have_back_buffer)
{
- __DRIscreenPrivate *psp;
- psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tdfxAPI);
- return (void *) psp;
+ __GLcontextModes *modes;
+ __GLcontextModes *m;
+ unsigned num_modes;
+ unsigned vis[2] = { GLX_TRUE_COLOR, GLX_DIRECT_COLOR };
+ unsigned deep = (depth_bits > 17);
+ unsigned i, db, depth, accum, stencil;
+
+ /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
+ * enough to add support. Basically, if a context is created with an
+ * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
+ * will never be used.
+ */
+
+ num_modes = (depth_bits == 16) ? 32 : 16;
+
+ modes = (*dri_interface->createContextModes)(num_modes, sizeof(__GLcontextModes));
+ m = modes;
+
+ for (i = 0; i <= 1; i++) {
+ for (db = 0; db <= 1; db++) {
+ for (depth = 0; depth <= 1; depth++) {
+ for (accum = 0; accum <= 1; accum++) {
+ for (stencil = 0; stencil <= !deep; stencil++) {
+ if (deep) stencil = depth;
+ m->redBits = deep ? 8 : 5;
+ m->greenBits = deep ? 8 : 6;
+ m->blueBits = deep ? 8 : 5;
+ m->alphaBits = deep ? 8 : 0;
+ m->redMask = deep ?0xFF000000 :0x0000F800;
+ m->greenMask = deep ?0x00FF0000 :0x000007E0;
+ m->blueMask = deep ?0x0000FF00 :0x0000001F;
+ m->alphaMask = deep ? 0x000000FF : 0;
+ m->rgbBits = m->redBits + m->greenBits +
+ m->blueBits + m->alphaBits;
+ m->accumRedBits = accum ? 16 : 0;
+ m->accumGreenBits = accum ? 16 : 0;
+ m->accumBlueBits = accum ? 16 : 0;
+ m->accumAlphaBits = (accum && deep) ? 16 : 0;
+ m->stencilBits = stencil ? 8 : 0;
+ m->depthBits = deep
+ ? (depth ? 24 : 0)
+ : (depth ? 0 : depth_bits);
+ m->visualType = vis[i];
+ m->renderType = GLX_RGBA_BIT;
+ m->drawableType = GLX_WINDOW_BIT;
+ m->rgbMode = GL_TRUE;
+ m->doubleBufferMode = db ? GL_TRUE : GL_FALSE;
+ if (db)
+ m->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ m->visualRating = ((stencil && !deep) || accum)
+ ? GLX_SLOW_CONFIG
+ : GLX_NONE;
+ m = m->next;
+ if (deep) stencil = 0;
+ }
+ }
+ }
+ }
+ }
+
+ return modes;
}
-#else
-void *__driCreateScreen(struct DRIDriverRec *driver,
- struct DRIDriverContextRec *driverContext)
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
+ */
+__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp;
- psp = __driUtilCreateScreen(driver, driverContext, &tdfxAPI);
- return (void *) psp;
+ static const __DRIversion ddx_expected = { 1, 1, 0 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 1, 0, 0 };
+
+ /* divined from tdfx_dri.c, sketchy */
+ TDFXDRIPtr dri_priv = (TDFXDRIPtr) psp->pDevPriv;
+
+ /* XXX i wish it was like this */
+ /* bpp = dri_priv->bpp */
+ int bpp = (dri_priv->cpp > 2) ? 24 : 16;
+
+ if ( ! driCheckDriDdxDrmVersions2( "tdfx",
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
+ return NULL;
+
+ psp->DriverAPI = tdfxAPI;
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+ driInitExtensions( NULL, napalm_extensions, GL_FALSE );
+
+ if (!tdfxInitDriver(psp))
+ return NULL;
+
+ return tdfxFillInModes(bpp, (bpp == 16) ? 16 : 24,
+ (bpp == 16) ? 0 : 8,
+ (dri_priv->backOffset!=dri_priv->depthOffset));
}
-#endif