EXT_secondary_color and EXT_separate_specular via multipass
authorDaniel Borca <dborca@users.sourceforge.net>
Mon, 15 Dec 2003 10:38:12 +0000 (10:38 +0000)
committerDaniel Borca <dborca@users.sourceforge.net>
Mon, 15 Dec 2003 10:38:12 +0000 (10:38 +0000)
src/mesa/drivers/glide/fxdd.c
src/mesa/drivers/glide/fxddtex.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/glide/fxglidew.h
src/mesa/drivers/glide/fxsetup.c
src/mesa/drivers/glide/fxtris.c
src/mesa/drivers/glide/fxvb.c
src/mesa/drivers/glide/fxvbtmp.h

index 9c889a0..0d0de38 100644 (file)
@@ -1421,6 +1421,10 @@ fxDDInitExtensions(GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
+#if 1 /* multipass ColorSum stage */
+   _mesa_enable_extension(ctx, "GL_EXT_secondary_color");
+#endif
+
    _mesa_enable_extension(ctx, "GL_EXT_point_parameters");
    _mesa_enable_extension(ctx, "GL_EXT_paletted_texture");
    _mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias");
@@ -1523,9 +1527,11 @@ fx_check_IsInHardware(GLcontext * ctx)
       return FX_FALLBACK_LOGICOP;
    }
 
+#if 0 /* multipass ColorSum stage */
    if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
       return FX_FALLBACK_SPECULAR;
    }
+#endif
 
    if ((fxMesa->colDepth == 16) &&
        ((ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP]) ||
index 3ad0f22..073a36d 100644 (file)
@@ -219,6 +219,11 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
         ti->LODblend = FXFALSE;
         break;
       case GL_NEAREST_MIPMAP_LINEAR:
+        /* ZZZ: HACK ALERT! disable LODBlend, because we can't implement
+                on Napalm. Ohwell, until at least I decide what to do...
+                trilinear is bugged! mipmap blending produce
+                incorrect filtered colors for the smallest mipmap levels. */
+#if 0
         if (fxMesa->haveTwoTMUs) {
            ti->mmMode = GR_MIPMAP_NEAREST;
            ti->LODblend = FXTRUE;
@@ -229,6 +234,7 @@ fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
         }
         ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
         break; /* ZZZ: we may have to fall through here for V3 */
+#endif
       case GL_NEAREST_MIPMAP_NEAREST:
         ti->mmMode = GR_MIPMAP_NEAREST;
         ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
index b4b44de..27a721a 100644 (file)
 #define SETUP_XYZW 0x10
 #define SETUP_PTEX 0x20
 #define SETUP_PSIZ 0x40
-#define MAX_SETUP  0x80
+#define SETUP_SPEC 0x80
+#define MAX_SETUP  0x100
 
 
 #define FX_NUM_TMU 2
@@ -469,7 +470,6 @@ struct tfxMesaContext
    GLuint stw_hint_state;      /* for grHints */
    GrVertex *verts;
    GLboolean snapVertices;      /* needed for older Voodoo hardware */
-   struct gl_client_array UbyteColor;
 
    /* Rasterization:
     */
@@ -691,6 +691,9 @@ extern void fxCheckIsInHardware(GLcontext *ctx);
 void fxSetupCull (GLcontext * ctx);
 void fxSetupScissor (GLcontext * ctx);
 void fxSetupColorMask (GLcontext * ctx);
+void fxSetupBlend (GLcontext *ctx);
+void fxSetupDepthTest (GLcontext *ctx);
+void fxSetupTexture (GLcontext *ctx);
 
 /* Flags for software fallback cases */
 #define FX_FALLBACK_TEXTURE_1D_3D      0x0001
index b3a6b0b..472cf94 100644 (file)
@@ -119,8 +119,9 @@ typedef struct {
         unsigned char pargb[4];        /* B, G, R, A [0..255] */
         GrTmuVertex tmuvtx[GLIDE_NUM_TMU];
         float fog;             /* fog coordinate */
+        unsigned char pspec[4];        /* B, G, R, A [0..255] */
         float psize;           /* point size */
-        long pad[16 - 13];     /* ensure 64b structure */
+        long pad[16 - 14];     /* ensure 64b structure */
 } GrVertex;
 
 #define GR_VERTEX_X_OFFSET              0
@@ -135,6 +136,7 @@ typedef struct {
 #define GR_VERTEX_TOW_TMU1_OFFSET       9
 #define GR_VERTEX_OOW_TMU1_OFFSET       10
 #define GR_VERTEX_FOG_OFFSET            11
+#define GR_VERTEX_PSPEC_OFFSET          12
 
 
 
@@ -152,36 +154,10 @@ typedef struct {
 
 
 /*
- * Write region: ToDo possible exploit the PixelPipe parameter.
- */
-#define FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)        \
-        do { \
-            BEGIN_BOARD_LOCK(); \
-            grLfbWriteRegion(dst_buffer,\
-                             dst_x,     \
-                             dst_y,     \
-                             src_format,\
-                             src_width, \
-                             src_height,\
-                             FXFALSE,   \
-                             src_stride,\
-                             src_data);        \
-            END_BOARD_LOCK(); \
-        } while(0)
-
-
-
-/*
- * ScreenWidth/Height stuff.
+ * Query
  */
 extern int FX_grSstScreenWidth(void);
 extern int FX_grSstScreenHeight(void);
-
-
-
-/*
- * Query
- */
 extern void FX_grSstPerfStats(GrSstPerfStats_t *st);
 extern int FX_grSstQueryHardware(GrHwConfiguration *config);
 #define FX_grGetInteger FX_grGetInteger_NoLock
index fad0d1e..9738d6e 100644 (file)
@@ -1207,7 +1207,7 @@ fxSetupTexture_NoLock(GLcontext * ctx)
    }
 }
 
-static void
+void
 fxSetupTexture(GLcontext * ctx)
 {
    BEGIN_BOARD_LOCK();
@@ -1464,7 +1464,7 @@ fxDDBlendEquation(GLcontext * ctx, GLenum mode)
  }
 }
 
