OSDN Git Service

Convert R200 driver to use the t_vertex interface.
authorIan Romanick <idr@us.ibm.com>
Fri, 23 Apr 2004 20:20:07 +0000 (20:20 +0000)
committerIan Romanick <idr@us.ibm.com>
Fri, 23 Apr 2004 20:20:07 +0000 (20:20 +0000)
src/mesa/drivers/dri/r200/r200_context.h
src/mesa/drivers/dri/r200/r200_swtcl.c
src/mesa/drivers/dri/r200/r200_tcl.c

index b147e25..ae7d2f4 100644 (file)
@@ -39,6 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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,28 @@ struct r200_tcl_info {
 /* r200_swtcl.c
  */
 struct r200_swtcl_info {
-   GLuint SetupIndex;
-   GLuint SetupNewInputs;
    GLuint RenderIndex;
+   
+   /**
+    * Size of a hardware vertex.  This is calculated when \c ::vertex_attrs is
+    * installed in the Mesa state vector.
+    */
    GLuint vertex_size;
-   GLuint vertex_stride_shift;
-   GLuint vertex_format;
+
+   /**
+    * Attributes instructing the Mesa TCL pipeline where / how to put vertex
+    * data in the hardware buffer.
+    */
+   struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
+
+   /**
+    * Number of elements of \c ::vertex_attrs that are actually used.
+    */
+   GLuint vertex_attr_count;
+
+   /**
+    * Cached pointer to the buffer where Mesa will store vertex data.
+    */
    GLubyte *verts;
 
    /* Fallback rasterization functions
@@ -629,6 +646,21 @@ struct r200_swtcl_info {
    GLenum render_primitive;
    GLuint numverts;
 
+   /**
+    * Offset of the 4UB color data within a hardware (swtcl) vertex.
+    */
+   GLuint coloroffset;
+
+   /**
+    * Offset of the 3UB specular color data within a hardware (swtcl) vertex.
+    */
+   GLuint specoffset;
+
+   /**
+    * Should Mesa project vertex data or will the hardware do it?
+    */
+   GLboolean needproj;
+
    struct r200_dma_region indexed_verts;
 };
 
index a66879f..2a0cd5b 100644 (file)
@@ -56,323 +56,192 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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 )                                   \
+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;                                                                \
+} 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++;                                   \
+} while (0)
 
-static void r200SetVertexFormat( GLcontext *ctx, GLuint ind ) 
+static void r200SetVertexFormat( GLcontext *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint index = tnl->render_inputs;
+   int fmt_0 = 0;
+   int fmt_1 = 0;
+   int offset = 0;
 
-   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;
+   /* Important:
+    */
+   if ( VB->NdcPtr != NULL ) {
+      VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
    }
    else {
-      tnl->Driver.Render.Interp = setup_tab[ind].interp;
-      tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
+      VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
    }
 
-   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;
+   assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
+   rmesa->swtcl.vertex_attr_count = 0;
 
-      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];
+   /* 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 );
+      offset = 4;
+   }
+   else {
+      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F, R200_VTX_XY | R200_VTX_Z0 );
+      offset = 3;
    }
 
-   {
-      GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
-      GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
-      GLuint needproj;
-
-      /* 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;
+   rmesa->swtcl.coloroffset = offset;
+   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) );
+   offset += 1;
+
+   rmesa->swtcl.specoffset = 0;
+   if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) {
+
+      if (index & _TNL_BIT_COLOR1) {
+        rmesa->swtcl.specoffset = offset;
+        EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
       }
       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) );
       }
-      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;
+
+      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+        if (index & _TNL_BIT_TEX(i)) {
+           GLuint sz = VB->TexCoordPtr[i]->size;
+           GLuint emit;
 
-   if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) {
-      r200SetVertexFormat( ctx, rmesa->swtcl.SetupIndex | R200_PTEX_BIT);
+           /* 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;
+           };
+
+           fmt_1 |= sz << (3 * i);
+           EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0 );
+        }
+      }
+   }
+
+
+
+   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,
+                             NULL, 0 );
+      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 );
 }
 
 
+/**
+ * Set vertex state for SW TCL.  The primary purpose of this function is to
+ * determine in advance whether or not the hardware can / should do the
+ * projection divide or Mesa should do it.
+ */
 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) == 0)
+       || (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 );
 
-   r200SetVertexFormat( ctx, ind );
+   if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
+      R200_STATECHANGE( rmesa, vte );
+      rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
+   }
+
+   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 +314,6 @@ static __inline void *r200AllocDmaLowVerts( r200ContextPtr rmesa,
 }
 
 
-
-
-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 +334,22 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim );
 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 +362,7 @@ static void r200ResetLineStipple( GLcontext *ctx );
 #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 +432,23 @@ do {                                                              \
 
 #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 +457,8 @@ do {                                                        \
  */
 #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 +467,9 @@ do {                                                        \
 #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 +674,16 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
    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) {
@@ -1067,7 +705,15 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
 
 
 
-/* Cope with depth operations by drawing individual pixels as points??? 
+/**
+ * Cope with depth operations by drawing individual pixels as points.
+ * 
+ * \todo
+ * The way the vertex state is set in this routine is hokey.  It seems to
+ * work, but it's very hackish.  This whole routine is pretty hackish.  If
+ * the bitmap is small enough, it seems like it would be faster to copy it
+ * to AGP memory and use it as a non-power-of-two texture (i.e.,
+ * NV_texture_rectangle).
  */
 void
 r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
@@ -1089,7 +735,37 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py,
 
    /* Choose tiny vertex format
     */
-   r200SetVertexFormat( ctx, R200_XYZW_BIT | R200_RGBA_BIT );
+   {
+      const GLuint fmt_0 = R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0
+         | (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT);
+      const GLuint fmt_1 = 0;
+      GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
+      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;
+
+      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;
+      }
+
+      if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
+        R200_STATECHANGE( rmesa, vte );
+        rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
+      }
+
+      if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
+        R200_STATECHANGE( rmesa, vap );
+        rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
+      }
+   }
 
    /* Ready for point primitives:
     */
@@ -1226,12 +902,10 @@ void r200InitSwtcl( GLcontext *ctx )
 {
    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 +913,14 @@ void r200InitSwtcl( GLcontext *ctx )
    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 +933,4 @@ void r200DestroySwtcl( GLcontext *ctx )
 
    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 9b1f522..daf4490 100644 (file)
@@ -403,7 +403,6 @@ static void transition_to_swtnl( GLcontext *ctx )
    TNLcontext *tnl = TNL_CONTEXT(ctx);
 
    R200_NEWPRIM( rmesa );
-   rmesa->swtcl.vertex_format = 0;
 
    r200ChooseVertexState( ctx );
    r200ChooseRenderState( ctx );
@@ -446,7 +445,6 @@ static void transition_to_hwtnl( GLcontext *ctx )
       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,