Keith Whitwell wrote:
Ian Romanick wrote:

This is what I have done so far to convert the R200 driver to use t_vertex. It is only a conversion for SW TCL, and it's not quite complete. I've managed to clean up all the crashes that I could find, but I've only tested with gears, geartrain, and tunnel. There are some known problems:

- The textures in tunnel are not quite right. They're sort of zig-zaggy.
- The colors of two of the gears in gears are swapped. The red gear is blue and the blue gear is red. The green gear is correct.


I chopped out all of the _r200_render_stage stuff from r200_swtcl.c. It is unused (due to bad interactions with UT2k3), and was only confusing me. When this patch gets committed, that code can go back in, I think.

There are two hacks that I had to do to get things working. Neither of these needed to be done by the i830 or savage drivers. First, I had to add a "viewport" matrix that remains an identity matrix. This is because the Radeon chips do the viewport transform in hardware. tnl_dd/t_dd_vbtmp.h had the ability to handle hardware like this, but t_vertex apparently does not. Second, I had to force TNL to always produce project coordinates. Again, the Radeon hardware can do the final projection in hardware almost all the time, but due to the way the i830 and savage drivers use use tnl->vb.NdcPtr (actually VB->NdcPtr) I couldn't see a way around this. I may just be missing something there.


Ah, ok. I see the problem. Basically this has to do with the fact that choosing the hw vertex format has gone from being something (normally) done ahead of time, prior to actually running the tnl pipeline, to something done after that, and based on its results. The only problem is that by this time, the pipeline has run, and it's too late to decide whether or not to calculate projected coordinates. Oh well, it's not too hard to do that ahead of time.

Here's an updated patch. In addition to the above, I've fixed up the way 'coloroffset' and the previously hardwired 'specoffset' are initialized. Most stuff seems to work ok now, except tuxracer-demo, which has issues which are probably related to polygon offset.


Keith
? diff
? drivers/dri/diff
? drivers/dri/common/diff
? drivers/dri/i830/diff
? drivers/dri/r200/diff
? drivers/dri/tdfx/diff
? tnl/backout
? tnl/c
? tnl/dead
? tnl/diff
? tnl_dd/diff
Index: drivers/dri/r200/r200_context.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_context.h,v
retrieving revision 1.12
diff -u -r1.12 r200_context.h
--- a/drivers/dri/r200/r200_context.h   11 Mar 2004 20:35:40 -0000      1.12
+++ b/drivers/dri/r200/r200_context.h   18 Apr 2004 12:13:36 -0000
@@ -39,6 +39,7 @@
 #ifdef GLX_DIRECT_RENDERING
 
 #include <inttypes.h>