-static void
+void
 fxSetupBlend(GLcontext * ctx)
 {
  fxMesaContext fxMesa = FX_CONTEXT(ctx);
@@ -1557,7 +1557,7 @@ fxDDDepthMask(GLcontext * ctx, GLboolean flag)
    }
 }
 
-static void
+void
 fxSetupDepthTest(GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
index 56563fc..cfd643e 100644 (file)
@@ -35,6 +35,7 @@
 #include "mtypes.h"
 #include "macros.h"
 #include "colormac.h"
+#include "nvfragprog.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
@@ -44,6 +45,9 @@
 #include "fxdrv.h"
 
 
+GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass);
+
+
 /*
  * Subpixel offsets to adjust Mesa's (true) window coordinates to
  * Glide coordinates.  We need these to ensure precise rasterization.
@@ -147,6 +151,10 @@ fx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst)
    dst->color[2] = src->pargb[0];
    dst->color[3] = src->pargb[3];
 
+   dst->specular[0] = src->pspec[2];
+   dst->specular[1] = src->pspec[1];
+   dst->specular[2] = src->pspec[0];
+
    dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w;
    dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w;
 
@@ -377,7 +385,7 @@ static struct {
 #define DO_FULL_QUAD 1
 
 #define HAVE_RGBA   1
-#define HAVE_SPEC   0
+#define HAVE_SPEC   1 /* [dBorca] investigate overhead !!! */
 #define HAVE_HW_FLATSHADE 0
 #define HAVE_BACK_COLORS  0
 #define VERTEX GrVertex
@@ -400,6 +408,7 @@ typedef union { GLfloat f; GLuint u; } fu_type;
 #define AREA_IS_CCW( a ) (a < 0)
 #endif
 
+
 #define VERT_SET_RGBA( dst, f )                        \
 do {                                           \
    UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[2], f[0]);\
