Add code to support projective texturing and fix mixed enabling of texture
authorEric Anholt <anholt@FreeBSD.org>
Sat, 16 Oct 2004 03:36:14 +0000 (03:36 +0000)
committerEric Anholt <anholt@FreeBSD.org>
Sat, 16 Oct 2004 03:36:14 +0000 (03:36 +0000)
coordinate generation.  Original code by Roland Schiedegger, with changes by
myself.  While here, ensure that the swtcl path does tnl_install_attrs enough
when fog/specular are being (en/dis)abled.

Notable effects:
- projtex test works with TCL and is closer with swtcl (Bugzilla #1461)
- 8/9 squares work in texgenmix instead of 3.
- texcyl "reflect" mode works (GL_SPHERE_MAP is now a fallback -- unclear if the
  hardware can actually support it).
- flickering in doom3 replaced by just plain darkness.
- blocktube fixed (Bugzilla #984)
- fixes stex3d

src/mesa/drivers/dri/r200/r200_context.h
src/mesa/drivers/dri/r200/r200_maos_arrays.c
src/mesa/drivers/dri/r200/r200_reg.h
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_state_init.c
src/mesa/drivers/dri/r200/r200_swtcl.c
src/mesa/drivers/dri/r200/r200_tcl.c
src/mesa/drivers/dri/r200/r200_texstate.c
src/mesa/drivers/dri/r200/r200_vtxfmt.c
src/mesa/drivers/dri/r200/r200_vtxfmt.h
src/mesa/drivers/dri/r200/r200_vtxfmt_c.c

index 140902c356b7a77968db844c680330436e60b088..af07653244c04a6a94f2f52521b0c1d0720c22e5 100644 (file)
@@ -845,6 +845,7 @@ struct r200_context {
    GLuint TclFallback;
    GLuint Fallback;
    GLuint NewGLState;
+   GLuint tnl_index;   /* index of bits for last tnl_install_attrs */
 
    /* Vertex buffers
     */
@@ -889,7 +890,6 @@ struct r200_context {
    GLuint TexMatEnabled;
    GLuint TexMatCompSel;
    GLuint TexGenEnabled;
-   GLuint TexGenInputs;
    GLuint TexGenCompSel;
    GLmatrix tmpmat;
 
index 3429cf6400db1453feea3971959f3a0c67e00135..0f8ca3048ed772a9b9f9f7ba5186c48f7cb62ad7 100644 (file)
@@ -344,7 +344,6 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
    GLuint vfmt0 = 0, vfmt1 = 0;
    GLuint count = VB->Count;
    GLuint i;
-   GLuint re_cntl;
    
    if (1) {
       if (!rmesa->tcl.obj.buf) 
@@ -421,12 +420,6 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
       component[nr++] = &rmesa->tcl.spec;
    }
       
-   re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D |
-                                               R200_VTX_STQ1_D3D |
-                                               R200_VTX_STQ2_D3D |
-                                               R200_VTX_STQ3_D3D |
-                                               R200_VTX_STQ4_D3D |
-                                               R200_VTX_STQ5_D3D );
    for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
       if (inputs & (VERT_BIT_TEX0 << i)) {
         if (!rmesa->tcl.tex[i].buf)
@@ -437,20 +430,11 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
                          VB->TexCoordPtr[i]->stride,
                          count );
 
-        if ( ctx->Texture.Unit[i]._ReallyEnabled == TEXTURE_CUBE_BIT ) {
-           re_cntl |= R200_VTX_STQ0_D3D << (2 * i);
-        }
-
         vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3);
         component[nr++] = &rmesa->tcl.tex[i];
       }
    }
 