+#include "tnl/t_vertex.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "dri_util.h"
@@ -611,12 +612,13 @@
 /* r200_swtcl.c
  */
 struct r200_swtcl_info {
-   GLuint SetupIndex;
-   GLuint SetupNewInputs;
    GLuint RenderIndex;
    GLuint vertex_size;
-   GLuint vertex_stride_shift;
-   GLuint vertex_format;
+
+   struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+   GLuint vertex_attr_count;
+
+
    GLubyte *verts;
 
    /* Fallback rasterization functions
@@ -629,6 +631,11 @@
    GLenum render_primitive;
    GLuint numverts;
 
+   GLboolean needproj;
+   
+   GLuint coloroffset;
+   GLuint specoffset;
+
    struct r200_dma_region indexed_verts;
 };
 
Index: drivers/dri/r200/r200_swtcl.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_swtcl.c,v
retrieving revision 1.9
diff -u -r1.9 r200_swtcl.c
--- a/drivers/dri/r200/r200_swtcl.c     20 Jan 2004 02:49:27 -0000      1.9
+++ b/drivers/dri/r200/r200_swtcl.c     18 Apr 2004 12:13:37 -0000
@@ -56,323 +56,185 @@
 #include "r200_swtcl.h"
 #include "r200_tcl.h"
 
-/***********************************************************************
- *              Build render functions from dd templates               *
- ***********************************************************************/
-
-
-#define R200_XYZW_BIT          0x01
-#define R200_RGBA_BIT          0x02
-#define R200_SPEC_BIT          0x04
-#define R200_TEX0_BIT          0x08
-#define R200_TEX1_BIT          0x10
-#define R200_PTEX_BIT          0x20
-#define R200_MAX_SETUP 0x40
 
 static void flush_last_swtcl_prim( r200ContextPtr rmesa  );
 
-static struct {
-   void                (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
-   interp_func         interp;
-   copy_pv_func                copy_pv;
-   GLboolean           (*check_tex_sizes)( GLcontext *ctx );
-   GLuint               vertex_size;
-   GLuint               vertex_format;
-} setup_tab[R200_MAX_SETUP];
-
-
-static int se_vtx_fmt_0[] = {
-   0,
-
-   (R200_VTX_XY |
-    R200_VTX_Z0 |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT)),
-
-   (R200_VTX_XY |
-    R200_VTX_Z0 |
-    R200_VTX_W0 |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)),
-
-   (R200_VTX_XY |
-    R200_VTX_Z0 |
-    R200_VTX_W0 |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)),
-
-   (R200_VTX_XY |
-    R200_VTX_Z0 |
-    R200_VTX_W0 |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT)),
-
-   (R200_VTX_XY |
-    R200_VTX_Z0 |
-    R200_VTX_W0 |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) |
-    (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT))
-};
-
-static int se_vtx_fmt_1[] = {
-   0,
-   0,
-   0,
-   ((2 << R200_VTX_TEX0_COMP_CNT_SHIFT)),
-   ((2 << R200_VTX_TEX0_COMP_CNT_SHIFT) |
-    (2 << R200_VTX_TEX1_COMP_CNT_SHIFT)),
-   ((3 << R200_VTX_TEX0_COMP_CNT_SHIFT) |
-    (3 << R200_VTX_TEX1_COMP_CNT_SHIFT)),
-};
-
-#define TINY_VERTEX_FORMAT     1
-#define NOTEX_VERTEX_FORMAT    2
-#define TEX0_VERTEX_FORMAT     3
-#define TEX1_VERTEX_FORMAT     4
-#define PROJ_TEX1_VERTEX_FORMAT        5
-#define TEX2_VERTEX_FORMAT 0
-#define TEX3_VERTEX_FORMAT 0
-#define PROJ_TEX3_VERTEX_FORMAT 0
-
-#define DO_XYZW (IND & R200_XYZW_BIT)
-#define DO_RGBA (IND & R200_RGBA_BIT)
-#define DO_SPEC (IND & R200_SPEC_BIT)
-#define DO_FOG  (IND & R200_SPEC_BIT)
-#define DO_TEX0 (IND & R200_TEX0_BIT)
-#define DO_TEX1 (IND & R200_TEX1_BIT)
-#define DO_TEX2 0
-#define DO_TEX3 0
-#define DO_PTEX (IND & R200_PTEX_BIT)
-
-#define VERTEX r200Vertex
-#define VERTEX_COLOR r200_color_t
-#define GET_VIEWPORT_MAT() 0
-#define GET_TEXSOURCE(n)  n
-#define GET_VERTEX_FORMAT() R200_CONTEXT(ctx)->swtcl.vertex_format
-#define GET_VERTEX_STORE() R200_CONTEXT(ctx)->swtcl.verts
-#define GET_VERTEX_SIZE() R200_CONTEXT(ctx)->swtcl.vertex_size * sizeof(GLuint)
-
-#define HAVE_HW_VIEWPORT    1
-#define HAVE_HW_DIVIDE      (IND & ~(R200_XYZW_BIT|R200_RGBA_BIT))
-#define HAVE_TINY_VERTICES  1
-#define HAVE_RGBA_COLOR     1
-#define HAVE_NOTEX_VERTICES 1
-#define HAVE_TEX0_VERTICES  1
-#define HAVE_TEX1_VERTICES  1
-#define HAVE_TEX2_VERTICES  0
-#define HAVE_TEX3_VERTICES  0
-#define HAVE_PTEX_VERTICES  1
-
-#define CHECK_HW_DIVIDE    (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE| \
-                                                    DD_TRI_UNFILLED)))
-
-#define INTERP_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].interp
-#define COPY_PV_VERTEX setup_tab[R200_CONTEXT(ctx)->swtcl.SetupIndex].copy_pv
-
-
-/***********************************************************************
- *         Generate  pv-copying and translation functions              *
- ***********************************************************************/
-
-#define TAG(x) r200_##x
-#define IND ~0
-#include "tnl_dd/t_dd_vb.c"
-#undef IND
-
-
-/***********************************************************************
- *             Generate vertex emit and interp functions               *
- ***********************************************************************/
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT)
-#define TAG(x) x##_wg
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT)
-#define TAG(x) x##_wgt0
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_PTEX_BIT)
-#define TAG(x) x##_wgpt0
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT)
-#define TAG(x) x##_wgt0t1
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_TEX0_BIT|R200_TEX1_BIT|\
-             R200_PTEX_BIT)
-#define TAG(x) x##_wgpt0t1
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT)
-#define TAG(x) x##_wgfs
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
-            R200_TEX0_BIT)
-#define TAG(x) x##_wgfst0
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
-            R200_TEX0_BIT|R200_PTEX_BIT)
-#define TAG(x) x##_wgfspt0
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
-            R200_TEX0_BIT|R200_TEX1_BIT)
-#define TAG(x) x##_wgfst0t1
-#include "tnl_dd/t_dd_vbtmp.h"
-
-#define IND (R200_XYZW_BIT|R200_RGBA_BIT|R200_SPEC_BIT|\
-            R200_TEX0_BIT|R200_TEX1_BIT|R200_PTEX_BIT)
-#define TAG(x) x##_wgfspt0t1
-#include "tnl_dd/t_dd_vbtmp.h"
-
 
 /***********************************************************************
  *                         Initialization 
  ***********************************************************************/
 