@@ -414,15 +423,31 @@ do {                                              \
 #define VERT_SAVE_RGBA( idx )                          \
    *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->pargb
 
-
 #define VERT_RESTORE_RGBA( idx )               \
    *(GLuint *)&v[idx]->pargb = *(GLuint *)&color[idx]
 
 
+#define VERT_SET_SPEC( dst, f )                        \
+do {                                           \
+   UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[2], f[0]);\
+   UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[1], f[1]);\
+   UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[0], f[2]);\
+} while (0)
+
+#define VERT_COPY_SPEC( v0, v1 )               \
+   *(GLuint *)&v0->pspec = *(GLuint *)&v1->pspec
+
+#define VERT_SAVE_SPEC( idx )                          \
+   *(GLuint *)&spec[idx] = *(GLuint *)&v[idx]->pspec
+
+#define VERT_RESTORE_SPEC( idx )               \
+   *(GLuint *)&v[idx]->pspec = *(GLuint *)&spec[idx]
+
+
 #define LOCAL_VARS(n)                          \
    fxMesaContext fxMesa = FX_CONTEXT(ctx);     \
-   GLubyte color[n][4];                                \
-   (void) color;
+   GLubyte color[n][4], spec[n][4];            \
+   (void) color; (void) spec;
 
 
 
@@ -1318,13 +1343,13 @@ void fxCheckIsInHardware( GLcontext *ctx )
         tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
         tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
         tnl->Driver.Render.BuildVertices = fxBuildVertices;
-        tnl->Driver.Render.Multipass = 0;
         fxChooseVertexState(ctx);
         fxDDChooseRenderState(ctx);
          if (fxMesa->verbose) {
             fprintf(stderr, "Voodoo ! leave SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback));
          }
       }
+      tnl->Driver.Render.Multipass = (HAVE_SPEC && NEED_SECONDARY_COLOR(ctx)) ? fxMultipass_ColorSum : NULL;
    }
 }
 
@@ -1348,12 +1373,74 @@ void fxDDInitTriFuncs( GLcontext *ctx )
    tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
    tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
    tnl->Driver.Render.BuildVertices = fxBuildVertices;
-   tnl->Driver.Render.Multipass = 0;
+   tnl->Driver.Render.Multipass = NULL;
    
    (void) fx_print_vertex;
 }
 
 
+/* [dBorca] Hack alert:
+ * does this approach work with multitex?
+ */
+GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ static int t0 = 0;
+ static int t1 = 0;
+
+ switch (pass) {
+        case 1: /* first pass: the TEXTURED triangles are drawn */
+             /* save per-pass data */
+             fxMesa->restoreUnitsState = fxMesa->unitsState;
+             /* turn off texturing */
+             t0 = ctx->Texture.Unit[0]._ReallyEnabled;
+             t1 = ctx->Texture.Unit[1]._ReallyEnabled;
+             ctx->Texture.Unit[0]._ReallyEnabled = 0;
+             ctx->Texture.Unit[1]._ReallyEnabled = 0;
+             /* SUM the colors */
+             fxDDBlendEquation(ctx, GL_FUNC_ADD_EXT);
+             fxDDBlendFuncSeparate(ctx, GL_ONE, GL_ONE, GL_ZERO, GL_ONE);
+             fxDDEnable(ctx, GL_BLEND, GL_TRUE);
+             /* make sure we draw only where we want to */
+             if (ctx->Depth.Mask) {
+                switch (ctx->Depth.Func) {
+                       case GL_NEVER:
+                       case GL_ALWAYS:
+                       break;
+                default:
+                       fxDDDepthFunc( ctx, GL_EQUAL );
+                       break;
+                }
+                fxDDDepthMask( ctx, GL_FALSE );
+             }
+             /* switch to secondary colors */
+             grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PSPEC_OFFSET << 2, GR_PARAM_ENABLE);
+             /* don't advertise new state */
+             fxMesa->new_state = 0;
+             break;
+        case 2: /* 2nd pass (last): the secondary color is summed over texture */
+             /* restore original state */
+             fxMesa->unitsState = fxMesa->restoreUnitsState;
+             /* restore texturing */
+             ctx->Texture.Unit[0]._ReallyEnabled = t0;
+             ctx->Texture.Unit[1]._ReallyEnabled = t1;
+             /* revert to primary colors */
+             grVertexLayout(GR_PARAM_PARGB, GR_VERTEX_PARGB_OFFSET << 2, GR_PARAM_ENABLE);
+             break;
+        default:
+             assert(0); /* NOTREACHED */
+ }
+
+ /* update HW state */
+ fxSetupBlend(ctx);
+ fxSetupDepthTest(ctx);
+ fxSetupTexture(ctx);
+
+ return (pass == 1);
+}
+
+
 #else
 
 