-   if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
-      R200_STATECHANGE( rmesa, set );
-      rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
-   }
-
    if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
        vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { 
       R200_STATECHANGE( rmesa, vtx ); 
index 726be6ef8fd0f8ca7e29b17d6025bc6179499ac7..89da699bdb6b263cddeab44a4e3abde7796830ce 100644 (file)
@@ -575,6 +575,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define     R200_LIGHT_7_SHIFT                   (16)
 /* gap */
 #define R200_SE_TCL_TEX_PROC_CTL_2        0x22a8 
+#define     R200_TEXGEN_COMP_MASK                (0xf)
+#define     R200_TEXGEN_COMP_S                   (0x1)
+#define     R200_TEXGEN_COMP_T                   (0x2)
+#define     R200_TEXGEN_COMP_R                   (0x4)
+#define     R200_TEXGEN_COMP_Q                   (0x8)
 #define     R200_TEXGEN_0_COMP_MASK_SHIFT        (0)
 #define     R200_TEXGEN_1_COMP_MASK_SHIFT        (4)
 #define     R200_TEXGEN_2_COMP_MASK_SHIFT        (8)
index dd547f9957a3d1ee7bcf26965272cad6e272eca0..825c036e272c5bb1cd38f35a553d022172eb253b 100644 (file)
@@ -2138,9 +2138,9 @@ static void update_texturematrix( GLcontext *ctx )
            /* Need to preconcatenate any active texgen 
             * obj/eyeplane matrices:
             */
-           _math_matrix_mul_matrix( &rmesa->tmpmat, 
-                                    &rmesa->TexGenMatrix[unit],
-                                    ctx->TextureMatrixStack[unit].Top );
+           _math_matrix_mul_matrix( &rmesa->tmpmat,
+                                    ctx->TextureMatrixStack[unit].Top, 
+                                    &rmesa->TexGenMatrix[unit] );
            upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit );
         } 
         else {
@@ -2155,11 +2155,9 @@ static void update_texturematrix( GLcontext *ctx )
    }
 
    tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
-   if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] ||
-       rmesa->TexGenInputs != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1]) {
+   if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) {
       R200_STATECHANGE(rmesa, tcg);
       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc;
-      rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = rmesa->TexGenInputs;
    }
 
    compsel &= ~R200_OUTPUT_TEX_MASK;
index 049820b3cb73049fc9d51905343f3832f5175e46..610706bd3187b68d57bbda9ffe22118a59136b69 100644 (file)
@@ -699,7 +699,7 @@ void r200InitState( r200ContextPtr rmesa )
        R200_CULL_FRONT_IS_CCW);
 
    /* Texgen/Texmat state */
-   rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x0; /* masks??? */
+   rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x00ffffff;
    rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_3] = 
       ((0 << R200_TEXGEN_0_INPUT_TEX_SHIFT) |
        (1 << R200_TEXGEN_1_INPUT_TEX_SHIFT) |
@@ -717,8 +717,6 @@ void r200InitState( r200ContextPtr rmesa )
        (5 << R200_TEXGEN_5_INPUT_SHIFT)); 
    rmesa->hw.tcg.cmd[TCG_TEX_CYL_WRAP_CTL] = 0;
 
-   rmesa->TexGenInputs = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1];
-
 
    for (i = 0 ; i < 8; i++) {
       struct gl_light *l = &ctx->Light.Light[i];
index 66662bb4d032d5cce3905d5eed6275c858059c8b..c40c7d09dbd4fa26c5a95f7d38176d4b0a8c33ea 100644 (file)
@@ -64,7 +64,6 @@ static void flush_last_swtcl_prim( r200ContextPtr rmesa  );
  *                         Initialization 
  ***********************************************************************/
 
-#define EMIT_SZ(sz)   (EMIT_1F + (sz) - 1)
 #define EMIT_ATTR( ATTR, STYLE, F0 )                                   \
 do {                                                                   \
    rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR);  \
@@ -145,28 +144,18 @@ static void r200SetVertexFormat( GLcontext *ctx )
       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
         if (index & _TNL_BIT_TEX(i)) {
            GLuint sz = VB->TexCoordPtr[i]->size;
-           GLuint emit;
-
-           /* r200 doesn't like 4D texcoords (is that true?):
-            */
-           if (sz != 4) {
-              emit = EMIT_1F + (sz - 1);
-           }
-           else {
-              sz = 3;
-              emit = EMIT_3F_XYW; 
-           }
 
            fmt_1 |= sz << (3 * i);
-           EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0 );
+           EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1, 0 );
         }
       }
    }
 
 
 
