fix some float/ubyte mistakes (Daniel Borca)
[mesa.git] / src / mesa / drivers / glide / fxdd.c
index d18c34a32af7f50b9e7566c21cc259df649e38f5..fd099e7e1153c25896cb9067a38808b42353b13c 100644 (file)
@@ -1,9 +1,10 @@
+/* $Id: fxdd.c,v 1.95 2003/01/08 21:32:36 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.3
+ * Version:  4.0
  *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2001  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"),
  * 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.
- *
- *
- * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
- * terms stated above.
- *
- * Thank you for your contribution, David!
- *
- * Please make note of the above copyright/license statement.  If you
- * contributed code or bug fixes to this code under the previous (GNU
- * Library) license and object to the new license, your code will be
- * removed at your request.  Please see the Mesa docs/COPYRIGHT file
- * for more information.
- *
- * Additional Mesa/3Dfx driver developers:
- *   Daryll Strauss <daryll@precisioninsight.com>
- *   Keith Whitwell <keith@precisioninsight.com>
- *
- * See fxapi.h for more revision/author details.
  */
 
+/* Authors:
+ *    David Bucciarelli
+ *    Brian Paul
+ *    Daryll Strauss
+ *    Keith Whitwell
+ */
 
 /* fxdd.c - 3Dfx VooDoo Mesa device driver functions */
 
@@ -56,6 +45,7 @@
 #include "fxdrv.h"
 #include "enums.h"
 #include "extensions.h"
+#include "mmath.h"
 #include "texstore.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
@@ -114,38 +104,45 @@ fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder)
 
 /* Return buffer size information */
 static void
-fxDDBufferSize(GLcontext * ctx, GLuint * width, GLuint * height)
+fxDDBufferSize(GLframebuffer *buffer, GLuint * width, GLuint * height)
 {
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   GET_CURRENT_CONTEXT(ctx);
+   if (ctx && ctx->DriverCtx) {
+      fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
 
-   if (MESA_VERBOSE & VERBOSE_DRIVER) {
-      fprintf(stderr, "fxmesa: fxDDBufferSize(...) Start\n");
-   }
+      if (MESA_VERBOSE & VERBOSE_DRIVER) {
+         fprintf(stderr, "fxmesa: fxDDBufferSize(...) Start\n");
+      }
 
-   *width = fxMesa->width;
-   *height = fxMesa->height;
+      *width = fxMesa->width;
+      *height = fxMesa->height;
 
-   if (MESA_VERBOSE & VERBOSE_DRIVER) {
-      fprintf(stderr, "fxmesa: fxDDBufferSize(...) End\n");
+      if (MESA_VERBOSE & VERBOSE_DRIVER) {
+         fprintf(stderr, "fxmesa: fxDDBufferSize(...) End\n");
+      }
    }
 }
 
 
 /* Implements glClearColor() */
 static void
-fxDDClearColor(GLcontext * ctx, const GLchan color[4])
+fxDDClearColor(GLcontext * ctx, const GLfloat color[4])
 {
    fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
    GLubyte col[4];
 
    if (MESA_VERBOSE & VERBOSE_DRIVER) {
-      fprintf(stderr, "fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",
+      fprintf(stderr, "fxmesa: fxDDClearColor(%f,%f,%f,%f)\n",
              color[0], color[1], color[2], color[3]);
    }
 
-   ASSIGN_4V(col, color[0], color[1], color[2], 255);
+   CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
+   CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
+   CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
+   CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);
+
    fxMesa->clearC = FXCOLOR4(col);
-   fxMesa->clearA = color[3];
+   fxMesa->clearA = col[3];
 }
 
 
@@ -253,7 +250,7 @@ fxDDClear(GLcontext * ctx, GLbitfield mask, GLboolean all,
       FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
       FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP]
                     && fxMesa->haveAlphaBuffer);
-      if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT)
+      if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
         FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
       if (!ctx->Depth.Test || !ctx->Depth.Mask)
         FX_grDepthMask(FXFALSE);
