Merge commit 'origin/gallium-0.1'
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_screen.c
index 72e8d12677326abab59187c06f9bff9f4d72f60c..5f2f5cfff5179cbe03c37ad15cda0d739e71291d 100644 (file)
@@ -23,7 +23,6 @@
  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_screen.c,v 1.3 2002/02/22 21:45:03 dawes Exp $ */
 
 /*
  * Original rewrite:
 #include "tdfx_context.h"
 #include "tdfx_lock.h"
 #include "tdfx_vb.h"
+#include "tdfx_span.h"
 #include "tdfx_tris.h"
-#include "utils.h"
 
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "xmlpool.h"
+
+#include "utils.h"
 
 #ifdef DEBUG_LOCKING
 char *prevLockFile = 0;
@@ -48,18 +52,25 @@ int prevLockLine = 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,
+    NULL
+};
+
+static const GLuint __driNConfigOptions = 1;
 
+extern const struct dri_extension card_extensions[];
+extern const struct dri_extension napalm_extensions[];
 
 static GLboolean
 tdfxCreateScreen( __DRIscreenPrivate *sPriv )
@@ -67,11 +78,20 @@ 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;
 
@@ -97,6 +117,8 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv )
       return GL_FALSE;
    }
 
+   sPriv->extensions = tdfxExtensions;
+
    return GL_TRUE;
 }
 
@@ -106,12 +128,16 @@ tdfxDestroyScreen( __DRIscreenPrivate *sPriv )
 {
    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;
 }
 
 
@@ -137,16 +163,67 @@ tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv,
                   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);
    }
 }
@@ -155,7 +232,7 @@ tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv,
 static void
 tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
 {
-   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
+   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
 }
 
 
@@ -195,7 +272,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
             return;
         LOCK_HARDWARE( fxMesa );
         fxMesa->Glide.grSstSelect( fxMesa->Glide.Board );
+#ifdef DEBUG
          printf("SwapBuf SetState 1\n");
+#endif
         fxMesa->Glide.grGlideSetState(fxMesa->Glide.State );
       }
    }
@@ -255,49 +334,23 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
       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 const struct __DriverAPIRec tdfxAPI = {
-   .InitDriver      = tdfxInitDriver,
-   .DestroyScreen   = tdfxDestroyScreen,
-   .CreateContext   = tdfxCreateContext,
-   .DestroyContext  = tdfxDestroyContext,
-   .CreateBuffer    = tdfxCreateBuffer,
-   .DestroyBuffer   = tdfxDestroyBuffer,
-   .SwapBuffers     = tdfxSwapBuffers,
-   .MakeCurrent     = tdfxMakeCurrent,
-   .UnbindContext   = tdfxUnbindContext,
-   .GetSwapInfo     = NULL,
-   .GetMSC          = NULL,
-   .WaitForMSC      = NULL,
-   .WaitForSBC      = NULL,
-   .SwapBuffersMSC  = NULL
-};
-
-#ifdef USE_NEW_INTERFACE
-/*
- * new interface code, derived from radeon_screen.c
- * XXX this may still be wrong
- */
-static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
-
-static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits,
-                                        unsigned depth_bits,
-                                        unsigned stencil_bits,
-                                        GLboolean have_back_buffer)
+static const __DRIconfig **
+tdfxFillInModes(__DRIscreenPrivate *psp,
+               unsigned pixel_bits,
+               unsigned depth_bits,
+               unsigned stencil_bits,
+               GLboolean have_back_buffer)
 {
-       __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
@@ -305,136 +358,101 @@ static __GLcontextModes *tdfxFillInModes(unsigned pixel_bits,
         * will never be used.
         */
 
-       num_modes = (depth_bits == 16) ? 32 : 16;
-
-       modes = (*create_context_modes)(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 ? 16 : 0;
-                           m->stencilBits      = stencil ? 8 : 0;
-                           m->depthBits        = deep
-                                                 ? (depth ? 24 : 0)
-                                                 : (depth ? 0 : depth_bits);
-                           m->visualType       = i ? GLX_TRUE_COLOR
-                                                   : GLX_DIRECT_COLOR;
-                           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;
-                       }
-                   }
-               }
-           }
+       static const GLenum db_modes[2] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML };
+       uint8_t depth_bits_array[4];
+       uint8_t stencil_bits_array[4];
+        uint8_t msaa_samples_array[1];
+       if(deep) {
+               depth_bits_array[0] = 0;
+               depth_bits_array[1] = 24;
+               stencil_bits_array[0] = 0;
+               stencil_bits_array[1] = 8;
+       } else {
+               depth_bits_array[0] = depth_bits;
+               depth_bits_array[1] = 0;
+               depth_bits_array[2] = depth_bits;
+               depth_bits_array[3] = 0;
+               stencil_bits_array[0] = 0;
+               stencil_bits_array[1] = 0;
+               stencil_bits_array[2] = 8;
+               stencil_bits_array[3] = 8;
        }
 