-   if ( (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0)
-       || (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
+   if ( rmesa->tnl_index != index ||
+       (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) ||
+       (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
       R200_NEWPRIM(rmesa);
       R200_STATECHANGE( rmesa, vtx );
       rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0;
@@ -178,6 +167,7 @@ static void r200SetVertexFormat( GLcontext *ctx )
                              rmesa->swtcl.vertex_attr_count,
                              NULL, 0 );
       rmesa->swtcl.vertex_size /= 4;
+      rmesa->tnl_index = index;
    }
 }
 
@@ -214,13 +204,11 @@ void r200ChooseVertexState( GLcontext *ctx )
        || (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
       rmesa->swtcl.needproj = GL_TRUE;
       vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT;
-      vte &= ~R200_VTX_W0_FMT;
       vap |= R200_VAP_FORCE_W_TO_ONE;
    }
    else {
       rmesa->swtcl.needproj = GL_FALSE;
       vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
-      vte |= R200_VTX_W0_FMT;
       vap &= ~R200_VAP_FORCE_W_TO_ONE;
    }
 
@@ -737,7 +725,6 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
       GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
 
       vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
-      vte |= R200_VTX_W0_FMT;
       vap &= ~R200_VAP_FORCE_W_TO_ONE;
 
       rmesa->swtcl.vertex_size = 5;
index 746cdb4778a452d05253fdeadaad7a2f233ad8e8..78d16ed0f3b5ecd4114b49ab792a618149c6b033 100644 (file)
@@ -351,13 +351,10 @@ static void r200_check_tcl_render( GLcontext *ctx,
 
       for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
         if (ctx->Texture.Unit[unit]._ReallyEnabled) {
-           if (ctx->Texture.Unit[unit].TexGenEnabled) {
-              if (rmesa->TexGenNeedNormals[unit]) {
-                 inputs |= VERT_BIT_NORMAL;
-              }
-           } else {
-              inputs |= VERT_BIT_TEX(unit);
+           if (rmesa->TexGenNeedNormals[unit]) {
+              inputs |= VERT_BIT_NORMAL;
            }
+           inputs |= VERT_BIT_TEX(unit);
         }
       }
 
@@ -434,18 +431,6 @@ static void transition_to_swtnl( GLcontext *ctx )
     */
    R200_STATECHANGE( rmesa, vap );
    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE;
-   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_D3D_TEX_DEFAULT;
-
-   R200_STATECHANGE( rmesa, vte );
-   rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~R200_VTX_W0_FMT;
-
-   R200_STATECHANGE( rmesa, set );
-   rmesa->hw.set.cmd[SET_RE_CNTL] |= (R200_VTX_STQ0_D3D |
-                                     R200_VTX_STQ1_D3D |
-                                     R200_VTX_STQ2_D3D |
-                                     R200_VTX_STQ3_D3D |
-                                     R200_VTX_STQ4_D3D |
-                                     R200_VTX_STQ5_D3D);
 }
 
 static void transition_to_hwtnl( GLcontext *ctx )
@@ -470,21 +455,10 @@ static void transition_to_hwtnl( GLcontext *ctx )
 
    R200_STATECHANGE( rmesa, vap );
    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
-   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_FORCE_W_TO_ONE |
-                                          R200_VAP_D3D_TEX_DEFAULT);
+   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE;
 
    R200_STATECHANGE( rmesa, vte );
    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
-   rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;
-
-   R200_STATECHANGE( rmesa, set );
-   rmesa->hw.set.cmd[SET_RE_CNTL] &= ~(R200_VTX_STQ0_D3D |
-                                      R200_VTX_STQ1_D3D |
-                                      R200_VTX_STQ2_D3D |
-                                      R200_VTX_STQ3_D3D |
-                                      R200_VTX_STQ4_D3D |
-                                      R200_VTX_STQ5_D3D);
-
 
    if (R200_DEBUG & DEBUG_FALLBACKS) 
       fprintf(stderr, "R200 end tcl fallback\n");
index 57ee245ee905cd44ff39024b4d135f6a33db4162..934ffc13493da6057da37d4969e0b6d611014de5 100644 (file)
@@ -293,6 +293,12 @@ static void r200SetTexImages( r200ContextPtr rmesa,
                            (log2Width << R200_FACE_WIDTH_4_SHIFT) |
                            (log2Height << R200_FACE_HEIGHT_4_SHIFT));
    }