-static void init_setup_tab( void )
-{
-   init_wg();
-   init_wgt0();
-   init_wgpt0();
-   init_wgt0t1();
-   init_wgpt0t1();
-   init_wgfs();
-   init_wgfst0();
-   init_wgfspt0();
-   init_wgfst0t1();
-   init_wgfspt0t1();
-}
-
-
-
-void r200PrintSetupFlags(char *msg, GLuint flags )
-{
-   fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
-          msg,
-          (int)flags,
-          (flags & R200_XYZW_BIT)      ? " xyzw," : "",
-          (flags & R200_RGBA_BIT)     ? " rgba," : "",
-          (flags & R200_SPEC_BIT)     ? " spec/fog," : "",
-          (flags & R200_TEX0_BIT)     ? " tex-0," : "",
-          (flags & R200_TEX1_BIT)     ? " tex-1," : "",
-          (flags & R200_PTEX_BIT)     ? " proj-tex," : "");
-}
-
+#define EMIT_SZ(sz)   (EMIT_1F + (sz) - 1)
+#define EMIT_ATTR( ATTR, STYLE, F0, F1, SZ )                           \
+do {                                                                   \
+   rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR);  \
+   rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = (STYLE); \
+   rmesa->swtcl.vertex_attr_count++;                                   \
+   fmt_0 |= F0;                                                                \
+   fmt_1 |= F1;                                                                \
+   offset += SZ;                                                       \
+} while (0)
 
+#define EMIT_PAD( N )                                                  \
+do {                                                                   \
+   rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = 0;              
 \
+   rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].format = EMIT_PAD;       
 \
+   rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].offset = (N);            
 \
+   rmesa->swtcl.vertex_attr_count++;                                   \
+   offset += N;                                                        \
+} while (0)
 
-static void r200SetVertexFormat( GLcontext *ctx, GLuint ind ) 
+static void r200SetVertexFormat( GLcontext *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-
-   rmesa->swtcl.SetupIndex = ind;
-
-   if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
-      tnl->Driver.Render.Interp = r200_interp_extras;
-      tnl->Driver.Render.CopyPV = r200_copy_pv_extras;
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint index = tnl->render_inputs;
+   int fmt_0 = 0;
+   int fmt_1 = 0;
+   int offset = 0;
+
+   rmesa->swtcl.vertex_attr_count = 0;
+
+   /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
+    * build up a hardware vertex.
+    */
+   if (rmesa->swtcl.needproj) {
+      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F, 
+                R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0, 0, 16 );
    }
    else {
-      tnl->Driver.Render.Interp = setup_tab[ind].interp;
-      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F, 
+                R200_VTX_XY | R200_VTX_Z0, 0, 12 );
    }
 
-   if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) {
-      int i;
-      R200_NEWPRIM(rmesa);
-      i = rmesa->swtcl.vertex_format = setup_tab[ind].vertex_format;
-      rmesa->swtcl.vertex_size = setup_tab[ind].vertex_size;
-
-      R200_STATECHANGE( rmesa, vtx );
-      rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = se_vtx_fmt_0[i];
-      rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = se_vtx_fmt_1[i];
-   }
+   rmesa->swtcl.coloroffset = offset / 4;
+   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, 
+             (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT), 0, 4 );
 