index 1b3eaea..7e3445f 100644 (file)
@@ -58,10 +58,21 @@ static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
    *(GLuint *)&dst->pargb = *(GLuint *)&src->pargb;
 }
 
+static void copy_pv2( GLcontext *ctx, GLuint edst, GLuint esrc )
+{
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
+   GrVertex *dst = fxMesa->verts + edst;
+   GrVertex *src = fxMesa->verts + esrc;
+
+   *(GLuint *)&dst->pargb = *(GLuint *)&src->pargb;
+   *(GLuint *)&dst->pspec = *(GLuint *)&src->pspec;
+}
+
 typedef void (*emit_func)( GLcontext *, GLuint, GLuint, void * );
 
 static struct {
    emit_func           emit;
+   copy_pv_func                copy_pv;
    interp_func         interp;
    GLboolean           (*check_tex_sizes)( GLcontext *ctx );
    GLuint               vertex_format;
@@ -85,14 +96,13 @@ static void interp_extras( GLcontext *ctx,
                 GET_COLOR(VB->ColorPtr[1], dst),
                 GET_COLOR(VB->ColorPtr[1], out),
                 GET_COLOR(VB->ColorPtr[1], in) );
-#if 1 /* [dBorca] GL_EXT_separate_specular_color */
+
       if (VB->SecondaryColorPtr[1]) {
         INTERP_3F( t,
                    GET_COLOR(VB->SecondaryColorPtr[1], dst),
                    GET_COLOR(VB->SecondaryColorPtr[1], out),
                    GET_COLOR(VB->SecondaryColorPtr[1], in) );
       }
-#endif
    }
 
    if (VB->EdgeFlag) {
@@ -110,15 +120,14 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
    if (VB->ColorPtr[1]) {
         COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
                   GET_COLOR(VB->ColorPtr[1], src) );
-#if 1 /* [dBorca] GL_EXT_separate_specular_color */
+
         if (VB->SecondaryColorPtr[1]) {
            COPY_3FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
                      GET_COLOR(VB->SecondaryColorPtr[1], src) );
         }
-#endif
    }
 
-   copy_pv(ctx, dst, src);
+   setup_tab[FX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src);
 }
 
 
@@ -165,6 +174,49 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
 #include "fxvbtmp.h"
 
 
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC)
+#define TAG(x) x##_2wg
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0)
+#define TAG(x) x##_2wgt0
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_2wgt0t1
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX)
+#define TAG(x) x##_2wgpt0
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\
+             SETUP_PTEX)
+#define TAG(x) x##_2wgpt0t1
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ)
+#define TAG(x) x##_2wga
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ)
+#define TAG(x) x##_2wgt0a
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|SETUP_PSIZ)
+#define TAG(x) x##_2wgt0t1a
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PTEX|SETUP_PSIZ)
+#define TAG(x) x##_2wgpt0a
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1|\
+             SETUP_PTEX|SETUP_PSIZ)
+#define TAG(x) x##_2wgpt0t1a
+#include "fxvbtmp.h"
+
+
 /* Snapping for voodoo-1
  */
 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
@@ -214,6 +266,53 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
 #include "fxvbtmp.h"
 
 
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC)
+#define TAG(x) x##_2wsg
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0)
+#define TAG(x) x##_2wsgt0
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
+             SETUP_TMU1)
+#define TAG(x) x##_2wsgt0t1
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
+             SETUP_PTEX)
+#define TAG(x) x##_2wsgpt0
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
+            SETUP_TMU1|SETUP_PTEX)
+#define TAG(x) x##_2wsgpt0t1
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_PSIZ)
+#define TAG(x) x##_2wsga
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_PSIZ)
+#define TAG(x) x##_2wsgt0a
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
+             SETUP_TMU1|SETUP_PSIZ)
+#define TAG(x) x##_2wsgt0t1a
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
+             SETUP_PTEX|SETUP_PSIZ)
+#define TAG(x) x##_2wsgpt0a
+#include "fxvbtmp.h"
+
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|\
+            SETUP_TMU1|SETUP_PTEX|SETUP_PSIZ)
+#define TAG(x) x##_2wsgpt0t1a
+#include "fxvbtmp.h"
+
+
 /* Vertex repair (multipass rendering)
  */
 #define IND (SETUP_RGBA)