+   else {
+      /* If we don't in fact send enough texture coordinates, q will be 1,
+       * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
+       */
+      t->pp_txformat_x |= R200_TEXCOORD_PROJ;
+   }
 
    t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
                    ((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
@@ -836,71 +842,42 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
 }
 
 
-
-
 static void set_texgen_matrix( r200ContextPtr rmesa, 
                               GLuint unit,
                               const GLfloat *s_plane,
                               const GLfloat *t_plane,
-                              const GLfloat *r_plane )
+                              const GLfloat *r_plane,
+                              const GLfloat *q_plane )
 {
-   static const GLfloat scale_identity[4] = { 1,1,1,1 };
-
-   if (!TEST_EQ_4V( s_plane, scale_identity) ||
-       !TEST_EQ_4V( t_plane, scale_identity) ||
-       !TEST_EQ_4V( r_plane, scale_identity)) {
-      rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
-      rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];
-      rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];
-      rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];
-      rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
-
-      rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];
-      rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];
-      rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];
-      rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
-
-      /* NOTE: r_plane goes in the 4th row, not 3rd! */
-      rmesa->TexGenMatrix[unit].m[3]  = r_plane[0];
-      rmesa->TexGenMatrix[unit].m[7]  = r_plane[1];
-      rmesa->TexGenMatrix[unit].m[11] = r_plane[2];
-      rmesa->TexGenMatrix[unit].m[15] = r_plane[3];
+   GLfloat m[16];
 
-      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
-   }
-}
+   m[0]  = s_plane[0];
+   m[4]  = s_plane[1];
+   m[8]  = s_plane[2];
+   m[12] = s_plane[3];
 
-/* Need this special matrix to get correct reflection map coords */
-static void
-set_texgen_reflection_matrix( r200ContextPtr rmesa, GLuint unit )
-{
-   static const GLfloat m[16] = {
-      -1,  0,  0,  0,
-       0, -1,  0,  0,
-       0,  0,  0, -1,
-       0,  0, -1,  0 };
-   _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
-   _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
-   rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
-}
+   m[1]  = t_plane[0];
+   m[5]  = t_plane[1];
+   m[9]  = t_plane[2];
+   m[13] = t_plane[3];
+
+   m[2]  = r_plane[0];
+   m[6]  = r_plane[1];
+   m[10] = r_plane[2];
+   m[14] = r_plane[3];
+
+   m[3]  = q_plane[0];
+   m[7]  = q_plane[1];
+   m[11] = q_plane[2];
+   m[15] = q_plane[3];
 
-/* Need this special matrix to get correct normal map coords */
-static void
-set_texgen_normal_map_matrix( r200ContextPtr rmesa, GLuint unit )
-{
-   static const GLfloat m[16] = {
-      1, 0, 0, 0,
-      0, 1, 0, 0,
-      0, 0, 0, 1,
-      0, 0, 1, 0 };
    _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
    _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
    rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
 }
 
 
-/* Ignoring the Q texcoord for now.
- *
+/*
  * Returns GL_FALSE if fallback required.  
  */
 static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
@@ -908,98 +885,130 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
-   GLuint tmp = rmesa->TexGenEnabled;
+   GLuint tgi, tgcm;
+   GLuint mode = 0;
+   GLboolean mixed_fallback = GL_FALSE;
+   static const GLfloat I[16] = {
+      1,  0,  0,  0,
+      0,  1,  0,  0,
+      0,  0,  1,  0,
+      0,  0,  0,  1 };
+   static const GLfloat reflect[16] = {
+      -1,  0,  0,  0,
+       0, -1,  0,  0,
+       0,  0,  -1, 0,
+       0,  0,  0,  1 };
 
    rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
    rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
    rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
-   rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
-   rmesa->TexGenNeedNormals[unit] = 0;
+   rmesa->TexGenNeedNormals[unit] = GL_FALSE;
+   tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK <<
+                                                  inputshift);
+   tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
+                                                   (unit * 4));
 
    if (0) 
       fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
 