-   {
-      GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
-      GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
-      GLuint needproj;
+   if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
 
-      /* HW perspective divide is a win, but tiny vertex formats are a
-       * bigger one.
-       */
-      if (setup_tab[ind].vertex_format == TINY_VERTEX_FORMAT ||
-         (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
-        needproj = GL_TRUE;
-        vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT;
-        vte &= ~R200_VTX_W0_FMT;
-        vap |= R200_VAP_FORCE_W_TO_ONE;
+      if (index & _TNL_BIT_COLOR1) {
+        rmesa->swtcl.specoffset = offset / 4;
+        EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB, 
+                   (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT), 0, 3 );
       }
       else {
-        needproj = GL_FALSE;
-        vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
-        vte |= R200_VTX_W0_FMT;
-        vap &= ~R200_VAP_FORCE_W_TO_ONE;
+        EMIT_PAD( 3 );
       }
 
-      _tnl_need_projected_coords( ctx, needproj );
-      if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
-        R200_STATECHANGE( rmesa, vte );
-        rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
+      if (index & _TNL_BIT_FOG) {
+        EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, 
+                   (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT), 0, 1 );
       }
-      if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
-        R200_STATECHANGE( rmesa, vap );
-        rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
+      else {
+        EMIT_PAD( 1 );
       }
    }
-}
 
-static void r200RenderStart( GLcontext *ctx )
-{
-   r200ContextPtr rmesa = R200_CONTEXT( ctx );
+   if (index & _TNL_BITS_TEX_ANY) {
+      int i;
 
-   if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) {
-      r200SetVertexFormat( ctx, rmesa->swtcl.SetupIndex | R200_PTEX_BIT);
+      /* Still using 2 as max tex units, but this code is fine for all
+       * 8 units supported by mesa:
+       */
+      for (i = 0; i < 2; i++) {
+        if (index & _TNL_BIT_TEX(i)) {
+           GLuint sz = VB->TexCoordPtr[i]->size;
+           GLuint emit;
+
+           /* r200 doesn't like 1D or 4D texcoords (is that true?):
+            */
+           switch (sz) {
+           case 1: 
+           case 2: 
+           case 3:             /* no attempt at cube texturing so far */
+              emit = EMIT_2F; 
+              sz = 2; 
+              break;
+           case 4: 
+              emit = EMIT_3F_XYW; 
+              sz = 3;     
+              break;
+           default: 
+              continue;
+           };
+       
+           EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0,
+                      (sz << (3 * i)), sz * 4);
+        }
+      }
+   }
+
+
+
+   if ( 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;
+      rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = fmt_1;
+
+      rmesa->swtcl.vertex_size =
+         _tnl_install_attrs( ctx,
+                             rmesa->swtcl.vertex_attrs, 
+                             rmesa->swtcl.vertex_attr_count,
+                             0, 0 );
+
+      assert(rmesa->swtcl.vertex_size == offset);
+      rmesa->swtcl.vertex_size /= 4;
    }
-   
-   if (rmesa->dma.flush != 0 && 
-       rmesa->dma.flush != flush_last_swtcl_prim)
-      rmesa->dma.flush( rmesa );
 }
 
 
-void r200BuildVertices( GLcontext *ctx, GLuint start, GLuint count,
-                          GLuint newinputs )
+static void r200RenderStart( GLcontext *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
-   GLuint stride = rmesa->swtcl.vertex_size * sizeof(int);
-   GLubyte *v = ((GLubyte *)rmesa->swtcl.verts + (start * stride));
 
-   newinputs |= rmesa->swtcl.SetupNewInputs;
-   rmesa->swtcl.SetupNewInputs = 0;
+   r200SetVertexFormat( ctx );
 
-   if (!newinputs)
-      return;
-
-   setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, v, stride );
+   if (rmesa->dma.flush != 0 && 
+       rmesa->dma.flush != flush_last_swtcl_prim)
+      rmesa->dma.flush( rmesa );
 }
 
 
 void r200ChooseVertexState( GLcontext *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
-   GLuint ind = (R200_XYZW_BIT | R200_RGBA_BIT);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
-   if (!rmesa->TclFallback || rmesa->Fallback)
-      return;
+   GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
+   GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
 
-   if (ctx->Fog.Enabled || (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
-      ind |= R200_SPEC_BIT;
+   /* HW perspective divide is a win, but tiny vertex formats are a
+    * bigger one.
+    */
+   if (!(tnl->render_inputs & _TNL_BITS_TEX_ANY) ||
+       (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;
+   }
 
-   if (ctx->Texture._EnabledUnits & 0x2)  /* unit 1 enabled */
-      ind |= R200_TEX0_BIT|R200_TEX1_BIT;
-   else if (ctx->Texture._EnabledUnits & 0x1)  /* unit 1 enabled */
-      ind |= R200_TEX0_BIT;
+   _tnl_need_projected_coords( ctx, rmesa->swtcl.needproj );
+
+   if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
+      R200_STATECHANGE( rmesa, vte );
+      rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
+   }
 
-   r200SetVertexFormat( ctx, ind );
+   if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
+      R200_STATECHANGE( rmesa, vap );
+      rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
+   }
 }
 
 
@@ -445,251 +307,6 @@
 }
 
 