@@ -237,6 +336,27 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
 #include "fxvbtmp.h"
 
 
+#define IND (SETUP_RGBA|SETUP_SPEC)
+#define TAG(x) x##_2g
+#include "fxvbtmp.h"
+
+#define IND (SETUP_TMU0|SETUP_SPEC)
+#define TAG(x) x##_2t0
+#include "fxvbtmp.h"
+
+#define IND (SETUP_TMU0|SETUP_SPEC|SETUP_TMU1)
+#define TAG(x) x##_2t0t1
+#include "fxvbtmp.h"
+
+#define IND (SETUP_RGBA|SETUP_SPEC|SETUP_TMU0)
+#define TAG(x) x##_2gt0
+#include "fxvbtmp.h"
+
+#define IND (SETUP_RGBA|SETUP_SPEC|SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_2gt0t1
+#include "fxvbtmp.h"
+
+
 
 static void init_setup_tab( void )
 {
@@ -250,6 +370,16 @@ static void init_setup_tab( void )
    init_wgt0t1a();
    init_wgpt0a();
    init_wgpt0t1a();
+    init_2wg();
+    init_2wgt0();
+    init_2wgt0t1();
+    init_2wgpt0();
+    init_2wgpt0t1();
+    init_2wga();
+    init_2wgt0a();
+    init_2wgt0t1a();
+    init_2wgpt0a();
+    init_2wgpt0t1a();
 
    init_wsg();
    init_wsgt0();
@@ -261,25 +391,42 @@ static void init_setup_tab( void )
    init_wsgt0t1a();
    init_wsgpt0a();
    init_wsgpt0t1a();
+    init_2wsg();
+    init_2wsgt0();
+    init_2wsgt0t1();
+    init_2wsgpt0();
+    init_2wsgpt0t1();
+    init_2wsga();
+    init_2wsgt0a();
+    init_2wsgt0t1a();
+    init_2wsgpt0a();
+    init_2wsgpt0t1a();
 
    init_g();
    init_t0();
    init_t0t1();
    init_gt0();
    init_gt0t1();
+    init_2g();
+    init_2t0();
+    init_2t0t1();
+    init_2gt0();
+    init_2gt0t1();
 }
 
 
 void fxPrintSetupFlags(char *msg, GLuint flags )
 {
-   fprintf(stderr, "%s(%x): %s%s%s%s%s\n",
+   fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s\n",
           msg,
           (int)flags,
           (flags & SETUP_XYZW)     ? " xyzw," : "", 
           (flags & SETUP_SNAP)     ? " snap," : "", 
           (flags & SETUP_RGBA)     ? " rgba," : "",
           (flags & SETUP_TMU0)     ? " tex-0," : "",
-          (flags & SETUP_TMU1)     ? " tex-1," : "");
+          (flags & SETUP_TMU1)     ? " tex-1," : "",
+          (flags & SETUP_PSIZ)     ? " psiz," : "",
+          (flags & SETUP_SPEC)     ? " spec," : "");
 }
 
 
@@ -334,6 +481,10 @@ void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
       if (newinputs & VERT_BIT_COLOR0)
         ind |= SETUP_RGBA;
       
+      if (newinputs & VERT_BIT_COLOR1) {
+        ind |= SETUP_SPEC;
+      }
+
       if (newinputs & VERT_BIT_TEX0) 
         ind |= SETUP_TMU0;
 
@@ -382,6 +533,10 @@ void fxChooseVertexState( GLcontext *ctx )
       ind |= SETUP_PSIZ;
    }
 
+   if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
+      ind |= SETUP_SPEC;
+   }
+
    fxMesa->SetupIndex = ind;
 
    if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