-   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT)) == 0) {
-      /* Disabled, no fallback:
-       */
-      rmesa->TexGenInputs |= 
-        (R200_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
-      return GL_TRUE;
+   if (texUnit->TexGenEnabled & S_BIT) {
+      mode = texUnit->GenModeS;
+   } else {
+      tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
    }
-   else if (texUnit->TexGenEnabled & Q_BIT) {
-      /* Very easy to do this, in fact would remove a fallback case
-       * elsewhere, but I haven't done it yet...  Fallback: 
-       */
-      /*fprintf(stderr, "fallback Q_BIT\n");*/
-      return GL_FALSE;
+
+   if (texUnit->TexGenEnabled & T_BIT) {
+      if (texUnit->GenModeT != mode)
+        mixed_fallback = GL_TRUE;
+   } else {
+      tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
    }
-   else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) &&
-           texUnit->GenModeS == texUnit->GenModeT) {
-      /* OK */
-      rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
-      /* continue */
+
+   if (texUnit->TexGenEnabled & R_BIT) {
+      if (texUnit->GenModeR != mode)
+        mixed_fallback = GL_TRUE;
+   } else {
+      tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
    }
-   else if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT) &&
-           texUnit->GenModeS == texUnit->GenModeT &&
-            texUnit->GenModeT == texUnit->GenModeR) {
-      /* OK */
-      rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
-      /* continue */
+
+   if (texUnit->TexGenEnabled & Q_BIT) {
+      if (texUnit->GenModeQ != mode)
+        mixed_fallback = GL_TRUE;
+   } else {
+      tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
    }
-   else {
-      /* Mixed modes, fallback:
-       */
-      /* fprintf(stderr, "fallback mixed texgen\n"); */
+
+   if (mixed_fallback) {
+      if (R200_DEBUG & DEBUG_FALLBACKS)
+        fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
+                texUnit->TexGenEnabled, texUnit->GenModeS, texUnit->GenModeT,
+                texUnit->GenModeR, texUnit->GenModeQ);
       return GL_FALSE;
    }
 
-   rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
-
-   switch (texUnit->GenModeS) {
+   switch (mode) {
    case GL_OBJECT_LINEAR:
-      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift;
+      tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
       set_texgen_matrix( rmesa, unit, 
-                        texUnit->ObjectPlaneS,
-                        texUnit->ObjectPlaneT,
-                         texUnit->ObjectPlaneR);
+        (texUnit->TexGenEnabled & S_BIT) ? texUnit->ObjectPlaneS : I,
+        (texUnit->TexGenEnabled & T_BIT) ? texUnit->ObjectPlaneT : I + 4,
+        (texUnit->TexGenEnabled & R_BIT) ? texUnit->ObjectPlaneR : I + 8,
+        (texUnit->TexGenEnabled & Q_BIT) ? texUnit->ObjectPlaneQ : I + 12);
       break;
 
    case GL_EYE_LINEAR:
-      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift;
+      tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
       set_texgen_matrix( rmesa, unit, 
-                        texUnit->EyePlaneS,
-                        texUnit->EyePlaneT,
-                        texUnit->EyePlaneR);
+        (texUnit->TexGenEnabled & S_BIT) ? texUnit->EyePlaneS : I,
+        (texUnit->TexGenEnabled & T_BIT) ? texUnit->EyePlaneT : I + 4,
+        (texUnit->TexGenEnabled & R_BIT) ? texUnit->EyePlaneR : I + 8,
+        (texUnit->TexGenEnabled & Q_BIT) ? texUnit->EyePlaneQ : I + 12);
       break;
 
    case GL_REFLECTION_MAP_NV:
       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
-      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
-      set_texgen_reflection_matrix(rmesa, unit);
+      tgi |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
+      set_texgen_matrix( rmesa, unit, 
+        (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
+        (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
+        (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
+        I + 12);
       break;
 
    case GL_NORMAL_MAP_NV:
       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
-      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
-      set_texgen_normal_map_matrix(rmesa, unit);
+      tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
       break;
 
    case GL_SPHERE_MAP:
       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
-      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
+      tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
+      /* GL_SPHERE_MAP doesn't appear to work. */
+      return GL_FALSE;
+
+   case 0:
+      /* All texgen units were disabled, so just pass coords through. */
+      tgi |= unit << inputshift;
       break;
 
    default:
       /* Unsupported mode, fallback:
        */
-      /*  fprintf(stderr, "fallback unsupported texgen\n"); */
+      if (R200_DEBUG & DEBUG_FALLBACKS)
+        fprintf(stderr, "fallback unsupported texgen, %d\n",
+                texUnit->GenModeS);
       return GL_FALSE;
    }
 
+   rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
    rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
 
-   if (tmp != rmesa->TexGenEnabled) {
-      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+   if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] || 
+       tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
+   {
+      R200_STATECHANGE(rmesa, tcg);
+      rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi;
+      rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm;
    }
 
    return GL_TRUE;
@@ -1042,15 +1051,12 @@ static void disable_tex( GLcontext *ctx, int unit )
 
 
       {
-        GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
         GLuint tmp = rmesa->TexGenEnabled;
 
         rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
         rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
-        rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
-        rmesa->TexGenNeedNormals[unit] = 0;
+        rmesa->TexGenNeedNormals[unit] = GL_FALSE;
         rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
-        rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
 
         if (tmp != rmesa->TexGenEnabled) {
            rmesa->recheck_texgen[unit] = GL_TRUE;
@@ -1060,6 +1066,22 @@ static void disable_tex( GLcontext *ctx, int unit )
    }
 }
 
+static void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
+{
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+
+   GLuint re_cntl;
+
+   re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
+   if (use_d3d)
+      re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
+
+   if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
+      R200_STATECHANGE( rmesa, set );
+      rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
+   }
+}
+
 static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -1084,6 +1106,8 @@ static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
         return GL_FALSE;
    }
 
+   set_re_cntl_d3d( ctx, unit, GL_FALSE );
+
    return GL_TRUE;
 }
 