@@ -272,7 +269,7 @@ fxDDClear(GLcontext * ctx, GLbitfield mask, GLboolean all,
 
 /* Set the buffer used for drawing */
 /* XXX support for separate read/draw buffers hasn't been tested */
-static GLboolean
+static void
 fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
 {
    fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
@@ -284,20 +281,21 @@ fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
    if (mode == GL_FRONT_LEFT) {
       fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
       FX_grRenderBuffer(fxMesa->currentFB);
-      return GL_TRUE;
    }
    else if (mode == GL_BACK_LEFT) {
       fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
       FX_grRenderBuffer(fxMesa->currentFB);
-      return GL_TRUE;
    }
    else if (mode == GL_NONE) {
       FX_grColorMask(FXFALSE, FXFALSE);
-      return GL_TRUE;
    }
    else {
-      return GL_FALSE;
+      /* we'll need a software fallback */
+      /* XXX not implemented */
    }
+
+   /* update s/w fallback state */
+   _swrast_DrawBuffer(ctx, mode);
 }
 
 
@@ -325,7 +323,9 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
        ctx->Stencil.Enabled ||
        ctx->Scissor.Enabled ||
        (ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
-       ctx->Color.ColorMask[ACOMP]) || ctx->Color.MultiDrawBuffer) {
+       ctx->Color.ColorMask[ACOMP]) ||
+       (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
+        ctx->Color._DrawDestMask != BACK_LEFT_BIT)) {
       _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
       return;
    }
@@ -657,28 +657,16 @@ int
 fxDDInitFxMesaContext(fxMesaContext fxMesa)
 {
    int i;
-   static int firsttime = 1;
 
    for (i = 0; i < 256; i++) {
       gl_ubyte_to_float_255_color_tab[i] = (float) i;
    }
 
-   if (firsttime) {
-      fxDDSetupInit();
-      fxDDTrifuncInit();
-      firsttime = 0;
-   }
-
    FX_setupGrVertexLayout();
 
    if (getenv("FX_EMULATE_SINGLE_TMU"))
       fxMesa->haveTwoTMUs = GL_FALSE;
 
-   fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs;
-
-   if (!getenv("FX_DONT_FAKE_MULTITEX"))
-      fxMesa->emulateTwoTMUs = GL_TRUE;
-
    if (getenv("FX_GLIDE_SWAPINTERVAL"))
       fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
    else
@@ -711,7 +699,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxMesa->unitsState.alphaTestEnabled = GL_FALSE;
    fxMesa->unitsState.alphaTestFunc = GR_CMP_ALWAYS;
-   fxMesa->unitsState.alphaTestRefValue = 0;
+   fxMesa->unitsState.alphaTestRefValue = 0.0;
 
    fxMesa->unitsState.blendEnabled = GL_FALSE;
    fxMesa->unitsState.blendSrcFuncRGB = GR_BLEND_ONE;
@@ -734,7 +722,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
    }
 
    fxMesa->state = malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE));
-   fxMesa->fogTable = malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES) *
+   fxMesa->fogTable = (GrFog_t *) malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES) *
                             sizeof(GrFog_t));
 
    if (!fxMesa->state || !fxMesa->fogTable) {
@@ -754,8 +742,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxMesa->textureAlign = FX_grGetInteger(FX_TEXTURE_ALIGN);
    fxMesa->glCtx->Const.MaxTextureLevels = 9;
-   fxMesa->glCtx->Const.MaxTextureSize = 256;
-   fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->emulateTwoTMUs ? 2 : 1;
+   fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->haveTwoTMUs ? 2 : 1;
    fxMesa->new_state = _NEW_ALL;
 
    /* Initialize the software rasterizer and helper modules.
@@ -771,6 +758,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
    fxAllocVB(fxMesa->glCtx);
 
    fxSetupDDPointers(fxMesa->glCtx);
+   fxDDInitTriFuncs(fxMesa->glCtx);
 
    /* Tell the software rasterizer to use pixel fog always.
     */
@@ -784,15 +772,8 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxDDInitExtensions(fxMesa->glCtx);
 
-#ifdef FXVTXFMT
-   fxDDInitVtxfmt(fxMesa->glCtx);
-#endif
-
    FX_grGlideGetState((GrState *) fxMesa->state);
 
-   /* Run the config file */
-   _mesa_context_initialize(fxMesa->glCtx);
-
    return 1;
 }
 
@@ -831,7 +812,7 @@ fxDDInitExtensions(GLcontext * ctx)
    if (fxMesa->haveTwoTMUs)
       _mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
 
-   if (fxMesa->emulateTwoTMUs)
+   if (fxMesa->haveTwoTMUs)
       _mesa_enable_extension(ctx, "GL_ARB_multitexture");
 }
 