-
-
-static void *r200_emit_contiguous_verts( GLcontext *ctx, 
-                                        GLuint start, 
-                                        GLuint count,
-                                        void *dest)
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   GLuint stride = rmesa->swtcl.vertex_size * 4;
-   setup_tab[rmesa->swtcl.SetupIndex].emit( ctx, start, count, dest, stride );
-   return (void *)((char *)dest + stride * (count - start));
-}
-
-
-
-void r200_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
-   r200AllocDmaRegionVerts( rmesa, 
-                             &rmesa->swtcl.indexed_verts, 
-                             count - start,
-                             rmesa->swtcl.vertex_size * 4, 
-                             64);
-
-   setup_tab[rmesa->swtcl.SetupIndex].emit( 
-      ctx, start, count, 
-      rmesa->swtcl.indexed_verts.address + rmesa->swtcl.indexed_verts.start, 
-      rmesa->swtcl.vertex_size * 4 );
-}
-
-
-/*
- * Render unclipped vertex buffers by emitting vertices directly to
- * dma buffers.  Use strip/fan hardware primitives where possible.
- * Try to simulate missing primitives with indexed vertices.
- */
-#define HAVE_POINTS      1
-#define HAVE_LINES       1
-#define HAVE_LINE_STRIPS 1
-#define HAVE_TRIANGLES   1
-#define HAVE_TRI_STRIPS  1
-#define HAVE_TRI_STRIP_1 0
-#define HAVE_TRI_FANS    1
-#define HAVE_QUADS       1
-#define HAVE_QUAD_STRIPS 1
-#define HAVE_POLYGONS    1
-#define HAVE_ELTS        1
-
-static const GLuint hw_prim[GL_POLYGON+1] = {
-   R200_VF_PRIM_POINTS,
-   R200_VF_PRIM_LINES,
-   0,
-   R200_VF_PRIM_LINE_STRIP,
-   R200_VF_PRIM_TRIANGLES,
-   R200_VF_PRIM_TRIANGLE_STRIP,
-   R200_VF_PRIM_TRIANGLE_FAN,
-   R200_VF_PRIM_QUADS,
-   R200_VF_PRIM_QUAD_STRIP,
-   R200_VF_PRIM_POLYGON
-};
-
-static __inline void r200DmaPrimitive( r200ContextPtr rmesa, GLenum prim )
-{
-   R200_NEWPRIM( rmesa );
-   rmesa->swtcl.hw_primitive = hw_prim[prim];
-   assert(rmesa->dma.current.ptr == rmesa->dma.current.start);
-}
-
-static __inline void r200EltPrimitive( r200ContextPtr rmesa, GLenum prim )
-{
-   R200_NEWPRIM( rmesa );
-   rmesa->swtcl.hw_primitive = hw_prim[prim] | R200_VF_PRIM_WALK_IND;
-}
-
-
-
-
-#define LOCAL_VARS r200ContextPtr rmesa = R200_CONTEXT(ctx)
-#define ELTS_VARS(buf)  GLushort *dest = buf
-#define INIT( prim ) r200DmaPrimitive( rmesa, prim )
-#define ELT_INIT(prim) r200EltPrimitive( rmesa, prim )
-#define FLUSH()  R200_NEWPRIM( rmesa )
-#define GET_CURRENT_VB_MAX_VERTS() \
-  (((int)rmesa->dma.current.end - (int)rmesa->dma.current.ptr) / 
(rmesa->swtcl.vertex_size*4))
-#define GET_SUBSEQUENT_VB_MAX_VERTS() \
-  ((RADEON_BUFFER_SIZE) / (rmesa->swtcl.vertex_size*4))
-
-#define GET_CURRENT_VB_MAX_ELTS() \
-  ((R200_CMD_BUF_SZ - (rmesa->store.cmd_used + 16)) / 2)
-#define GET_SUBSEQUENT_VB_MAX_ELTS() \
-  ((R200_CMD_BUF_SZ - 1024) / 2)
-
-static void *r200_alloc_elts( r200ContextPtr rmesa, int nr )
-{
-   if (rmesa->dma.flush == r200FlushElts &&
-       rmesa->store.cmd_used + nr*2 < R200_CMD_BUF_SZ) {
-
-      rmesa->store.cmd_used += nr*2;
-
-      return (void *)(rmesa->store.cmd_buf + rmesa->store.cmd_used);
-   }
-   else {
-      if (rmesa->dma.flush) {
-        rmesa->dma.flush( rmesa );
-      }
-
-      r200EmitVertexAOS( rmesa,
-                          rmesa->swtcl.vertex_size,
-                          (rmesa->r200Screen->gart_buffer_offset +
-                           rmesa->swtcl.indexed_verts.buf->buf->idx *
-                           RADEON_BUFFER_SIZE +
-                           rmesa->swtcl.indexed_verts.start));
-
-      return (void *) r200AllocEltsOpenEnded( rmesa,
-                                             rmesa->swtcl.hw_primitive,
-                                             nr );
-   }
-}
-
-#define ALLOC_ELTS(nr) r200_alloc_elts(rmesa, nr)
-
-
-
-#ifdef MESA_BIG_ENDIAN
-/* We could do without (most of) this ugliness if dest was always 32 bit word 
aligned... */
-#define EMIT_ELT(offset, x) do {                                \
-        int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 );     \
-        GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 );    \
-        (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
-#else
-#define EMIT_ELT(offset, x) (dest)[offset] = (GLushort) (x)
-#endif
-#define EMIT_TWO_ELTS(offset, x, y)  *(GLuint *)(dest+offset) = ((y)<<16)|(x);
-#define INCR_ELTS( nr ) dest += nr
-#define ELTPTR dest
-#define RELEASE_ELT_VERTS() \
-  r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ )
-
-#define EMIT_INDEXED_VERTS( ctx, start, count ) \
-  r200_emit_indexed_verts( ctx, start, count )
-
-
-#define ALLOC_VERTS( nr ) \
-  r200AllocDmaLowVerts( rmesa, nr, rmesa->swtcl.vertex_size * 4 )
-#define EMIT_VERTS( ctx, j, nr, buf ) \
-  r200_emit_contiguous_verts(ctx, j, (j)+(nr), buf)
-
-
-
-#define TAG(x) r200_dma_##x
-#include "tnl_dd/t_dd_dmatmp.h"
-
-
-/**********************************************************************/
-/*                          Render pipeline stage                     */
-/**********************************************************************/
-
-
-
-static GLboolean r200_run_render( GLcontext *ctx,
-                                   struct tnl_pipeline_stage *stage )
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct vertex_buffer *VB = &tnl->vb;
-   GLuint i;
-   render_func *tab = TAG(render_tab_verts);
-
-   if (rmesa->swtcl.indexed_verts.buf && (!VB->Elts || stage->changed_inputs)) 
-      RELEASE_ELT_VERTS();
-       
-   
-
-   if ((R200_DEBUG & DEBUG_VERTS) ||
-       rmesa->swtcl.RenderIndex != 0 ||
-       !r200_dma_validate_render( ctx, VB ))
-      return GL_TRUE;          
-
-   if (VB->Elts) {
-      tab = TAG(render_tab_elts);
-      if (!rmesa->swtcl.indexed_verts.buf) {
-        if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
-           return GL_TRUE;
-        EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
-      }
-   }
-
-   tnl->Driver.Render.Start( ctx );
-
-   for (i = 0 ; i < VB->PrimitiveCount ; i++)
-   {
-      GLuint prim = VB->Primitive[i].mode;
-      GLuint start = VB->Primitive[i].start;
-      GLuint length = VB->Primitive[i].count;
-
-      if (!length)
-        continue;
-
-      if (R200_DEBUG & DEBUG_PRIMS)
-        fprintf(stderr, "r200_render.c: prim %s %d..%d\n", 
-                _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK), 
-                start, start+length);
-
-      tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim );
-   }
-
-   tnl->Driver.Render.Finish( ctx );
-
-   return GL_FALSE;            /* finished the pipe */
-}
-
-
-
-static void r200_check_render( GLcontext *ctx,
-                                struct tnl_pipeline_stage *stage )
-{
-   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
-}
-
-
-static void dtr( struct tnl_pipeline_stage *stage )
-{
-   (void)stage;
-}
-
-
-const struct tnl_pipeline_stage _r200_render_stage =
-{
-   "r200 render",
-   (_DD_NEW_SEPARATE_SPECULAR |
-    _NEW_TEXTURE|
-    _NEW_FOG|
-    _NEW_RENDERMODE),          /* re-check (new inputs) */
-   0,                          /* re-run (always runs) */
-   GL_TRUE,                    /* active */
-   0, 0,                       /* inputs (set in check_render), outputs */
-   0, 0,                       /* changed_inputs, private */
-   dtr,                                /* destructor */
-   r200_check_render,          /* check - initially set to alloc data */
-   r200_run_render             /* run */
-};
-
-
-
 /**************************************************************************/
 
 