@@ -1118,6 +1142,8 @@ static GLboolean enable_tex_3d( GLcontext *ctx, int unit )
         return GL_FALSE;
    }
 
+   set_re_cntl_d3d( ctx, unit, GL_TRUE );
+
    return GL_TRUE;
 }
 #endif
@@ -1161,6 +1187,8 @@ static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
       return GL_FALSE;
    }
 
+   set_re_cntl_d3d( ctx, unit, GL_TRUE );
+
    return GL_TRUE;
 }
 
@@ -1186,6 +1214,8 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
         return GL_FALSE;
    }
 
+   set_re_cntl_d3d( ctx, unit, GL_FALSE );
+
    return GL_TRUE;
 }
 
@@ -1230,6 +1260,7 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit )
                                         R200_TEX_BLEND_0_ENABLE) << unit;
 
       R200_STATECHANGE( rmesa, vtx );
+      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
 
       rmesa->recheck_texgen[unit] = GL_TRUE;
index bd0003e127e1b70ab6851627e4c1f6c0af41b61c..7a2fa35d44f368d550335069d91f00d533fd5f2b 100644 (file)
@@ -401,24 +401,6 @@ static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller )
  * to look-up the table, and a specialized version of GL_CALL that used the
  * offset number instead of the name.
  */
-static void dispatch_texcoord( GLuint count, GLfloat * f )
-{
-   switch( count ) {
-   case 3:
-      GL_CALL(TexCoord3fv)( f );
-      break;
-   case 2:
-      GL_CALL(TexCoord2fv)( f );
-      break;
-   case 1:
-      GL_CALL(TexCoord1fv)( f );
-      break;
-   default:
-      assert( count == 0 );
-      break;
-   }
-}
-
 static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f )
 {
    switch( count ) {
@@ -437,7 +419,7 @@ static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f )
    }
 }
 
-static void VFMT_FALLBACK( const char *caller )
+void VFMT_FALLBACK( const char *caller )
 {
    GET_CURRENT_CONTEXT(ctx);
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -663,8 +645,6 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
    GLuint ind1 = 0;
    GLuint i;
    GLuint count[R200_MAX_TEXTURE_UNITS];
-   GLuint re_cntl;
-
 
    if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
       return GL_FALSE;
@@ -692,26 +672,16 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
       }
    }
 
