mesa: standardize on C99's uint*_t instead of u_int*_t
[mesa.git] / src / mesa / drivers / dri / ffb / ffb_xmesa.c
index 4e38d0823738539c5f68c89615f976f11c8cd514..2a2cf5ec06a97f11019e766b713877053edba617 100644 (file)
  *    David S. Miller <davem@redhat.com>
  */
 
-#ifdef GLX_DIRECT_RENDERING
-
 #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)
@@ -76,59 +86,59 @@ ffbInitDriver(__DRIscreenPrivate *sPriv)
        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;
@@ -149,11 +159,11 @@ ffbDestroyScreen(__DRIscreenPrivate *sPriv)
        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);
 }
@@ -216,7 +226,7 @@ ffbCreateContext(const __GLcontextModes *mesaVis,
        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;
 
@@ -267,7 +277,7 @@ ffbCreateContext(const __GLcontextModes *mesaVis,
 
        /* Initialize the software rasterizer and helper modules. */
        _swrast_CreateContext( ctx );
-       _ac_CreateContext( ctx );
+       _vbo_CreateContext( ctx );
        _tnl_CreateContext( ctx );
        _swsetup_CreateContext( ctx );
 
@@ -278,9 +288,6 @@ ffbCreateContext(const __GLcontextModes *mesaVis,
        ffbDDExtensionsInit(ctx);
        ffbDDInitDriverFuncs(ctx);
        ffbDDInitStateFuncs(ctx);
-       ffbDDInitSpanFuncs(ctx);
-       ffbDDInitDepthFuncs(ctx);
-       ffbDDInitStencilFuncs(ctx);
        ffbDDInitRenderFuncs(ctx);
        /*ffbDDInitTexFuncs(ctx); not needed */
        ffbDDInitBitmapFuncs(ctx);
@@ -306,7 +313,7 @@ ffbDestroyContext(__DRIcontextPrivate *driContextPriv)
 
                _swsetup_DestroyContext( fmesa->glCtx );
                _tnl_DestroyContext( fmesa->glCtx );
-               _ac_DestroyContext( fmesa->glCtx );
+               _vbo_DestroyContext( fmesa->glCtx );
                _swrast_DestroyContext( fmesa->glCtx );
 
                 /* free the Mesa context */
@@ -324,16 +331,59 @@ ffbCreateBuffer(__DRIscreenPrivate *driScrnPriv,
                 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);
    }
 }
@@ -342,7 +392,7 @@ ffbCreateBuffer(__DRIscreenPrivate *driScrnPriv,
 static void
 ffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
 {
-   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
 }
 
 
@@ -490,7 +540,7 @@ ffbMakeCurrent(__DRIcontextPrivate *driContextPriv,
 
                fmesa->driDrawable = driDrawPriv;
 
-               _mesa_make_current2(fmesa->glCtx, 
+               _mesa_make_current(fmesa->glCtx, 
                            (GLframebuffer *) driDrawPriv->driverPrivate, 
                            (GLframebuffer *) driReadPriv->driverPrivate);
 
@@ -517,12 +567,11 @@ ffbMakeCurrent(__DRIcontextPrivate *driContextPriv,
                         * 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;
@@ -547,39 +596,123 @@ void ffbXMesaUpdateState(ffbContextPtr fmesa)
                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;
 
-#endif /* GLX_DIRECT_RENDERING */
+   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
+};