@@ -710,16 +327,22 @@
 static void r200RenderPrimitive( GLcontext *ctx, GLenum prim );
 static void r200ResetLineStipple( GLcontext *ctx );
 
-#undef HAVE_QUADS
-#define HAVE_QUADS 0
-
-#undef HAVE_QUAD_STRIPS
-#define HAVE_QUAD_STRIPS 0
-
 /***********************************************************************
  *                    Emit primitives as inline vertices               *
  ***********************************************************************/
 
+#define HAVE_POINTS      1
+#define HAVE_LINES       1
+#define HAVE_LINE_STRIPS 1
+#define HAVE_TRIANGLES   1
+#define HAVE_TRI_STRIPS  1
+#define HAVE_TRI_STRIP_1 0
+#define HAVE_TRI_FANS    1
+#define HAVE_QUADS       0
+#define HAVE_QUAD_STRIPS 0
+#define HAVE_POLYGONS    1
+#define HAVE_ELTS        0
+
 #undef LOCAL_VARS
 #undef ALLOC_VERTS
 #define CTX_ARG r200ContextPtr rmesa
@@ -732,7 +355,7 @@
 #define VERT(x) (r200Vertex *)(r200verts + ((x) * vertsize * sizeof(int)))
 #define VERTEX r200Vertex 
 #define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS))