-   re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D |
-                                               R200_VTX_STQ1_D3D |
-                                               R200_VTX_STQ2_D3D |
-                                               R200_VTX_STQ3_D3D |
-                                               R200_VTX_STQ4_D3D |
-                                               R200_VTX_STQ5_D3D );
    for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
       count[i] = 0;
 
       if (ctx->Texture.Unit[i]._ReallyEnabled) {
-        if (ctx->Texture.Unit[i].TexGenEnabled) {
-           if (rmesa->TexGenNeedNormals[i]) {
-              ind0 |= R200_VTX_N0;
-           }
+        if (rmesa->TexGenNeedNormals[i]) {
+           ind0 |= R200_VTX_N0;
         }
         else {
            switch( ctx->Texture.Unit[i]._ReallyEnabled ) {
            case TEXTURE_CUBE_BIT:
-              re_cntl |= R200_VTX_STQ0_D3D << (2 * i);
-              /* FALLTHROUGH */
            case TEXTURE_3D_BIT:
               count[i] = 3;
               break;
@@ -729,11 +699,6 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
       }
    }
 
-   if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
-      R200_STATECHANGE( rmesa, set );
-      rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
-   }
-
    if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE))
       fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 );
 
index 39f0a10e4eb15c13062ca6056c98fffed2ed856c..071a74082ff3633be780c5cc5e5770fd27a99527 100644 (file)
@@ -52,6 +52,7 @@ extern void r200VtxfmtMakeCurrent( GLcontext *ctx );
 extern void r200VtxfmtUnbindContext( GLcontext *ctx );
 
 extern void r200_copy_to_current( GLcontext *ctx );
+extern void VFMT_FALLBACK( const char *caller );
 
 #define DFN( FUNC, CACHE)                              \
 do {                                                   \
index 9f40b18c9d259004546dfe66ce43f77154eba5f9..70301afb04e33126c432a1f113a98b71b1d61a8d 100644 (file)
@@ -515,66 +515,118 @@ static void r200_Normal3fv( const GLfloat *v )
 /* TexCoord
  */
 
-#define TEX_to_nF(N, P, S, T, R)                                       \
-   static void r200_TexCoord ## N P                                    \
-   {                                                                   \
-      GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); \
-      GLfloat * const dest = rmesa->vb.texcoordptr[0];                 \
-      switch( ctx->Texture.Unit[0]._ReallyEnabled ) {                  \
-      case TEXTURE_CUBE_BIT:                                           \
-      case TEXTURE_3D_BIT:                                             \
-        dest[2] = R;                                                   \
-      case TEXTURE_2D_BIT:                                             \
-      case TEXTURE_RECT_BIT:                                           \
-        dest[1] = T;                                                   \
-      case TEXTURE_1D_BIT:                                             \
-        dest[0] = S;                                                   \
-      }                                                                        \
+/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */
+static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLint unit = (target & 7);
+   GLfloat * const dest = rmesa->vb.texcoordptr[unit];
+
+   switch( ctx->Texture.Unit[unit]._ReallyEnabled ) {
+   case TEXTURE_CUBE_BIT:
+   case TEXTURE_3D_BIT:
+      dest[2] = 0.0;
+      /* FALLTHROUGH */
+   case TEXTURE_2D_BIT:
+   case TEXTURE_RECT_BIT:
+      dest[1] = 0.0;
+      /* FALLTHROUGH */
+   case TEXTURE_1D_BIT:
+      dest[0] = s;
    }
+}
 
-TEX_to_nF( 1f,  (GLfloat s),                       s,    0.0,  0.0 )
-TEX_to_nF( 2f,  (GLfloat s, GLfloat t),            s,    t,    0.0 )
-TEX_to_nF( 3f,  (GLfloat s, GLfloat t, GLfloat r), s,    t,    r )
-TEX_to_nF( 1fv, (const GLfloat * v),               v[0], 0.0,  0.0 )
-TEX_to_nF( 2fv, (const GLfloat * v),               v[0], v[1], 0.0 )
-TEX_to_nF( 3fv, (const GLfloat * v),               v[0], v[1], v[2] )
-
-
-/* MultiTexcoord
- * 
- * Technically speaking, these functions should subtract GL_TEXTURE0 from
- * \c target before masking and using it.  The value of GL_TEXTURE0 is 0x84C0,
- * which has the low-order 5 bits 0.  For all possible valid values of 
- * \c target.  Subtracting GL_TEXTURE0 has the net effect of masking \c target
- * with 0x1F.  Masking with 0x1F and then masking with 0x07 is redundant, so
- * the subtraction has been omitted.
- */
+static void r200_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLint unit = (target & 7);
+   GLfloat * const dest = rmesa->vb.texcoordptr[unit];
 