@@ -844,8 +825,8 @@ fxDDInitExtensions(GLcontext * ctx)
  *
  * Performs similar work to fxDDChooseRenderState() - should be merged.
  */
-static GLboolean
-fxIsInHardware(GLcontext * ctx)
+GLboolean
+fx_check_IsInHardware(GLcontext * ctx)
 {
    fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
 
@@ -853,7 +834,8 @@ fxIsInHardware(GLcontext * ctx)
       return GL_FALSE;
 
    if (ctx->Stencil.Enabled ||
-       ctx->Color.MultiDrawBuffer ||
+       (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
+        ctx->Color._DrawDestMask != BACK_LEFT_BIT) ||
        ((ctx->Color.BlendEnabled)
        && (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT))
        || ((ctx->Color.ColorLogicOpEnabled)
@@ -869,15 +851,16 @@ fxIsInHardware(GLcontext * ctx)
    }
    /* Unsupported texture/multitexture cases */
 
-   if (fxMesa->emulateTwoTMUs) {
-      if (ctx->Texture._ReallyEnabled & (TEXTURE0_3D | TEXTURE1_3D))
-        return GL_FALSE;       /* can't do 3D textures */
-      if (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE1_1D))
-        return GL_FALSE;       /* can't do 1D textures */
+   if (fxMesa->haveTwoTMUs) {
+      /* we can only do 2D textures */
+      if (ctx->Texture.Unit[0]._ReallyEnabled & ~TEXTURE_2D_BIT)
+        return GL_FALSE;
+      if (ctx->Texture.Unit[1]._ReallyEnabled & ~TEXTURE_2D_BIT)
+        return GL_FALSE;
 
-      if (ctx->Texture._ReallyEnabled & TEXTURE0_2D) {
+      if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) {
         if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
-            (ctx->Texture._ReallyEnabled & TEXTURE1_2D ||
+            (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT ||
              ctx->Texture.Unit[0].EnvColor[0] != 0 ||
              ctx->Texture.Unit[0].EnvColor[1] != 0 ||
              ctx->Texture.Unit[0].EnvColor[2] != 0 ||
@@ -888,10 +871,10 @@ fxIsInHardware(GLcontext * ctx)
            return GL_FALSE;
       }
 
-      if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) {
+      if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) {
         if (ctx->Texture.Unit[1].EnvMode == GL_BLEND)
            return GL_FALSE;
-        if (ctx->Texture.Unit[0]._Current->Image[0]->Border > 0)
+        if (ctx->Texture.Unit[1]._Current->Image[0]->Border > 0)
            return GL_FALSE;
       }
 
@@ -902,9 +885,10 @@ fxIsInHardware(GLcontext * ctx)
 
       /* KW: This was wrong (I think) and I changed it... which doesn't mean
        * it is now correct...
+       * BP: The old condition just seemed to test if both texture units
+       * were enabled.  That's easy!
        */
-      if ((ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D)) &&
-         (ctx->Texture._ReallyEnabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D))) {
+      if (ctx->Texture._EnabledUnits == 0x3) {
         /* Can't use multipass to blend a multitextured triangle - fall
          * back to software.
          */
@@ -922,16 +906,12 @@ fxIsInHardware(GLcontext * ctx)
       }
    }
    else {
-      if ((ctx->Texture._ReallyEnabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)) ||
-         /* Not very well written ... */
-         ((ctx->Texture._ReallyEnabled & TEXTURE0_1D) &&
-           (!(ctx->Texture._ReallyEnabled & TEXTURE0_2D)))
-        ) {
+      /* we have just one texture unit */
+      if (ctx->Texture._EnabledUnits > 0x1) {
         return GL_FALSE;
       }
 
-
-      if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) &&
+      if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
          (ctx->Texture.Unit[0].EnvMode == GL_BLEND)) {
         return GL_FALSE;
       }
@@ -940,6 +920,8 @@ fxIsInHardware(GLcontext * ctx)
    return GL_TRUE;
 }
 