-#define PRINT_VERTEX(v) r200_print_vertex(rmesa->glCtx, v)
+
 #undef TAG
 #define TAG(x) r200_##x
 #include "tnl_dd/t_dd_triemit.h"
@@ -802,20 +425,23 @@
 
 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
 
-#define VERT_SET_SPEC( v0, c )                                 \
+#define VERT_SET_SPEC( v, c )                                  \
 do {                                                           \
-   if (havespec) {                                             \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]);    \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]);  \
-      UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]);   \
+   if (specoffset) {                                           \
+      r200_color_t *spec = (r200_color_t *)&((v)->ui[specoffset]);     \
+      UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]);     \
+      UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]);   \
+      UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]);    \
    }                                                           \
 } while (0)
 #define VERT_COPY_SPEC( v0, v1 )                       \
 do {                                                   \
-   if (havespec) {                                     \
-      v0->v.specular.red   = v1->v.specular.red;       \
-      v0->v.specular.green = v1->v.specular.green;     \
-      v0->v.specular.blue  = v1->v.specular.blue;      \
+   if (specoffset) {                                   \
+      r200_color_t *spec0 = (r200_color_t *)&((v0)->ui[specoffset]);   \
+      r200_color_t *spec1 = (r200_color_t *)&((v1)->ui[specoffset]);   \
+      spec0->red   = spec1->red;       \
+      spec0->green = spec1->green;     \
+      spec0->blue  = spec1->blue;      \
    }                                                   \
 } while (0)
 
@@ -824,8 +450,8 @@
  */
 #define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
-#define VERT_SAVE_SPEC( idx )    if (havespec) spec[idx] = v[idx]->ui[5]
-#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
+#define VERT_SAVE_SPEC( idx )    if (specoffset) spec[idx] = v[idx]->ui[specoffset]
+#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
 
 #undef LOCAL_VARS
 #undef TAG
@@ -834,9 +460,9 @@
 #define LOCAL_VARS(n)                                                  \
    r200ContextPtr rmesa = R200_CONTEXT(ctx);                   \
    GLuint color[n], spec[n];                                           \
-   GLuint coloroffset = (rmesa->swtcl.vertex_size == 4 ? 3 : 4);       \
-   GLboolean havespec = (rmesa->swtcl.vertex_size > 4);                        \
-   (void) color; (void) spec; (void) coloroffset; (void) havespec;
+   GLuint coloroffset = rmesa->swtcl.coloroffset;      \
+   GLuint specoffset = rmesa->swtcl.specoffset;                        \
+   (void) color; (void) spec; (void) coloroffset; (void) specoffset;
 
 /***********************************************************************
  *                Helpers for rendering unfilled primitives            *
@@ -1041,11 +667,16 @@
    else {
       rmesa->Fallback &= ~bit;
       if (oldfallback == bit) {
+
         _swrast_flush( ctx );
         tnl->Driver.Render.Start = r200RenderStart;
         tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
         tnl->Driver.Render.Finish = r200RenderFinish;
-        tnl->Driver.Render.BuildVertices = r200BuildVertices;
+
+        tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+        tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+        tnl->Driver.Render.Interp = _tnl_interp;
+
         tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
         TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_FALSE );
         if (rmesa->TclFallback) {
@@ -1089,7 +720,9 @@
 
    /* Choose tiny vertex format
     */
+#if 0
    r200SetVertexFormat( ctx, R200_XYZW_BIT | R200_RGBA_BIT );
+#endif
 
    /* Ready for point primitives:
     */
@@ -1226,12 +859,10 @@
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   GLuint size = tnl->vb.Size;
    static int firsttime = 1;
 
    if (firsttime) {
       init_rast_tab();
-      init_setup_tab();
       firsttime = 0;
    }
 
@@ -1239,9 +870,14 @@
    tnl->Driver.Render.Finish = r200RenderFinish;
    tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
    tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
-   tnl->Driver.Render.BuildVertices = r200BuildVertices;
+   tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
+   tnl->Driver.Render.CopyPV = _tnl_copy_pv;
+   tnl->Driver.Render.Interp = _tnl_interp;
 
-   rmesa->swtcl.verts = (GLubyte *)ALIGN_MALLOC( size * 16 * 4, 32 );
+   _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 
+                      22 * sizeof(GLfloat) );
+   
+   rmesa->swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
    rmesa->swtcl.RenderIndex = ~0;
    rmesa->swtcl.render_primitive = GL_TRIANGLES;
    rmesa->swtcl.hw_primitive = 0;