-#define MTEX_to_nF(N, P, U, S, T, R)                                   \
-   static void r200_MultiTexCoord ## N ## ARB P                                \
-   {                                                                   \
-      GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); \
-      GLfloat * const dest = rmesa->vb.texcoordptr[U];                 \
-      switch( ctx->Texture.Unit[U]._ReallyEnabled ) {                  \
-      case TEXTURE_CUBE_BIT:                                           \
-      case TEXTURE_3D_BIT:                                             \
-        dest[2] = R;                                                   \
-      case TEXTURE_2D_BIT:                                             \
-      case TEXTURE_RECT_BIT:                                           \
-        dest[1] = T;                                                   \
-      case TEXTURE_1D_BIT:                                             \
-        dest[0] = S;                                                   \
-      }                                                                        \
+   switch( ctx->Texture.Unit[unit]._ReallyEnabled ) {
+   case TEXTURE_CUBE_BIT:
+   case TEXTURE_3D_BIT:
+      dest[2] = 0.0;
+      /* FALLTHROUGH */
+   case TEXTURE_2D_BIT:
+   case TEXTURE_RECT_BIT:
+      dest[1] = t;
+      dest[0] = s;
+      break;
+   default:
+      VFMT_FALLBACK(__FUNCTION__);
+      GL_CALL(MultiTexCoord2fARB)(target, s, t);
+      return;  
    }
+}
 
-/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */
-MTEX_to_nF( 1f, (GLenum target, GLfloat s), (target & 7), s, 0.0, 0.0 )
-MTEX_to_nF( 2f, (GLenum target, GLfloat s, GLfloat t), (target & 7), s, t, 0.0 )
-MTEX_to_nF( 3f, (GLenum target, GLfloat s, GLfloat t, GLfloat r), (target & 7), s, t, r )
+static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLint unit = (target & 7);
+   GLfloat * const dest = rmesa->vb.texcoordptr[unit];
+
+   switch( ctx->Texture.Unit[unit]._ReallyEnabled ) {
+   case TEXTURE_CUBE_BIT:
+   case TEXTURE_3D_BIT:
+      dest[2] = r;
+      dest[1] = t;
+      dest[0] = s;
+      break;
+   default:
+      VFMT_FALLBACK(__FUNCTION__);
+      GL_CALL(MultiTexCoord3fARB)(target, s, t, r);
+      return;  
+   }
+}
+
+static void r200_TexCoord1f(GLfloat s)
+{
+   r200_MultiTexCoord1fARB(GL_TEXTURE0, s);
+}
+
+static void r200_TexCoord2f(GLfloat s, GLfloat t)
+{
+   r200_MultiTexCoord2fARB(GL_TEXTURE0, s, t);
+}
+
+static void r200_TexCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+   r200_MultiTexCoord3fARB(GL_TEXTURE0, s, t, r);
+}
+
+static void r200_TexCoord1fv(const GLfloat *v)
+{
+   r200_MultiTexCoord1fARB(GL_TEXTURE0, v[0]);
+}
+
+static void r200_TexCoord2fv(const GLfloat *v)
+{
+   r200_MultiTexCoord2fARB(GL_TEXTURE0, v[0], v[1]);
+}
+
+static void r200_TexCoord3fv(const GLfloat *v)
+{
+   r200_MultiTexCoord3fARB(GL_TEXTURE0, v[0], v[1], v[2]);
+}
+
+static void r200_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
+{
+   r200_MultiTexCoord1fARB(target, v[0]);
+}
+
+static void r200_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
+{
+   r200_MultiTexCoord2fARB(target, v[0], v[1]);
+}
+
+static void r200_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
+{
+   r200_MultiTexCoord3fARB(target, v[0], v[1], v[2]);
+}
 
-MTEX_to_nF( 1fv, (GLenum target, const GLfloat *v), (target & 7), v[0], 0.0, 0.0 )
-MTEX_to_nF( 2fv, (GLenum target, const GLfloat *v), (target & 7), v[0], v[1], 0.0 )
-MTEX_to_nF( 3fv, (GLenum target, const GLfloat *v), (target & 7), v[0], v[1], v[2] )
 
 static struct dynfn *lookup( struct dynfn *l, const int *key )
 {