-/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_xmesa.c,v 1.4 2002/02/22 21:32:59 dawes Exp $
+/*
*
* GLX Hardware Device Driver for Sun Creator/Creator3D
* Copyright (C) 2000, 2001 David S. Miller
*/
#include "ffb_xmesa.h"
-#include "context.h"
-#include "matrix.h"
-#include "simple_list.h"
-#include "imports.h"
+#include "main/context.h"
+#include "main/framebuffer.h"
+#include "main/matrix.h"
+#include "main/renderbuffer.h"
+#include "main/simple_list.h"
+#include "main/imports.h"
+#include "utils.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "drivers/common/driverfuncs.h"
#include "ffb_context.h"
#include "drm_sarea.h"
+#include "drirenderbuffer.h"
+
static GLboolean
ffbInitDriver(__DRIscreenPrivate *sPriv)
{
ffbScreenPrivate *ffbScreen;
FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
+ drmAddress map;
if (getenv("LIBGL_FORCE_XSERVER"))
return GL_FALSE;
+
+ if (sPriv->devPrivSize != sizeof(FFBDRIRec)) {
+ fprintf(stderr,"\nERROR! sizeof(FFBDRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
/* Allocate the private area. */
ffbScreen = (ffbScreenPrivate *) MALLOC(sizeof(ffbScreenPrivate));
if (!ffbScreen)
if (drmMap(sPriv->fd,
gDRIPriv->hFbcRegs,
gDRIPriv->sFbcRegs,
- &gDRIPriv->mFbcRegs)) {
+ &map)) {
FREE(ffbScreen);
return GL_FALSE;
}
- ffbScreen->regs = (ffb_fbcPtr) gDRIPriv->mFbcRegs;
+ ffbScreen->regs = (ffb_fbcPtr) map;
/* Map ramdac registers. */
if (drmMap(sPriv->fd,
gDRIPriv->hDacRegs,
gDRIPriv->sDacRegs,
- &gDRIPriv->mDacRegs)) {
- drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
+ &map)) {
+ drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
FREE(ffbScreen);
return GL_FALSE;
}
- ffbScreen->dac = (ffb_dacPtr) gDRIPriv->mDacRegs;
+ ffbScreen->dac = (ffb_dacPtr) map;
/* Map "Smart" framebuffer views. */
if (drmMap(sPriv->fd,
gDRIPriv->hSfb8r,
gDRIPriv->sSfb8r,
- &gDRIPriv->mSfb8r)) {
- drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
- drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
+ &map)) {
+ drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
+ drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
FREE(ffbScreen);
return GL_FALSE;
}
- ffbScreen->sfb8r = (volatile char *) gDRIPriv->mSfb8r;
+ ffbScreen->sfb8r = (volatile char *) map;
if (drmMap(sPriv->fd,
gDRIPriv->hSfb32,
gDRIPriv->sSfb32,
- &gDRIPriv->mSfb32)) {
- drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
- drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
- drmUnmap(gDRIPriv->mSfb8r, gDRIPriv->sSfb8r);
+ &map)) {
+ drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
+ drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
+ drmUnmap((drmAddress)ffbScreen->sfb8r, gDRIPriv->sSfb8r);
FREE(ffbScreen);
return GL_FALSE;
}
- ffbScreen->sfb32 = (volatile char *) gDRIPriv->mSfb32;
+ ffbScreen->sfb32 = (volatile char *) map;
if (drmMap(sPriv->fd,
gDRIPriv->hSfb64,
gDRIPriv->sSfb64,
- &gDRIPriv->mSfb64)) {
- drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
- drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
- drmUnmap(gDRIPriv->mSfb8r, gDRIPriv->sSfb8r);
- drmUnmap(gDRIPriv->mSfb32, gDRIPriv->sSfb32);
+ &map)) {
+ drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
+ drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
+ drmUnmap((drmAddress)ffbScreen->sfb8r, gDRIPriv->sSfb8r);
+ drmUnmap((drmAddress)ffbScreen->sfb32, gDRIPriv->sSfb32);
FREE(ffbScreen);
return GL_FALSE;
}
- ffbScreen->sfb64 = (volatile char *) gDRIPriv->mSfb64;
+ ffbScreen->sfb64 = (volatile char *) map;
ffbScreen->fifo_cache = 0;
ffbScreen->rp_active = 0;
ffbScreenPrivate *ffbScreen = sPriv->private;
FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
- drmUnmap(gDRIPriv->mFbcRegs, gDRIPriv->sFbcRegs);
- drmUnmap(gDRIPriv->mDacRegs, gDRIPriv->sDacRegs);
- drmUnmap(gDRIPriv->mSfb8r, gDRIPriv->sSfb8r);
- drmUnmap(gDRIPriv->mSfb32, gDRIPriv->sSfb32);
- drmUnmap(gDRIPriv->mSfb64, gDRIPriv->sSfb64);
+ drmUnmap((drmAddress)ffbScreen->regs, gDRIPriv->sFbcRegs);
+ drmUnmap((drmAddress)ffbScreen->dac, gDRIPriv->sDacRegs);
+ drmUnmap((drmAddress)ffbScreen->sfb8r, gDRIPriv->sSfb8r);
+ drmUnmap((drmAddress)ffbScreen->sfb32, gDRIPriv->sSfb32);
+ drmUnmap((drmAddress)ffbScreen->sfb64, gDRIPriv->sSfb64);
FREE(ffbScreen);
}
fmesa->driScreen = sPriv;
fmesa->ffb_sarea = FFB_DRISHARE(sPriv->pSAREA);
- /* Register and framebuffer hw pointers. */
+ /* Register and framebuffer pointers. */
fmesa->regs = ffbScreen->regs;
fmesa->sfb32 = ffbScreen->sfb32;
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext( ctx );
- _ac_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
ffbDDExtensionsInit(ctx);
ffbDDInitDriverFuncs(ctx);
ffbDDInitStateFuncs(ctx);
- ffbDDInitSpanFuncs(ctx);
- ffbDDInitDepthFuncs(ctx);
- ffbDDInitStencilFuncs(ctx);
ffbDDInitRenderFuncs(ctx);
/*ffbDDInitTexFuncs(ctx); not needed */
ffbDDInitBitmapFuncs(ctx);
_swsetup_DestroyContext( fmesa->glCtx );
_tnl_DestroyContext( fmesa->glCtx );
- _ac_DestroyContext( fmesa->glCtx );
+ _vbo_DestroyContext( fmesa->glCtx );
_swrast_DestroyContext( fmesa->glCtx );
/* free the Mesa context */
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
+ /* Mesa checks for pitch > 0, but ffb doesn't use pitches */
+ int bogusPitch = 1;
+ int bpp = 4; /* we've always got a 32bpp framebuffer */
+ int offset = 0; /* always at 0 for offset */
+
if (isPixmap) {
return GL_FALSE; /* not implemented */
- }
- else {
- driDrawPriv->driverPrivate = (void *)
- _mesa_create_framebuffer(mesaVis,
- GL_FALSE, /* software depth buffer? */
- mesaVis->stencilBits > 0,
- mesaVis->accumRedBits > 0,
- mesaVis->alphaBits > 0);
+ } else {
+ GLboolean swStencil = (mesaVis->stencilBits > 0 &&
+ mesaVis->depthBits != 24);
+ struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+
+ {
+ driRenderbuffer *frontRb
+ = driNewRenderbuffer(GL_RGBA, NULL, bpp, offset, bogusPitch,
+ driDrawPriv);
+ ffbSetSpanFunctions(frontRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
+ }
+
+ if (mesaVis->doubleBufferMode) {
+ driRenderbuffer *backRb
+ = driNewRenderbuffer(GL_RGBA, NULL, bpp, offset, bogusPitch,
+ driDrawPriv);
+ ffbSetSpanFunctions(backRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
+ }
+
+ if (mesaVis->depthBits == 16) {
+ driRenderbuffer *depthRb
+ = driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, bpp, offset,
+ bogusPitch, driDrawPriv);
+ ffbSetDepthFunctions(depthRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
+ }
+
+ if (mesaVis->stencilBits > 0 && !swStencil) {
+ driRenderbuffer *stencilRb
+ = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL, bpp, offset,
+ bogusPitch, driDrawPriv);
+ ffbSetStencilFunctions(stencilRb, mesaVis);
+ _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
+ }
+
+ _mesa_add_soft_renderbuffers(fb,
+ GL_FALSE, /* color */
+ GL_FALSE, /* depth */
+ swStencil,
+ mesaVis->accumRedBits > 0,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux */);
+ driDrawPriv->driverPrivate = (void *) fb;
+
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
ffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
- _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
}
fmesa->driDrawable = driDrawPriv;
- _mesa_make_current2(fmesa->glCtx,
+ _mesa_make_current(fmesa->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate);
* we need to clear all the hw buffers.
*/
ffbDDClear(fmesa->glCtx,
- (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT |
- DD_DEPTH_BIT | DD_STENCIL_BIT),
- 1, 0, 0, 0, 0);
+ (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
+ BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
}
} else {
- _mesa_make_current(NULL, NULL);
+ _mesa_make_current(NULL, NULL, NULL);
}
return GL_TRUE;
GLcontext *ctx = fmesa->glCtx;
ffbCalcViewport(ctx);
- if (ctx->Polygon.StippleFlag)
+ driUpdateFramebufferSize(ctx, dPriv);
+ if (ctx->Polygon.StippleFlag) {
ffbXformAreaPattern(fmesa,
(const GLubyte *)ctx->PolygonStipple);
+ }
}
}
+static const __DRIconfig **
+ffbFillInModes( __DRIscreenPrivate *psp,
+ unsigned pixel_bits, unsigned depth_bits,
+ unsigned stencil_bits, GLboolean have_back_buffer )
+{
+ __DRIconfig **configs;
+ __GLcontextModes *m;
+ unsigned depth_buffer_factor;
+ unsigned back_buffer_factor;
+ GLenum fb_format;
+ GLenum fb_type;
+ int i;
+
+ /* GLX_SWAP_COPY_OML is only supported because the FFB driver doesn't
+ * support pageflipping at all.
+ */
+ static const GLenum back_buffer_modes[] = {
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+ };
+
+ uint8_t depth_bits_array[3];
+ uint8_t stencil_bits_array[3];
+
+ depth_bits_array[0] = 0;
+ depth_bits_array[1] = depth_bits;
+ depth_bits_array[2] = depth_bits;
+
+ /* Just like with the accumulation buffer, always provide some modes
+ * with a stencil buffer. It will be a sw fallback, but some apps won't
+ * care about that.
+ */
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = 0;
+ stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+ depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
+ back_buffer_factor = (have_back_buffer) ? 3 : 1;
+
+ if ( pixel_bits == 16 ) {
+ fb_format = GL_RGB;
+ fb_type = GL_UNSIGNED_SHORT_5_6_5;
+ }
+ else {
+ fb_format = GL_BGRA;
+ fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ configs = driCreateConfigs(fb_format, fb_type,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor, back_buffer_modes,
+ back_buffer_factor);
+ if (configs == NULL) {
+ fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+ __LINE__);
+ return NULL;
+ }
-static struct __DriverAPIRec ffbAPI = {
- ffbInitDriver,
- ffbDestroyScreen,
- ffbCreateContext,
- ffbDestroyContext,
- ffbCreateBuffer,
- ffbDestroyBuffer,
- ffbSwapBuffers,
- ffbMakeCurrent,
- ffbUnbindContext
-};
+ /* Mark the visual as slow if there are "fake" stencil bits.
+ */
+ for (i = 0; configs[i]; i++) {
+ m = &configs[i]->modes;
+ if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
+ m->visualRating = GLX_SLOW_CONFIG;
+ }
+ }
+ return (const __DRIconfig **) configs;
+}
-/*
- * This is the bootstrap function for the driver.
- * The __driCreateScreen name is the symbol that libGL.so fetches.
- * Return: pointer to a __DRIscreenPrivate.
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * \todo maybe fold this into intelInitDriver
+ *
+ * \return the __GLcontextModes supported by this driver
*/
-void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
- int numConfigs, __GLXvisualConfig *config)
+static const __DRIconfig **
+ffbInitScreen(__DRIscreen *psp)
{
- __DRIscreenPrivate *psp;
- psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &ffbAPI);
- return (void *) psp;
+ static const __DRIversion ddx_expected = { 0, 1, 1 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 0, 0, 1 };
+
+ if ( ! driCheckDriDdxDrmVersions2( "ffb",
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
+ return NULL;
+
+ if (!ffbInitDriver(psp))
+ return NULL;
+
+ return ffbFillInModes( psp, 32, 16, 0, GL_TRUE );
}
+
+const struct __DriverAPIRec driDriverAPI = {
+ .InitScreen = ffbInitScreen,
+ .DestroyScreen = ffbDestroyScreen,
+ .CreateContext = ffbCreateContext,
+ .DestroyContext = ffbDestroyContext,
+ .CreateBuffer = ffbCreateBuffer,
+ .DestroyBuffer = ffbDestroyBuffer,
+ .SwapBuffers = ffbSwapBuffers,
+ .MakeCurrent = ffbMakeCurrent,
+ .UnbindContext = ffbUnbindContext,
+ .GetSwapInfo = NULL,
+ .GetDrawableMSC = NULL,
+ .WaitForMSC = NULL,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL
+};