jjjjjjjjjIan Romanick wrote:
Here's an updated version of the patch. It incorporates most of Keith's code. It seems to mostly work with 2 exceptions.
- r200PointsBitmap is still broken. I'm not sure what the right way is going to be to fix that.
- Colors are wrong. The cylinder in gloss is brownish instead of purple, and the red & blue gears in gears have their colors swapped. It almost looks like the RGBA values are being sent to the card in the wrong order (i.e., as BGRA).
Yes, that's exactly what's happening. The enums for RGBA & BGRA are flipped in t_vertex.h. During testing with i830, I convinced myself that that hardware had RGBA vertices so I didn't notice the error.
Here's a patch with the corrected enums, and fixes to the i830 and savage driver to maintain their current behaviour.
Keith
Index: src/mesa/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/src/mesa/drivers/dri/r200/r200_context.h 11 Mar 2004 20:35:40 -0000 1.12 +++ b/src/mesa/drivers/dri/r200/r200_context.h 21 Apr 2004 13:13:41 -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,12 @@ /* 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 +630,18 @@ 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; + + GLboolean needproj; + struct r200_dma_region indexed_verts; }; Index: src/mesa/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/src/mesa/drivers/dri/r200/r200_swtcl.c 20 Jan 2004 02:49:27 -0000 1.9 +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c 21 Apr 2004 13:13:41 -0000 @@ -56,323 +56,187 @@ #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; - if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) { - r200SetVertexFormat( ctx, rmesa->swtcl.SetupIndex | R200_PTEX_BIT); + 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 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 ); } 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 ); + + 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 +309,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 +329,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 +357,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 +427,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 +452,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 +462,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 +669,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 +722,9 @@ /* Choose tiny vertex format */ +#if 0 r200SetVertexFormat( ctx, R200_XYZW_BIT | R200_RGBA_BIT ); +#endif /* Ready for point primitives: */ @@ -1226,12 +861,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 +872,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 +892,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: src/mesa/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/src/mesa/drivers/dri/r200/r200_tcl.c 9 Dec 2003 14:18:41 -0000 1.6 +++ b/src/mesa/drivers/dri/r200/r200_tcl.c 21 Apr 2004 13:13:41 -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: src/mesa/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/src/mesa/tnl/t_vertex.h 16 Feb 2004 15:15:24 -0000 1.6 +++ b/src/mesa/tnl/t_vertex.h 21 Apr 2004 13:13:41 -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. */ @@ -46,10 +48,10 @@ EMIT_4F_VIEWPORT, /* do viewport transform and emit */ EMIT_3F_XYW, /* for projective texture */ EMIT_1UB_1F, /* for fog coordinate */ - EMIT_3UB_3F_BGR, /* for specular color */ EMIT_3UB_3F_RGB, /* for specular color */ - EMIT_4UB_4F_BGRA, /* for color */ + EMIT_3UB_3F_BGR, /* for specular color */ EMIT_4UB_4F_RGBA, /* for color */ + EMIT_4UB_4F_BGRA, /* for color */ EMIT_4CHAN_4F_RGBA, /* for swrast color */ EMIT_PAD, /* leave a hole of 'offset' bytes */ EMIT_MAX