@@ -1254,9 +890,4 @@
 
    if (rmesa->swtcl.indexed_verts.buf) 
       r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ );
-
-   if (rmesa->swtcl.verts) {
-      ALIGN_FREE(rmesa->swtcl.verts);
-      rmesa->swtcl.verts = 0;
-   }
 }
Index: drivers/dri/r200/r200_tcl.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_tcl.c,v
retrieving revision 1.6
diff -u -r1.6 r200_tcl.c
--- a/drivers/dri/r200/r200_tcl.c       9 Dec 2003 14:18:41 -0000       1.6
+++ b/drivers/dri/r200/r200_tcl.c       18 Apr 2004 12:13:37 -0000
@@ -403,7 +403,6 @@
    TNLcontext *tnl = TNL_CONTEXT(ctx);
 
    R200_NEWPRIM( rmesa );
-   rmesa->swtcl.vertex_format = 0;
 
    r200ChooseVertexState( ctx );
    r200ChooseRenderState( ctx );
@@ -446,7 +445,6 @@
       rmesa->dma.flush( rmesa );       
 
    rmesa->dma.flush = 0;
-   rmesa->swtcl.vertex_format = 0;
    
    if (rmesa->swtcl.indexed_verts.buf) 
       r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, 
Index: tnl/t_vertex.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/tnl/t_vertex.h,v
retrieving revision 1.6
diff -u -r1.6 t_vertex.h
--- a/tnl/t_vertex.h    16 Feb 2004 15:15:24 -0000      1.6
+++ b/tnl/t_vertex.h    18 Apr 2004 12:13:37 -0000
@@ -28,6 +28,8 @@
 #ifndef _TNL_VERTEX_H
 #define _TNL_VERTEX_H
 
+#include "mtypes.h"
+
 /* New mechanism to specify hardware vertices so that tnl can build
  * and manipulate them directly.  
  */

Reply via email to