@@ -389,7 +544,7 @@ void fxChooseVertexState( GLcontext *ctx )
       tnl->Driver.Render.CopyPV = copy_pv_extras;
    } else {
       tnl->Driver.Render.Interp = setup_tab[ind].interp;
-      tnl->Driver.Render.CopyPV = copy_pv;
+      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
    }
 
    if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) {
@@ -422,11 +577,6 @@ void fxFreeVB( GLcontext *ctx )
       ALIGN_FREE(fxMesa->verts);
       fxMesa->verts = 0;
    }
-
-   if (fxMesa->UbyteColor.Ptr) {
-      ALIGN_FREE((void *)fxMesa->UbyteColor.Ptr);
-      fxMesa->UbyteColor.Ptr = 0;
-   }
 }
 #else
 
index 9028cd1..4e1b10f 100644 (file)
@@ -41,8 +41,8 @@ static void TAG(emit)( GLcontext *ctx,
    GLuint tmu0_source = fxMesa->tmu_source[0];
    GLuint tmu1_source = fxMesa->tmu_source[1];
    GLfloat (*tc0)[4], (*tc1)[4];
-   GLfloat (*col)[4];
-   GLuint tc0_stride, tc1_stride, col_stride;
+   GLfloat (*col)[4], (*spec)[4];
+   GLuint tc0_stride, tc1_stride, col_stride, spec_stride;
    GLuint tc0_size, tc1_size;
    GLfloat (*proj)[4] = VB->NdcPtr->data; 
    GLuint proj_stride = VB->NdcPtr->stride;
@@ -82,6 +82,11 @@ static void TAG(emit)( GLcontext *ctx,
       col_stride = VB->ColorPtr[0]->stride;
    }
 
+   if (IND & SETUP_SPEC) {
+      spec = VB->SecondaryColorPtr[0]->data;
+      spec_stride = VB->SecondaryColorPtr[0]->stride;
+   }
+
    if (start) {
       proj =  (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride);
       if (IND & SETUP_PSIZ) {
@@ -93,6 +98,8 @@ static void TAG(emit)( GLcontext *ctx,
         tc1 =  (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride);
       if (IND & SETUP_RGBA) 
         STRIDE_4F(col, start * col_stride);
+      if (IND & SETUP_SPEC)
+        STRIDE_4F(spec, start * spec_stride);
    }
 
    for (i=start; i < end; i++, v++) {
@@ -135,6 +142,12 @@ static void TAG(emit)( GLcontext *ctx,
          UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[3], col[0][3]);
         STRIDE_4F(col, col_stride);
       }
+      if (IND & SETUP_SPEC) {
+        UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[2], spec[0][0]);
+        UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[1], spec[0][1]);
+        UNCLAMPED_FLOAT_TO_UBYTE(v->pspec[0], spec[0][2]);
+        STRIDE_4F(spec, spec_stride);
+      }
       if (IND & SETUP_TMU0) {
         GLfloat w = v->oow;
          v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
@@ -228,6 +241,12 @@ static void TAG(interp)( GLcontext *ctx,
    INTERP_UB( t, dst->pargb[2], out->pargb[2], in->pargb[2] );
    INTERP_UB( t, dst->pargb[3], out->pargb[3], in->pargb[3] );
 
+   if (IND & SETUP_SPEC) {
+      INTERP_UB( t, dst->pspec[0], out->pspec[0], in->pspec[0] );
+      INTERP_UB( t, dst->pspec[1], out->pspec[1], in->pspec[1] );
+      INTERP_UB( t, dst->pspec[2], out->pspec[2], in->pspec[2] );
+   }
+
    if (IND & SETUP_TMU0) {
       if (IND & SETUP_PTEX) {
         INTERP_F( t, 
@@ -301,6 +320,12 @@ static void TAG(init)( void )
 {
    setup_tab[IND].emit = TAG(emit);
    
+   if (IND & SETUP_SPEC) {
+      setup_tab[IND].copy_pv = copy_pv2;
+   } else {
+      setup_tab[IND].copy_pv = copy_pv;
+   }
+
 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
    setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
    setup_tab[IND].interp = TAG(interp);