Drop fb, ffb and gamma dri drivers
[mesa.git] / src / mesa / drivers / dri / fb / fb_dri.c
diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c
deleted file mode 100644 (file)
index ac07e57..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.3
- *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* Minimal swrast-based dri loadable driver.
- *
- * Todo:
- *   -- Use malloced (rather than framebuffer) memory for backbuffer
- *   -- 32bpp is hardwared -- fix
- *
- * NOTES:
- *   -- No mechanism for cliprects or resize notification --
- *      assumes this is a fullscreen device.  
- *   -- No locking -- assumes this is the only driver accessing this 
- *      device.
- *   -- Doesn't (yet) make use of any acceleration or other interfaces
- *      provided by fb.  Would be entirely happy working against any 
- *     fullscreen interface.
- *   -- HOWEVER: only a small number of pixelformats are supported, and
- *      the mechanism for choosing between them makes some assumptions
- *      that may not be valid everywhere.
- */
-
-#include "driver.h"
-#include "drm.h"
-#include "utils.h"
-#include "drirenderbuffer.h"
-
-#include "buffers.h"
-#include "main/extensions.h"
-#include "main/framebuffer.h"
-#include "main/renderbuffer.h"
-#include "vbo/vbo.h"
-#include "swrast/swrast.h"
-#include "swrast_setup/swrast_setup.h"
-#include "tnl/tnl.h"
-#include "tnl/tcontext.h"
-#include "tnl/t_pipeline.h"
-#include "drivers/common/driverfuncs.h"
-
-void fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis);
-
-typedef struct {
-   GLcontext *glCtx;           /* Mesa context */
-
-   struct {
-      __DRIcontext *context;   
-      __DRIscreen *screen;     
-      __DRIdrawable *drawable; /* drawable bound to this ctx */
-   } dri;
-   
-} fbContext, *fbContextPtr;
-
-#define FB_CONTEXT(ctx)                ((fbContextPtr)(ctx->DriverCtx))
-
-
-static const GLubyte *
-get_string(GLcontext *ctx, GLenum pname)
-{
-   (void) ctx;
-   switch (pname) {
-      case GL_RENDERER:
-         return (const GLubyte *) "Mesa dumb framebuffer";
-      default:
-         return NULL;
-   }
-}
-
-
-static void
-update_state( GLcontext *ctx, GLuint new_state )
-{
-   /* not much to do here - pass it on */
-   _swrast_InvalidateState( ctx, new_state );
-   _swsetup_InvalidateState( ctx, new_state );
-   _vbo_InvalidateState( ctx, new_state );
-   _tnl_InvalidateState( ctx, new_state );
-}
-
-
-/**
- * Called by ctx->Driver.GetBufferSize from in core Mesa to query the
- * current framebuffer size.
- */
-static void
-get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   fbContextPtr fbmesa = FB_CONTEXT(ctx);
-
-   *width  = fbmesa->dri.drawable->w;
-   *height = fbmesa->dri.drawable->h;
-}
-
-
-static void
-updateFramebufferSize(GLcontext *ctx)
-{
-   fbContextPtr fbmesa = FB_CONTEXT(ctx);
-   struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
-   if (fbmesa->dri.drawable->w != fb->Width ||
-       fbmesa->dri.drawable->h != fb->Height) {
-      driUpdateFramebufferSize(ctx, fbmesa->dri.drawable);
-   }
-}
-
-static void
-viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
-{
-   /* XXX this should be called after we acquire the DRI lock, not here */
-   updateFramebufferSize(ctx);
-}
-
-
-static void
-init_core_functions( struct dd_function_table *functions )
-{
-   functions->GetString = get_string;
-   functions->UpdateState = update_state;
-   functions->GetBufferSize = get_buffer_size;
-   functions->Viewport = viewport;
-
-   functions->Clear = _swrast_Clear;  /* could accelerate with blits */
-}
-
-
-/*
- * Generate code for span functions.
- */
-
-/* 24-bit BGR */
-#define NAME(PREFIX) PREFIX##_B8G8R8
-#define FORMAT GL_RGBA8
-#define SPAN_VARS \
-   driRenderbuffer *drb = (driRenderbuffer *) rb;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 3;
-#define INC_PIXEL_PTR(P) P += 3
-#define STORE_PIXEL(DST, X, Y, VALUE) \
-   DST[0] = VALUE[BCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[2] = VALUE[RCOMP]
-#define FETCH_PIXEL(DST, SRC) \
-   DST[RCOMP] = SRC[2]; \
-   DST[GCOMP] = SRC[1]; \
-   DST[BCOMP] = SRC[0]; \
-   DST[ACOMP] = 0xff
-
-#include "swrast/s_spantemp.h"
-
-
-/* 32-bit BGRA */
-#define NAME(PREFIX) PREFIX##_B8G8R8A8
-#define FORMAT GL_RGBA8
-#define SPAN_VARS \
-   driRenderbuffer *drb = (driRenderbuffer *) rb;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 4;
-#define INC_PIXEL_PTR(P) P += 4
-#define STORE_PIXEL(DST, X, Y, VALUE) \
-   DST[0] = VALUE[BCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[2] = VALUE[RCOMP]; \
-   DST[3] = VALUE[ACOMP]
-#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
-   DST[0] = VALUE[BCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[2] = VALUE[RCOMP]; \
-   DST[3] = 0xff
-#define FETCH_PIXEL(DST, SRC) \
-   DST[RCOMP] = SRC[2]; \
-   DST[GCOMP] = SRC[1]; \
-   DST[BCOMP] = SRC[0]; \
-   DST[ACOMP] = SRC[3]
-
-#include "swrast/s_spantemp.h"
-
-
-/* 16-bit BGR (XXX implement dithering someday) */
-#define NAME(PREFIX) PREFIX##_B5G6R5
-#define FORMAT GL_RGBA8
-#define SPAN_VARS \
-   driRenderbuffer *drb = (driRenderbuffer *) rb;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
-#define INC_PIXEL_PTR(P) P += 1
-#define STORE_PIXEL(DST, X, Y, VALUE) \
-   DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
-#define FETCH_PIXEL(DST, SRC) \
-   DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
-   DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >>  5) & 0x3) ); \
-   DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
-   DST[ACOMP] = 0xff
-
-#include "swrast/s_spantemp.h"
-
-
-/* 15-bit BGR (XXX implement dithering someday) */
-#define NAME(PREFIX) PREFIX##_B5G5R5
-#define FORMAT GL_RGBA8
-#define SPAN_VARS \
-   driRenderbuffer *drb = (driRenderbuffer *) rb;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
-#define INC_PIXEL_PTR(P) P += 1
-#define STORE_PIXEL(DST, X, Y, VALUE) \
-   DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
-#define FETCH_PIXEL(DST, SRC) \
-   DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
-   DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >>  5) & 0x7) ); \
-   DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
-   DST[ACOMP] = 0xff
-
-#include "swrast/s_spantemp.h"
-
-
-/* 8-bit color index */
-#define NAME(PREFIX) PREFIX##_CI8
-#define FORMAT GL_COLOR_INDEX8_EXT
-#define SPAN_VARS \
-   driRenderbuffer *drb = (driRenderbuffer *) rb;
-#define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X);
-#define INC_PIXEL_PTR(P) P += 1
-#define STORE_PIXEL(DST, X, Y, VALUE) \
-   *DST = VALUE[0]
-#define FETCH_PIXEL(DST, SRC) \
-   DST = SRC[0]
-
-#include "swrast/s_spantemp.h"
-
-
-
-void
-fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
-{
-   ASSERT(drb->Base.InternalFormat == GL_RGBA);
-   if (drb->Base.InternalFormat == GL_RGBA) {
-      if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
-         drb->Base.GetRow = get_row_B5G6R5;
-         drb->Base.GetValues = get_values_B5G6R5;
-         drb->Base.PutRow = put_row_B5G6R5;
-         drb->Base.PutMonoRow = put_mono_row_B5G6R5;
-         drb->Base.PutRowRGB = put_row_rgb_B5G6R5;
-         drb->Base.PutValues = put_values_B5G6R5;
-         drb->Base.PutMonoValues = put_mono_values_B5G6R5;
-      }
-      else if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
-         drb->Base.GetRow = get_row_B5G5R5;
-         drb->Base.GetValues = get_values_B5G5R5;
-         drb->Base.PutRow = put_row_B5G5R5;
-         drb->Base.PutMonoRow = put_mono_row_B5G5R5;
-         drb->Base.PutRowRGB = put_row_rgb_B5G5R5;
-         drb->Base.PutValues = put_values_B5G5R5;
-         drb->Base.PutMonoValues = put_mono_values_B5G5R5;
-      }
-      else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
-               && vis->alphaBits == 8) {
-         drb->Base.GetRow = get_row_B8G8R8A8;
-         drb->Base.GetValues = get_values_B8G8R8A8;
-         drb->Base.PutRow = put_row_B8G8R8A8;
-         drb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
-         drb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
-         drb->Base.PutValues = put_values_B8G8R8A8;
-         drb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
-      }
-      else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
-               && vis->alphaBits == 0) {
-         drb->Base.GetRow = get_row_B8G8R8;
-         drb->Base.GetValues = get_values_B8G8R8;
-         drb->Base.PutRow = put_row_B8G8R8;
-         drb->Base.PutMonoRow = put_mono_row_B8G8R8;
-         drb->Base.PutRowRGB = put_row_rgb_B8G8R8;
-         drb->Base.PutValues = put_values_B8G8R8;
-         drb->Base.PutMonoValues = put_mono_values_B8G8R8;
-      }
-      else if (vis->indexBits == 8) {
-         drb->Base.GetRow = get_row_CI8;
-         drb->Base.GetValues = get_values_CI8;
-         drb->Base.PutRow = put_row_CI8;
-         drb->Base.PutMonoRow = put_mono_row_CI8;
-         drb->Base.PutValues = put_values_CI8;
-         drb->Base.PutMonoValues = put_mono_values_CI8;
-      }
-   }
-   else {
-      /* hardware z/stencil/etc someday */
-   }
-}
-
-
-
-/* Initialize the driver specific screen private data.
- */
-static GLboolean
-fbInitDriver( __DRIscreen *sPriv )
-{
-   sPriv->private = NULL;
-   return GL_TRUE;
-}
-
-static void
-fbDestroyScreen( __DRIscreen *sPriv )
-{
-}
-
-
-/* Create the device specific context.
- */
-static GLboolean
-fbCreateContext( const __GLcontextModes *glVisual,
-                __DRIcontext *driContextPriv,
-                void *sharedContextPrivate)
-{
-   fbContextPtr fbmesa;
-   GLcontext *ctx, *shareCtx;
-   struct dd_function_table functions;
-
-   assert(glVisual);
-   assert(driContextPriv);
-
-   /* Allocate the Fb context */
-   fbmesa = (fbContextPtr) calloc(1,  sizeof(*fbmesa) );
-   if ( !fbmesa )
-      return GL_FALSE;
-
-   /* Init default driver functions then plug in our FBdev-specific functions
-    */
-   _mesa_init_driver_functions(&functions);
-   init_core_functions(&functions);
-
-   /* Allocate the Mesa context */
-   if (sharedContextPrivate)
-      shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx;
-   else
-      shareCtx = NULL;
-
-   ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx, 
-                                             &functions, (void *) fbmesa);
-   if (!fbmesa->glCtx) {
-      free(fbmesa);
-      return GL_FALSE;
-   }
-   driContextPriv->driverPrivate = fbmesa;
-
-   /* Create module contexts */
-   _swrast_CreateContext( ctx );
-   _vbo_CreateContext( ctx );
-   _tnl_CreateContext( ctx );
-   _swsetup_CreateContext( ctx );
-   _swsetup_Wakeup( ctx );
-
-
-   /* use default TCL pipeline */
-   {
-      TNLcontext *tnl = TNL_CONTEXT(ctx);
-      tnl->Driver.RunPipeline = _tnl_run_pipeline;
-   }
-
-   _mesa_enable_sw_extensions(ctx);
-
-   return GL_TRUE;
-}
-
-
-static void
-fbDestroyContext( __DRIcontext *driContextPriv )
-{
-   GET_CURRENT_CONTEXT(ctx);
-   fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate;
-   fbContextPtr current = ctx ? FB_CONTEXT(ctx) : NULL;
-
-   /* check if we're deleting the currently bound context */
-   if (fbmesa == current) {
-      _mesa_make_current(NULL, NULL, NULL);
-   }
-
-   /* Free fb context resources */
-   if ( fbmesa ) {
-      _swsetup_DestroyContext( fbmesa->glCtx );
-      _tnl_DestroyContext( fbmesa->glCtx );
-      _vbo_DestroyContext( fbmesa->glCtx );
-      _swrast_DestroyContext( fbmesa->glCtx );
-
-      /* free the Mesa context */
-      fbmesa->glCtx->DriverCtx = NULL;
-      _mesa_destroy_context( fbmesa->glCtx );
-
-      free( fbmesa );
-   }
-}
-
-
-/* Create and initialize the Mesa and driver specific pixmap buffer
- * data.
- */
-static GLboolean
-fbCreateBuffer( __DRIscreen *driScrnPriv,
-               __DRIdrawable *driDrawPriv,
-               const __GLcontextModes *mesaVis,
-               GLboolean isPixmap )
-{
-   struct gl_framebuffer *mesa_framebuffer;
-   
-   if (isPixmap) {
-      return GL_FALSE; /* not implemented */
-   }
-   else {
-      const GLboolean swDepth = mesaVis->depthBits > 0;
-      const GLboolean swAlpha = mesaVis->alphaBits > 0;
-      const GLboolean swAccum = mesaVis->accumRedBits > 0;
-      const GLboolean swStencil = mesaVis->stencilBits > 0;
-      
-      mesa_framebuffer = _mesa_create_framebuffer(mesaVis);
-      if (!mesa_framebuffer)
-         return 0;
-
-      /* XXX double-check these parameters (bpp vs cpp, etc) */
-      {
-         driRenderbuffer *drb = driNewRenderbuffer(MESA_FORMAT_ARGB8888,
-                                                   driScrnPriv->pFB,
-                                                   driScrnPriv->fbBPP / 8,
-                                                   driScrnPriv->fbOrigin,
-                                                   driScrnPriv->fbStride,
-                                                   driDrawPriv);
-         fbSetSpanFunctions(drb, mesaVis);
-         _mesa_add_renderbuffer(mesa_framebuffer,
-                                BUFFER_FRONT_LEFT, &drb->Base);
-      }
-      if (mesaVis->doubleBufferMode) {
-         /* XXX what are the correct origin/stride values? */
-         GLvoid *backBuf = malloc(driScrnPriv->fbStride
-                                        * driScrnPriv->fbHeight);
-         driRenderbuffer *drb = driNewRenderbuffer(MESA_FORMAT_ARGB8888,
-                                                   backBuf,
-                                                   driScrnPriv->fbBPP /8,
-                                                   driScrnPriv->fbOrigin,
-                                                   driScrnPriv->fbStride,
-                                                   driDrawPriv);
-         fbSetSpanFunctions(drb, mesaVis);
-         _mesa_add_renderbuffer(mesa_framebuffer,
-                                BUFFER_BACK_LEFT, &drb->Base);
-      }
-
-      _mesa_add_soft_renderbuffers(mesa_framebuffer,
-                                   GL_FALSE, /* color */
-                                   swDepth,
-                                   swStencil,
-                                   swAccum,
-                                   swAlpha, /* or always zero? */
-                                   GL_FALSE /* aux */);
-      
-      driDrawPriv->driverPrivate = mesa_framebuffer;
-
-      return 1;
-   }
-}
-
-
-static void
-fbDestroyBuffer(__DRIdrawable *driDrawPriv)
-{
-   _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
-}
-
-
-
-/* If the backbuffer is on a videocard, this is extraordinarily slow!
- */
-static void
-fbSwapBuffers( __DRIdrawable *dPriv )
-{
-   struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate;
-   struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
-   void *frontBuffer = front_renderbuffer->Data;
-   int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
-   void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;
-
-   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
-      fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate;
-      GLcontext *ctx = fbmesa->glCtx;
-      
-      if (ctx->Visual.doubleBufferMode) {
-        int i;
-        int offset = 0;
-         char *tmp = malloc(currentPitch);
-
-         _mesa_notifySwapBuffers( ctx );  /* flush pending rendering comands */
-
-         ASSERT(frontBuffer);
-         ASSERT(backBuffer);
-
-        for (i = 0; i < dPriv->h; i++) {
-            memcpy(tmp, (char *) backBuffer + offset, currentPitch);
-            memcpy((char *) frontBuffer + offset, tmp, currentPitch);
-            offset += currentPitch;
-        }
-           
-        free(tmp);
-      }
-   }
-   else {
-      /* XXX this shouldn't be an error but we can't handle it for now */
-      _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
-   }
-}
-
-
-/* Force the context `c' to be the current context and associate with it
- * buffer `b'.
- */
-static GLboolean
-fbMakeCurrent( __DRIcontext *driContextPriv,
-              __DRIdrawable *driDrawPriv,
-              __DRIdrawable *driReadPriv )
-{
-   if ( driContextPriv ) {
-      fbContextPtr newFbCtx = 
-            (fbContextPtr) driContextPriv->driverPrivate;
-
-      newFbCtx->dri.drawable = driDrawPriv;
-
-      _mesa_make_current( newFbCtx->glCtx, 
-                           driDrawPriv->driverPrivate,
-                           driReadPriv->driverPrivate);
-   } else {
-      _mesa_make_current( NULL, NULL, NULL );
-   }
-
-   return GL_TRUE;
-}
-
-
-/* Force the context `c' to be unbound from its buffer.
- */
-static GLboolean
-fbUnbindContext( __DRIcontext *driContextPriv )
-{
-   return GL_TRUE;
-}
-
-static struct __DriverAPIRec fbAPI = {
-   .InitDriver      = fbInitDriver,
-   .DestroyScreen   = fbDestroyScreen,
-   .CreateContext   = fbCreateContext,
-   .DestroyContext  = fbDestroyContext,
-   .CreateBuffer    = fbCreateBuffer,
-   .DestroyBuffer   = fbDestroyBuffer,
-   .SwapBuffers     = fbSwapBuffers,
-   .MakeCurrent     = fbMakeCurrent,
-   .UnbindContext   = fbUnbindContext,
-};
-
-
-
-static int
-__driValidateMode(const DRIDriverContext *ctx )
-{
-   return 1;
-}
-
-static int
-__driInitFBDev( struct DRIDriverContextRec *ctx )
-{
-   /* Note that drmOpen will try to load the kernel module, if needed. */
-   /* we need a fbdev drm driver - it will only track maps */
-   ctx->drmFD = drmOpen("radeon", NULL );
-   if (ctx->drmFD < 0) {
-      fprintf(stderr, "[drm] drmOpen failed\n");
-      return 0;
-   }
-
-   ctx->shared.SAREASize = SAREA_MAX;
-
-   if (drmAddMap( ctx->drmFD,
-       0,
-       ctx->shared.SAREASize,
-       DRM_SHM,
-       DRM_CONTAINS_LOCK,
-       &ctx->shared.hSAREA) < 0)
-   {
-      fprintf(stderr, "[drm] drmAddMap failed\n");
-      return 0;
-   }
-   fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
-           ctx->shared.SAREASize,
-           (unsigned long) ctx->shared.hSAREA);
-
-   if (drmMap( ctx->drmFD,
-       ctx->shared.hSAREA,
-       ctx->shared.SAREASize,
-       (drmAddressPtr)(&ctx->pSAREA)) < 0)
-   {
-      fprintf(stderr, "[drm] drmMap failed\n");
-      return 0;
-   }
-   memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
-   fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
-           (unsigned long) ctx->shared.hSAREA, ctx->pSAREA,
-           ctx->shared.SAREASize);
-   
-   /* Need to AddMap the framebuffer and mmio regions here:
-   */
-   if (drmAddMap( ctx->drmFD,
-       (drm_handle_t)ctx->FBStart,
-       ctx->FBSize,
-       DRM_FRAME_BUFFER,
-#ifndef _EMBEDDED
-                 0,
-#else
-                 DRM_READ_ONLY,
-#endif
-                 &ctx->shared.hFrameBuffer) < 0)
-   {
-      fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
-      return 0;
-   }
-
-   fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
-           (unsigned long) ctx->shared.hFrameBuffer);
-
-   return 1;
-}
-
-static void
-__driHaltFBDev( struct DRIDriverContextRec *ctx )
-{
-}
-
-struct DRIDriverRec __driDriver = {
-   __driValidateMode,
-   __driValidateMode,
-   __driInitFBDev,
-   __driHaltFBDev
-};
-
-static __GLcontextModes *
-fbFillInModes( __DRIscreen *psp,
-              unsigned pixel_bits, unsigned depth_bits,
-              unsigned stencil_bits, GLboolean have_back_buffer )
-{
-   __GLcontextModes * modes;
-   __GLcontextModes * m;
-   unsigned num_modes;
-   unsigned depth_buffer_factor;
-   unsigned back_buffer_factor;
-   GLenum fb_format;
-   GLenum fb_type;
-
-    /* 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.
-    */
-   static const GLenum back_buffer_modes[] = {
-      GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
-   };
-
-   uint8_t depth_bits_array[2];
-   uint8_t stencil_bits_array[2];
-
-
-   depth_bits_array[0] = depth_bits;
-   depth_bits_array[1] = 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] = (stencil_bits == 0) ? 8 : stencil_bits;
-
-   depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
-   back_buffer_factor  = (have_back_buffer) ? 2 : 1;
-
-   num_modes = depth_buffer_factor * back_buffer_factor * 4;
-
-   if ( pixel_bits == 16 ) {
-      fb_format = GL_RGB;
-      fb_type = GL_UNSIGNED_SHORT_5_6_5;
-   }
-   else {
-      fb_format = GL_RGBA;
-      fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
-   }
-
-   modes = (*psp->contextModes->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
-   m = modes;
-   if ( ! driFillInModes( & m, fb_format, fb_type,
-          depth_bits_array, stencil_bits_array, depth_buffer_factor,
-          back_buffer_modes, back_buffer_factor,
-          GLX_TRUE_COLOR ) ) {
-             fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
-                      __func__, __LINE__ );
-             return NULL;
-          }
-
-          if ( ! driFillInModes( & m, fb_format, fb_type,
-                 depth_bits_array, stencil_bits_array, depth_buffer_factor,
-                 back_buffer_modes, back_buffer_factor,
-                 GLX_DIRECT_COLOR ) ) {
-                    fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
-                             __func__, __LINE__ );
-                    return NULL;
-                 }
-
-    /* Mark the visual as slow if there are "fake" stencil bits.
-    */
-                 for ( m = modes ; m != NULL ; m = m->next ) {
-                    if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
-                       m->visualRating = GLX_SLOW_CONFIG;
-                    }
-                 }
-
-                 return modes;
-}
-
-
-/**
- * This is the bootstrap function for the driver.  libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
- * 
- * \return A pointer to a \c __DRIscreen on success, or \c NULL on 
- *         failure.
- */
-PUBLIC
-void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
-                                   const __GLcontextModes * modes,
-                                   const __DRIversion * ddx_version,
-                                   const __DRIversion * dri_version,
-                                   const __DRIversion * drm_version,
-                                   const __DRIframebuffer * frame_buffer,
-                                   drmAddress pSAREA, int fd, 
-                                   int internal_api_version,
-                                   __GLcontextModes ** driver_modes )
-{
-   __DRIscreen *psp;
-   static const __DRIversion ddx_expected = { 4, 0, 0 };
-   static const __DRIversion dri_expected = { 4, 0, 0 };
-   static const __DRIversion drm_expected = { 1, 5, 0 };
-
-
-   if ( ! driCheckDriDdxDrmVersions2( "fb",
-          dri_version, & dri_expected,
-          ddx_version, & ddx_expected,
-          drm_version, & drm_expected ) ) {
-             return NULL;
-          }
-      
-          psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
-                                         ddx_version, dri_version, drm_version,
-                                         frame_buffer, pSAREA, fd,
-                                         internal_api_version, &fbAPI);
-          if ( psp != NULL ) {
-            *driver_modes = fbFillInModes( psp, psp->fbBPP,
-                                           (psp->fbBPP == 16) ? 16 : 24,
-                                           (psp->fbBPP == 16) ? 0  : 8,
-                                           1);
-          }
-
-          return (void *) psp;
-}
-
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
-    &driCoreExtension.base,
-    &driLegacyExtension.base,
-    NULL
-};