+
+
 static void
 update_texture_scales(GLcontext * ctx)
 {
@@ -965,7 +947,7 @@ update_texture_scales(GLcontext * ctx)
 static void
 fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
 {
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   /*   TNLcontext *tnl = TNL_CONTEXT(ctx);*/
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
    _swrast_InvalidateState(ctx, new_state);
@@ -981,72 +963,29 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
 
    if (new_state & (_FX_NEW_IS_IN_HARDWARE |
                    _FX_NEW_RENDERSTATE |
-                   _FX_NEW_SETUP_FUNCTION | _NEW_TEXTURE)) {
+                   _FX_NEW_SETUP_FUNCTION | 
+                   _NEW_TEXTURE)) {
 
       if (new_state & _FX_NEW_IS_IN_HARDWARE)
-        fxMesa->is_in_hardware = fxIsInHardware(ctx);
+        fxCheckIsInHardware(ctx);
 
       if (fxMesa->new_state)
         fxSetupFXUnits(ctx);
 
-      if (new_state & _FX_NEW_RENDERSTATE)
-        fxDDChooseRenderState(ctx);
+      if (fxMesa->is_in_hardware) {
+        if (new_state & _FX_NEW_RENDERSTATE)
+           fxDDChooseRenderState(ctx);
 
-      if (new_state & _FX_NEW_SETUP_FUNCTION)
-        tnl->Driver.BuildProjectedVertices = fx_validate_BuildProjVerts;
+        if (new_state & _FX_NEW_SETUP_FUNCTION)
+           fxChooseVertexState(ctx);
+      }
 
       if (new_state & _NEW_TEXTURE)
         update_texture_scales(ctx);
-
-   }
-
-#ifdef FXVTXFMT
-   if (fxMesa->allow_vfmt) {
-      if (new_state & _NEW_LIGHT)
-        fx_update_lighting(ctx);
-
-      if (new_state & _FX_NEW_VTXFMT)
-        fxDDCheckVtxfmt(ctx);
-   }
-#endif
-}
-
-static void
-fxDDRenderPrimitive(GLcontext * ctx, GLenum mode)
-{
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   if (!fxMesa->is_in_hardware) {
-      _swsetup_RenderPrimitive(ctx, mode);
-   }
-   else {
-      fxMesa->render_prim = mode;
    }
 }
 
 
-static void
-fxDDRenderStart(GLcontext * ctx)
-{
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   _swsetup_RenderStart(ctx);
-
-   if (fxMesa->new_state) {
-      fxSetupFXUnits(ctx);
-   }
-}
-
-static void
-fxDDRenderFinish(GLcontext * ctx)
-{
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   if (!fxMesa->is_in_hardware) {
-      _swsetup_RenderFinish(ctx);
-   }
-}
-
 
 
 void
@@ -1063,22 +1002,29 @@ fxSetupDDPointers(GLcontext * ctx)
    ctx->Driver.ClearIndex = NULL;
    ctx->Driver.ClearColor = fxDDClearColor;
    ctx->Driver.Clear = fxDDClear;
-   ctx->Driver.SetDrawBuffer = fxDDSetDrawBuffer;
+   ctx->Driver.DrawBuffer = fxDDSetDrawBuffer;
    ctx->Driver.GetBufferSize = fxDDBufferSize;
    ctx->Driver.Accum = _swrast_Accum;
    ctx->Driver.Bitmap = fxDDDrawBitmap;
    ctx->Driver.CopyPixels = _swrast_CopyPixels;
    ctx->Driver.DrawPixels = _swrast_DrawPixels;
    ctx->Driver.ReadPixels = fxDDReadPixels;
-   ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
+   ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
    ctx->Driver.Finish = fxDDFinish;
    ctx->Driver.Flush = NULL;
+   ctx->Driver.ChooseTextureFormat = fxDDChooseTextureFormat;
    ctx->Driver.TexImage1D = _mesa_store_teximage1d;
    ctx->Driver.TexImage2D = fxDDTexImage2D;
    ctx->Driver.TexImage3D = _mesa_store_teximage3d;
    ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
    ctx->Driver.TexSubImage2D = fxDDTexSubImage2D;
    ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+   ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+   ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+   ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+   ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+   ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+   ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
    ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
    ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
    ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
@@ -1106,14 +1052,7 @@ fxSetupDDPointers(GLcontext * ctx)
    ctx->Driver.ShadeModel = fxDDShadeModel;
    ctx->Driver.Enable = fxDDEnable;
 
-   tnl->Driver.RenderStart = fxDDRenderStart;
-   tnl->Driver.RenderFinish = fxDDRenderFinish;
-   tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
-   tnl->Driver.RenderPrimitive = fxDDRenderPrimitive;
-   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
-   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
-   tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
-   tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
+   tnl->Driver.RunPipeline = _tnl_run_pipeline;
 
    fxSetupDDSpanPointers(ctx);
    fxDDUpdateDDPointers(ctx, ~0);