-       return modes;
+       msaa_samples_array[0] = 0;
+
+       return (const __DRIconfig **)
+          driCreateConfigs(deep ? GL_RGBA : GL_RGB,
+                           deep ? GL_UNSIGNED_INT_8_8_8_8 :
+                                  GL_UNSIGNED_SHORT_5_6_5,
+                           depth_bits_array,
+                           stencil_bits_array,
+                           deep ? 2 : 4,
+                           db_modes, 2,
+                           msaa_samples_array, 1);
 }
 
 /**
- * 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.
+ * This is the driver specific part of the createNewScreen entry point.
+ * 
+ * \todo maybe fold this into intelInitDriver
  *
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- *         failure.
+ * \return the __GLcontextModes supported by this driver
  */
-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 )
+static const __DRIconfig **
+tdfxInitScreen(__DRIscreen *psp)
 {
-   __DRIscreenPrivate *psp;
-   static const __DRIversion ddx_expected = { 1, 0, 0 };
+   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",
-                                     dri_version, & dri_expected,
-                                     ddx_version, & ddx_expected,
-                                     drm_version, & drm_expected ) ) {
+                                     &psp->dri_version, & dri_expected,
+                                     &psp->ddx_version, & ddx_expected,
+                                     &psp->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, &tdfxAPI);
-
-   create_context_modes = (PFNGLXCREATECONTEXTMODES)
-      glXGetProcAddress((const GLubyte *)"__glXCreateContextModes");
-      
-   if (create_context_modes != NULL) {
-      /* divined from tdfx_dri.c, sketchy */
-      TDFXDRIPtr dri_priv = (TDFXDRIPtr) psp->pDevPriv;
-      int bpp = (dri_priv->cpp > 2) ? 24 : 16;
+   /* 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 );
 
-      /* XXX i wish it was like this */
-      /* bpp = dri_priv->bpp */
+   if (!tdfxInitDriver(psp))
+      return NULL;
       
-      *driver_modes = tdfxFillInModes(bpp, (bpp == 16) ? 16 : 24,
-                               (bpp == 16) ? 0 : 8,
-                               (dri_priv->backOffset!=dri_priv->depthOffset));
-   }
-
-   return (void *)psp;
+   return tdfxFillInModes(psp,
+                         bpp, (bpp == 16) ? 16 : 24,
+                         (bpp == 16) ? 0 : 8,
+                         (dri_priv->backOffset!=dri_priv->depthOffset));
 }
-#endif /* USE_NEW_INTERFACE */
-
 
-/*
- * This is the bootstrap function for the driver.
- * The __driCreateScreen name is the symbol that libGL.so fetches.
- * Return:  pointer to a __DRIscreenPrivate.
- */
-#if !defined(DRI_NEW_INTERFACE_ONLY)
-#ifndef _SOLO
-void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
-                        int numConfigs, __GLXvisualConfig *config)
-{
-   __DRIscreenPrivate *psp;
-   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &tdfxAPI);
-   return (void *) psp;
-}
-#else
-void *__driCreateScreen(struct DRIDriverRec *driver,
-                        struct DRIDriverContextRec *driverContext)
-{
-   __DRIscreenPrivate *psp;
-   psp = __driUtilCreateScreen(driver, driverContext, &tdfxAPI);
-   return (void *) psp;
-}
-#endif
-#endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
+const struct __DriverAPIRec driDriverAPI = {
+   .InitScreen      = tdfxInitScreen,
+   .DestroyScreen   = tdfxDestroyScreen,
+   .CreateContext   = tdfxCreateContext,
+   .DestroyContext  = tdfxDestroyContext,
+   .CreateBuffer    = tdfxCreateBuffer,
+   .DestroyBuffer   = tdfxDestroyBuffer,
+   .SwapBuffers     = tdfxSwapBuffers,
+   .MakeCurrent     = tdfxMakeCurrent,
+   .UnbindContext   = tdfxUnbindContext,
+   .GetSwapInfo     = NULL,
+   .GetDrawableMSC  = NULL,
+   .WaitForMSC      = NULL,
+   .WaitForSBC      = NULL,
+   .SwapBuffersMSC  = NULL
+};