X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fsis%2Fsis_tris.c;h=76d12d07b3ca4e3aef5a665b8d0ad2646efa0088;hb=f094b86bb5ab93aedc03df5cf5bdf51ab9d37045;hp=6c7865f6c4bc07896b2da856c2bc9ff6fae575c9;hpb=9556a5286730aa6839b9aa7cbbb2fe815a318e28;p=mesa.git diff --git a/src/mesa/drivers/dri/sis/sis_tris.c b/src/mesa/drivers/dri/sis/sis_tris.c index 6c7865f6c4b..76d12d07b3c 100644 --- a/src/mesa/drivers/dri/sis/sis_tris.c +++ b/src/mesa/drivers/dri/sis/sis_tris.c @@ -32,22 +32,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Eric Anholt */ -#include "glheader.h" -#include "mtypes.h" -#include "colormac.h" -#include "macros.h" +#include "main/glheader.h" +#include "main/mtypes.h" +#include "main/colormac.h" +#include "main/macros.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" +#include "sis_context.h" #include "sis_tris.h" #include "sis_state.h" -#include "sis_vb.h" #include "sis_lock.h" +#include "sis_span.h" +#include "sis_alloc.h" +#include "sis_tex.h" +/* 6326 and 300-series shared */ static const GLuint hw_prim[GL_POLYGON+1] = { OP_3D_POINT_DRAW, /* GL_POINTS */ OP_3D_LINE_DRAW, /* GL_LINES */ @@ -66,6 +69,11 @@ static const GLuint hw_prim_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = { OP_3D_FIRE_TSARGBb, OP_3D_FIRE_TSARGBc }; +static const GLuint hw_prim_6326_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = { + OP_6326_3D_FIRE_TSARGBa, + OP_6326_3D_FIRE_TSARGBb, + OP_6326_3D_FIRE_TSARGBc +}; static const GLuint hw_prim_mmio_shade[OP_3D_TRIANGLE_DRAW+1] = { SHADE_FLAT_VertexA, @@ -87,145 +95,262 @@ static const GLuint hw_prim_agp_shade[OP_3D_TRIANGLE_DRAW+1] = { static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim ); static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ); -static void sisMakeRoomAGP( sisContextPtr smesa, GLint num ); -static void sisUpdateAGP( sisContextPtr smesa ); -static void sisFireVertsAGP( sisContextPtr smesa ); - -static float *AGP_StartPtr; -static float *AGP_WritePtr; /* Current write position */ -static float *AGP_ReadPtr; /* Last known engine readposition */ -static long AGP_SpaceLeft; /* Last known engine readposition */ /*********************************************************************** * Emit primitives as inline vertices * ***********************************************************************/ -/* Future optimizations: - * - * The previous code only emitted W when fog or textures were enabled. - */ +#define HAVE_QUADS 0 +#define HAVE_LINES 1 +#define HAVE_POINTS 1 +#define CTX_ARG sisContextPtr smesa +#define GET_VERTEX_DWORDS() smesa->vertex_size +#define ALLOC_VERTS( n, size ) sisAllocDmaLow( smesa, n * size * sizeof(int) ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + const char *vertptr = smesa->verts; +#define VERT(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int))) +#define VERTEX sisVertex +#undef TAG +#define TAG(x) sis_##x +#include "tnl_dd/t_dd_triemit.h" +#undef TAG +#undef LOCAL_VARS + +/*********************************************************************** + * Dispatch vertices to hardware through MMIO * + ***********************************************************************/ +/* The ARGB write of the last vertex of the primitive fires the 3d engine, so + * save it until the end. + */ #define SIS_MMIO_WRITE_VERTEX(_v, i, lastvert) \ do { \ - MMIOBase[(REG_3D_TSXa+(i)*0x30)/4] = _v->v.x; \ - MMIOBase[(REG_3D_TSYa+(i)*0x30)/4] = _v->v.y; \ - MMIOBase[(REG_3D_TSZa+(i)*0x30)/4] = _v->v.z; \ - MMIOBase[(REG_3D_TSWGa+(i)*0x30)/4] = _v->v.w; \ - /*((GLint *) MMIOBase)[(REG_3D_TSFSa+(i)*0x30)/4] = _v->ui[5];*/ \ - if (SIS_STATES & SIS_VERT_TEX0) { \ - MMIOBase[(REG_3D_TSUAa+(i)*0x30)/4] = _v->v.u0; \ - MMIOBase[(REG_3D_TSVAa+(i)*0x30)/4] = _v->v.v0; \ + GLuint __color, __i = 0; \ + MMIO(REG_3D_TSXa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSYa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSZa+(i)*0x30, _v->ui[__i++]); \ + if (SIS_STATES & VERT_W) \ + MMIO(REG_3D_TSWGa+(i)*0x30, _v->ui[__i++]); \ + __color = _v->ui[__i++]; \ + if (SIS_STATES & VERT_SPEC) \ + MMIO(REG_3D_TSFSa+(i)*0x30, _v->ui[__i++]); \ + if (SIS_STATES & VERT_UV0) { \ + MMIO(REG_3D_TSUAa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSVAa+(i)*0x30, _v->ui[__i++]); \ } \ - if (SIS_STATES & SIS_VERT_TEX1) { \ - MMIOBase[(REG_3D_TSUBa+(i)*0x30)/4] = _v->v.u1; \ - MMIOBase[(REG_3D_TSVBa+(i)*0x30)/4] = _v->v.v1; \ + if (SIS_STATES & VERT_UV1) { \ + MMIO(REG_3D_TSUBa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSVBa+(i)*0x30, _v->ui[__i++]); \ } \ - /*MMIOBase[(REG_3D_TSUCa+(i)*0x30)/4] = _v->v.u2; \ - MMIOBase[(REG_3D_TSVCa+(i)*0x30)/4] = _v->v.v2;*/ \ - /* the ARGB write of the last vertex of the primitive fires the 3d engine*/ \ - if (lastvert || (SIS_STATES & SIS_VERT_SMOOTH)) \ - ((GLint *) MMIOBase)[(REG_3D_TSARGBa+(i)*0x30)/4] = _v->ui[4]; \ -} while (0); - -#define SIS_AGP_WRITE_VERTEX(_v) \ + if (lastvert || (SIS_STATES & VERT_SMOOTH)) \ + MMIO(REG_3D_TSARGBa+(i)*0x30, __color); \ +} while (0) + +#define SIS6326_MMIO_WRITE_VERTEX(_v, i, lastvert) \ do { \ - AGP_WritePtr[0] = _v->v.x; \ - AGP_WritePtr[1] = _v->v.y; \ - AGP_WritePtr[2] = _v->v.z; \ - AGP_WritePtr[3] = _v->v.w; \ - ((GLint *)AGP_WritePtr)[4] = _v->ui[4]; \ - AGP_WritePtr += 5; \ - if (SIS_STATES & SIS_VERT_TEX0) { \ - AGP_WritePtr[0] = _v->v.u0; \ - AGP_WritePtr[1] = _v->v.v0; \ - AGP_WritePtr += 2; \ - } \ - if (SIS_STATES & SIS_VERT_TEX1) { \ - AGP_WritePtr[0] = _v->v.u1; \ - AGP_WritePtr[1] = _v->v.v1; \ - AGP_WritePtr += 2; \ + GLuint __color, __i = 0; \ + MMIO(REG_6326_3D_TSXa+(i)*0x20, _v->ui[__i++]); \ + MMIO(REG_6326_3D_TSYa+(i)*0x20, _v->ui[__i++]); \ + MMIO(REG_6326_3D_TSZa+(i)*0x20, _v->ui[__i++]); \ + if (SIS_STATES & VERT_W) \ + MMIO(REG_6326_3D_TSWa+(i)*0x20, _v->ui[__i++]); \ + __color = _v->ui[__i++]; \ + if (SIS_STATES & VERT_SPEC) \ + MMIO(REG_6326_3D_TSFSa+(i)*0x20, _v->ui[__i++]); \ + if (SIS_STATES & VERT_UV0) { \ + MMIO(REG_6326_3D_TSUa+(i)*0x20, _v->ui[__i++]); \ + MMIO(REG_6326_3D_TSVa+(i)*0x20, _v->ui[__i++]); \ } \ -} while(0) + if (lastvert || (SIS_STATES & VERT_SMOOTH)) \ + MMIO(REG_6326_3D_TSARGBa+(i)*0x30, __color); \ +} while (0) #define MMIO_VERT_REG_COUNT 10 -#define SIS_VERT_SMOOTH 0x01 -#define SIS_VERT_TEX0 0x02 -#define SIS_VERT_TEX1 0x04 - -static sis_quad_func sis_quad_func_agp[8]; -static sis_tri_func sis_tri_func_agp[8]; -static sis_line_func sis_line_func_agp[8]; -static sis_point_func sis_point_func_agp[8]; -static sis_quad_func sis_quad_func_mmio[8]; -static sis_tri_func sis_tri_func_mmio[8]; -static sis_line_func sis_line_func_mmio[8]; -static sis_point_func sis_point_func_mmio[8]; - -/* XXX: These definitions look questionable */ -#define USE_XYZ MASK_PsVertex_HAS_RHW -#define USE_W MASK_PsVertex_HAS_NORMALXYZ -#define USE_RGB MASK_PsVertex_HAS_SPECULAR -#define USE_UV1 MASK_PsVertex_HAS_UVSet2 -#define USE_UV2 MASK_PsVertex_HAS_UVSet3 - -static GLint AGPParsingValues[8] = { - (5 << 28) | USE_XYZ | USE_W | USE_RGB, - (5 << 28) | USE_XYZ | USE_W | USE_RGB, - (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1, - (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1, - (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV2, - (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV2, - (9 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1 | USE_UV2, - (9 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1 | USE_UV2, -}; +#define VERT_SMOOTH 0x01 +#define VERT_W 0x02 +#define VERT_SPEC 0x04 +#define VERT_UV0 0x08 +#define VERT_UV1 0x10 +#define VERT_6326 0x20 /* Right after UV1, but won't have a UV1 set */ + +typedef void (*mmio_draw_func)(sisContextPtr smesa, char *verts); +static mmio_draw_func sis_tri_func_mmio[48]; +static mmio_draw_func sis_line_func_mmio[48]; +static mmio_draw_func sis_point_func_mmio[48]; #define SIS_STATES (0) #define TAG(x) x##_none #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_SMOOTH) +#define SIS_STATES (VERT_SMOOTH) +#define TAG(x) x##_g +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W) +#define TAG(x) x##_w +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W) +#define TAG(x) x##_gw +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC) #define TAG(x) x##_s #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_TEX0) +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC) +#define TAG(x) x##_gs +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC) +#define TAG(x) x##_ws +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC) +#define TAG(x) x##_gws +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV0) #define TAG(x) x##_t0 #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_SMOOTH | SIS_VERT_TEX0) +#define SIS_STATES (VERT_SMOOTH | VERT_UV0) +#define TAG(x) x##_gt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV0) +#define TAG(x) x##_wt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0) +#define TAG(x) x##_gwt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV0) #define TAG(x) x##_st0 #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_TEX1) +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_gst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_wst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_gwst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV1) #define TAG(x) x##_t1 #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_SMOOTH | SIS_VERT_TEX1) +#define SIS_STATES (VERT_SMOOTH | VERT_UV1) +#define TAG(x) x##_gt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV1) +#define TAG(x) x##_wt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV1) +#define TAG(x) x##_gwt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV1) #define TAG(x) x##_st1 #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_TEX0 | SIS_VERT_TEX1) +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_gst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_wst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_gwst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV0 | VERT_UV1) #define TAG(x) x##_t0t1 #include "sis_tritmp.h" -#define SIS_STATES (SIS_VERT_SMOOTH | SIS_VERT_TEX0 | SIS_VERT_TEX1) +#define SIS_STATES (VERT_SMOOTH | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_wt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gwt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV0 | VERT_UV1) #define TAG(x) x##_st0t1 #include "sis_tritmp.h" +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gst0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_wst0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gwst0t1 +#include "sis_tritmp.h" + /*********************************************************************** * Macros for t_dd_tritmp.h to draw basic primitives * ***********************************************************************/ -#define POINT( v0 ) smesa->draw_point( smesa, v0 ) -#define LINE( v0, v1 ) smesa->draw_line( smesa, v0, v1 ) -#define TRI( a, b, c ) smesa->draw_tri( smesa, a, b, c ) -#define QUAD( a, b, c, d ) smesa->draw_quad( smesa, a, b, c, d ) +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_tri( smesa, a, b, c ); \ + else \ + sis_triangle( smesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + smesa->draw_tri( smesa, a, b, d ); \ + smesa->draw_tri( smesa, b, c, d ); \ + } else \ + sis_quad( smesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_line( smesa, v0, v1 ); \ + else \ + sis_line( smesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_point( smesa, v0 ); \ + else \ + sis_point( smesa, v0 ); \ +} while (0) /*********************************************************************** * Build render functions from dd templates * ***********************************************************************/ -#define SIS_OFFSET_BIT 0x01 +#define SIS_OFFSET_BIT 0x01 #define SIS_TWOSIDE_BIT 0x02 #define SIS_UNFILLED_BIT 0x04 #define SIS_FALLBACK_BIT 0x08 @@ -233,10 +358,10 @@ static GLint AGPParsingValues[8] = { static struct { - points_func points; - line_func line; - triangle_func triangle; - quad_func quad; + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; } rast_tab[SIS_MAX_TRIFUNC]; @@ -258,14 +383,14 @@ static struct { #define VERTEX sisVertex #define TAB rast_tab -#define DEPTH_SCALE 1.0 +#define DEPTH_SCALE smesa->depth_scale #define UNFILLED_TRI unfilled_tri #define UNFILLED_QUAD unfilled_quad #define VERT_X(_v) _v->v.x #define VERT_Y(_v) _v->v.y #define VERT_Z(_v) _v->v.z #define AREA_IS_CCW( a ) (a > 0) -#define GET_VERTEX(e) (smesa->verts + (e << smesa->vertex_stride_shift)) +#define GET_VERTEX(e) (smesa->verts + (e * smesa->vertex_size * sizeof(int))) #define VERT_SET_RGBA( v, c ) \ do { \ @@ -278,34 +403,37 @@ 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 != 0) { \ + sis_color_t *spec = (sis_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; \ - } \ +#define VERT_COPY_SPEC( v0, v1 ) \ +do { \ + if (specoffset != 0) { \ + sis_color_t *spec0 = (sis_color_t *)&((v0)->ui[specoffset]); \ + sis_color_t *spec1 = (sis_color_t *)&((v1)->ui[specoffset]); \ + spec0->red = spec1->red; \ + spec0->green = spec1->green; \ + spec0->blue = spec1->blue; \ + } \ } while (0) #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 != 0) spec[idx] = v[idx]->ui[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset != 0) v[idx]->ui[specoffset] = spec[idx] #define LOCAL_VARS(n) \ sisContextPtr smesa = SIS_CONTEXT(ctx); \ GLuint color[n], spec[n]; \ - GLuint coloroffset = (smesa->vertex_size == 4 ? 3 : 4); \ - GLboolean havespec = (smesa->vertex_size == 4 ? 0 : 1); \ - (void) color; (void) spec; (void) coloroffset; (void) havespec; + GLuint coloroffset = smesa->coloroffset; \ + GLuint specoffset = smesa->specoffset; \ + (void) color; (void) spec; (void) coloroffset; (void) specoffset; /*********************************************************************** * Helpers for rendering unfilled primitives * @@ -337,7 +465,7 @@ do { \ #define TAG(x) x##_twoside #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT) +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT) #define TAG(x) x##_twoside_offset #include "tnl_dd/t_dd_tritmp.h" @@ -345,15 +473,15 @@ do { \ #define TAG(x) x##_unfilled #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_OFFSET_BIT | SIS_UNFILLED_BIT) +#define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT) #define TAG(x) x##_offset_unfilled #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_UNFILLED_BIT) +#define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT) #define TAG(x) x##_twoside_unfilled #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT | SIS_UNFILLED_BIT) +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT) #define TAG(x) x##_twoside_offset_unfilled #include "tnl_dd/t_dd_tritmp.h" @@ -361,31 +489,31 @@ do { \ #define TAG(x) x##_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_OFFSET_BIT | SIS_FALLBACK_BIT) +#define IND (SIS_OFFSET_BIT|SIS_FALLBACK_BIT) #define TAG(x) x##_offset_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_FALLBACK_BIT) +#define IND (SIS_TWOSIDE_BIT|SIS_FALLBACK_BIT) #define TAG(x) x##_twoside_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT | SIS_FALLBACK_BIT) +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_FALLBACK_BIT) #define TAG(x) x##_twoside_offset_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_UNFILLED_BIT | SIS_FALLBACK_BIT) +#define IND (SIS_UNFILLED_BIT|SIS_FALLBACK_BIT) #define TAG(x) x##_unfilled_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_OFFSET_BIT | SIS_UNFILLED_BIT | SIS_FALLBACK_BIT) +#define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT) #define TAG(x) x##_offset_unfilled_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_UNFILLED_BIT | SIS_FALLBACK_BIT) +#define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT) #define TAG(x) x##_twoside_unfilled_fallback #include "tnl_dd/t_dd_tritmp.h" -#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT | SIS_UNFILLED_BIT | \ +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT| \ SIS_FALLBACK_BIT) #define TAG(x) x##_twoside_offset_unfilled_fallback #include "tnl_dd/t_dd_tritmp.h" @@ -422,22 +550,6 @@ static void init_rast_tab( void ) * primitives are being drawn, and only for the unaccelerated * primitives. */ -static void -sis_fallback_quad( sisContextPtr smesa, - sisVertex *v0, - sisVertex *v1, - sisVertex *v2, - sisVertex *v3 ) -{ - GLcontext *ctx = smesa->glCtx; - SWvertex v[4]; - sis_translate_vertex( ctx, v0, &v[0] ); - sis_translate_vertex( ctx, v1, &v[1] ); - sis_translate_vertex( ctx, v2, &v[2] ); - sis_translate_vertex( ctx, v3, &v[3] ); - _swrast_Triangle( ctx, &v[0], &v[1], &v[3] ); - _swrast_Triangle( ctx, &v[1], &v[2], &v[3] ); -} static void sis_fallback_tri( sisContextPtr smesa, @@ -447,10 +559,13 @@ sis_fallback_tri( sisContextPtr smesa, { GLcontext *ctx = smesa->glCtx; SWvertex v[3]; - sis_translate_vertex( ctx, v0, &v[0] ); - sis_translate_vertex( ctx, v1, &v[1] ); - sis_translate_vertex( ctx, v2, &v[2] ); + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + _swsetup_Translate( ctx, v2, &v[2] ); + sisSpanRenderStart( ctx ); _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); } @@ -461,9 +576,12 @@ sis_fallback_line( sisContextPtr smesa, { GLcontext *ctx = smesa->glCtx; SWvertex v[2]; - sis_translate_vertex( ctx, v0, &v[0] ); - sis_translate_vertex( ctx, v1, &v[1] ); + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + sisSpanRenderStart( ctx ); _swrast_Line( ctx, &v[0], &v[1] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); } @@ -473,8 +591,11 @@ sis_fallback_point( sisContextPtr smesa, { GLcontext *ctx = smesa->glCtx; SWvertex v[1]; - sis_translate_vertex( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v0, &v[0] ); + sisSpanRenderStart( ctx ); _swrast_Point( ctx, &v[0] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); } @@ -483,21 +604,20 @@ sis_fallback_point( sisContextPtr smesa, /* Render unclipped begin/end objects */ /**********************************************************************/ -#define VERT(x) (sisVertex *)(sisverts + (x << shift)) +#define IND 0 +#define V(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int))) #define RENDER_POINTS( start, count ) \ for ( ; start < count ; start++) \ - smesa->draw_point( smesa, VERT(start) ) -#define RENDER_LINE( v0, v1 ) smesa->draw_line( smesa, VERT(v0), VERT(v1) ) -#define RENDER_TRI( v0, v1, v2 ) smesa->draw_tri( smesa, VERT(v0), VERT(v1), \ - VERT(v2) ) -#define RENDER_QUAD( v0, v1, v2, v3 ) smesa->draw_quad( smesa, VERT(v0), \ - VERT(v1), VERT(v2), VERT(v3)) + POINT( V(ELT(start)) ) +#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) +#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) #define INIT(x) sisRenderPrimitive( ctx, x ) #undef LOCAL_VARS #define LOCAL_VARS \ sisContextPtr smesa = SIS_CONTEXT(ctx); \ - const GLuint shift = smesa->vertex_stride_shift; \ - const char *sisverts = (char *)smesa->verts; \ + const GLuint vertsize = smesa->vertex_size; \ + const char *vertptr = (char *)smesa->verts; \ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ (void) elt; #define RESET_STIPPLE @@ -513,103 +633,26 @@ sis_fallback_point( sisContextPtr smesa, #include "tnl/t_vb_rendertmp.h" -/**********************************************************************/ -/* Render clipped primitives */ -/**********************************************************************/ - -static void sisRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - - /* Render the new vertices as an unclipped polygon. - */ - { - GLuint *tmp = VB->Elts; - VB->Elts = (GLuint *)elts; - tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); - VB->Elts = tmp; - } -} - -static void sisRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->Driver.Render.Line( ctx, ii, jj ); -} - -#if 0 -static void sisFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, - GLuint n ) -{ - sisContextPtr smesa = SIS_CONTEXT( ctx ); - GLuint vertsize = smesa->vertex_size; - GLuint *vb = r128AllocDmaLow( rmesa, (n-2) * 3 * 4 * vertsize ); - GLubyte *sisverts = (GLubyte *)smesa->verts; - const GLuint shift = smesa->vertex_stride_shift; - const GLuint *start = (const GLuint *)VERT(elts[0]); - int i,j; - - smesa->num_verts += (n-2) * 3; - - for (i = 2 ; i < n ; i++) { - COPY_DWORDS( j, vb, vertsize, (sisVertexPtr) VERT(elts[i-1]) ); - COPY_DWORDS( j, vb, vertsize, (sisVertexPtr) VERT(elts[i]) ); - COPY_DWORDS( j, vb, vertsize, (sisVertexPtr) start ); - } -} -#endif - - - - /**********************************************************************/ /* Choose render functions */ /**********************************************************************/ -#define _SIS_NEW_RENDER_STATE (_DD_NEW_LINE_STIPPLE | \ - _DD_NEW_LINE_SMOOTH | \ - _DD_NEW_POINT_SMOOTH | \ - _DD_NEW_TRI_SMOOTH | \ - _DD_NEW_TRI_UNFILLED | \ - _DD_NEW_TRI_LIGHT_TWOSIDE | \ - _DD_NEW_TRI_OFFSET) \ - - #define POINT_FALLBACK (DD_POINT_SMOOTH) #define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH) -#define TRI_FALLBACK (DD_TRI_SMOOTH) +#define TRI_FALLBACK (DD_TRI_STIPPLE|DD_TRI_SMOOTH) #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) - +#define _SIS_NEW_RENDER_STATE (ANY_RASTER_FLAGS | ANY_FALLBACK_FLAGS) static void sisChooseRenderState(GLcontext *ctx) { + TNLcontext *tnl = TNL_CONTEXT(ctx); sisContextPtr smesa = SIS_CONTEXT( ctx ); GLuint flags = ctx->_TriangleCaps; GLuint index = 0; - GLuint vertindex = 0; - - if (ctx->Texture.Unit[0]._ReallyEnabled) - vertindex |= SIS_VERT_TEX0; - if (ctx->Texture.Unit[1]._ReallyEnabled) - vertindex |= SIS_VERT_TEX1; - if (ctx->Light.ShadeModel == GL_SMOOTH) - vertindex |= SIS_VERT_SMOOTH; - - if (smesa->AGPCmdModeEnabled) { - smesa->draw_quad = sis_quad_func_agp[vertindex]; - smesa->draw_tri = sis_tri_func_agp[vertindex]; - smesa->draw_line = sis_line_func_agp[vertindex]; - smesa->draw_point = sis_point_func_agp[vertindex]; - } else { - smesa->draw_quad = sis_quad_func_mmio[vertindex]; - smesa->draw_tri = sis_tri_func_mmio[vertindex]; - smesa->draw_line = sis_line_func_mmio[vertindex]; - smesa->draw_point = sis_point_func_mmio[vertindex]; - } - smesa->AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat); - smesa->AGPParseSet |= AGPParsingValues[vertindex]; + + if (smesa->Fallback) + return; if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) { @@ -619,6 +662,9 @@ static void sisChooseRenderState(GLcontext *ctx) if (flags & DD_TRI_UNFILLED) index |= SIS_UNFILLED_BIT; } + smesa->draw_point = sis_point; + smesa->draw_line = sis_line; + smesa->draw_tri = sis_triangle; /* Hook in fallbacks for specific primitives. */ if (flags & ANY_FALLBACK_FLAGS) { @@ -626,35 +672,30 @@ static void sisChooseRenderState(GLcontext *ctx) smesa->draw_point = sis_fallback_point; if (flags & LINE_FALLBACK) smesa->draw_line = sis_fallback_line; - if (flags & TRI_FALLBACK) { - smesa->draw_quad = sis_fallback_quad; + if (flags & TRI_FALLBACK) smesa->draw_tri = sis_fallback_tri; - } index |= SIS_FALLBACK_BIT; } } if (index != smesa->RenderIndex) { - TNLcontext *tnl = TNL_CONTEXT(ctx); + smesa->RenderIndex = index; + tnl->Driver.Render.Points = rast_tab[index].points; tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; tnl->Driver.Render.Triangle = rast_tab[index].triangle; tnl->Driver.Render.Quad = rast_tab[index].quad; if (index == 0) { tnl->Driver.Render.PrimTabVerts = sis_render_tab_verts; tnl->Driver.Render.PrimTabElts = sis_render_tab_elts; - tnl->Driver.Render.ClippedLine = rast_tab[index].line; - /*XXX: sisFastRenderClippedPoly*/ - tnl->Driver.Render.ClippedPolygon = sisRenderClippedPoly; + tnl->Driver.Render.ClippedPolygon = sis_fast_clipped_poly; } else { tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; - tnl->Driver.Render.ClippedLine = sisRenderClippedLine; - tnl->Driver.Render.ClippedPolygon = sisRenderClippedPoly; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; } - - smesa->RenderIndex = index; } } @@ -707,22 +748,13 @@ static void sisRunPipeline( GLcontext *ctx ) { sisContextPtr smesa = SIS_CONTEXT( ctx ); - LOCK_HARDWARE(); - sisUpdateHWState( ctx ); - - if (smesa->AGPCmdModeEnabled) { - AGP_WritePtr = (GLfloat *)smesa->AGPCmdBufBase + *smesa->pAGPCmdBufNext; - AGP_StartPtr = AGP_WritePtr; - AGP_ReadPtr = (GLfloat *)((long)MMIO_READ(REG_3D_AGPCmBase) - - (long)smesa->AGPCmdBufAddr + (long)smesa->AGPCmdBufBase); - sisUpdateAGP( smesa ); - } - - if (!smesa->Fallback && smesa->NewGLState) { - if (smesa->NewGLState & _SIS_NEW_VERTEX_STATE) - sisChooseVertexState( ctx ); + if (smesa->NewGLState) { + SIS_FIREVERTICES(smesa); + if (smesa->NewGLState & _NEW_TEXTURE) { + sisUpdateTextureState(ctx); + } - if (smesa->NewGLState & (_SIS_NEW_RENDER_STATE | _NEW_TEXTURE)) + if (smesa->NewGLState & _SIS_NEW_RENDER_STATE) sisChooseRenderState( ctx ); smesa->NewGLState = 0; @@ -730,11 +762,10 @@ static void sisRunPipeline( GLcontext *ctx ) _tnl_run_pipeline( ctx ); - if (smesa->AGPCmdModeEnabled) - sisFireVertsAGP( smesa ); - else - mEndPrimitive(); - UNLOCK_HARDWARE(); + /* XXX: If we put flushing in sis_state.c and friends, we can avoid this. + * Is it worth it? + */ + SIS_FIREVERTICES(smesa); } /**********************************************************************/ @@ -750,26 +781,34 @@ static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim ) { sisContextPtr smesa = SIS_CONTEXT(ctx); if (smesa->hw_primitive != hwprim) { - if (smesa->AGPCmdModeEnabled) { - sisFireVertsAGP( smesa ); - smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode); - smesa->AGPParseSet |= hw_prim_agp_type[hwprim]; - if (ctx->Light.ShadeModel == GL_FLAT) - smesa->AGPParseSet |= hw_prim_agp_shade[hwprim]; - else - smesa->AGPParseSet |= MASK_PsShadingSmooth; + SIS_FIREVERTICES(smesa); + smesa->hw_primitive = hwprim; + + smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode); + smesa->AGPParseSet |= hw_prim_agp_type[hwprim]; + + if (smesa->is6326) { + smesa->dwPrimitiveSet &= ~(MASK_6326_DrawPrimitiveCommand | + MASK_6326_SetFirePosition | MASK_6326_ShadingMode); + smesa->dwPrimitiveSet |= hwprim | hw_prim_6326_mmio_fire[hwprim]; + } else { + smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand | + MASK_SetFirePosition | MASK_ShadingMode); + smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim]; + } + + if (ctx->Light.ShadeModel == GL_FLAT) { + smesa->AGPParseSet |= hw_prim_agp_shade[hwprim]; + smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim]; } else { - mEndPrimitive(); - smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand | - MASK_SetFirePosition | MASK_ShadingMode); - smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim]; - if (ctx->Light.ShadeModel == GL_FLAT) - smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim]; - else - smesa->dwPrimitiveSet |= SHADE_GOURAUD; + smesa->AGPParseSet |= MASK_PsShadingSmooth; + if (smesa->is6326) { + smesa->dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_GOURAUD; + } else { + smesa->dwPrimitiveSet |= SHADE_GOURAUD; + } } } - smesa->hw_primitive = hwprim; } static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ) @@ -777,23 +816,39 @@ static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ) sisContextPtr smesa = SIS_CONTEXT(ctx); smesa->render_primitive = prim; + if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; sisRasterPrimitive( ctx, hw_prim[prim] ); } +#define EMIT_ATTR( ATTR, STYLE) \ +do { \ + smesa->vertex_attrs[smesa->vertex_attr_count].attrib = (ATTR); \ + smesa->vertex_attrs[smesa->vertex_attr_count].format = (STYLE); \ + smesa->vertex_attr_count++; \ +} while (0) +#define EMIT_PAD( N ) \ +do { \ + smesa->vertex_attrs[smesa->vertex_attr_count].attrib = 0; \ + smesa->vertex_attrs[smesa->vertex_attr_count].format = EMIT_PAD; \ + smesa->vertex_attrs[smesa->vertex_attr_count].offset = (N); \ + smesa->vertex_attr_count++; \ +} while (0) + static void sisRenderStart( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); sisContextPtr smesa = SIS_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); + GLuint AGPParseSet = smesa->AGPParseSet; + GLboolean tex_fallback = GL_FALSE; - /* Check for projective texturing. Make sure all texcoord - * pointers point to something. (fix in mesa?) - */ - sisCheckTexSizes( ctx ); + RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); - if (ctx->Color._DrawDestMask == FRONT_LEFT_BIT && + if (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT && smesa->driDrawable->numClipRects != 0) { multipass_cliprect(ctx, 0); @@ -804,89 +859,186 @@ static void sisRenderStart( GLcontext *ctx ) } else { tnl->Driver.Render.Multipass = NULL; } + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + smesa->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to build up a + * hardware vertex. + */ + + AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat); + AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE; + if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT); + AGPParseSet |= SiS_PS_HAS_W; + smesa->coloroffset = 4; + } else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT); + smesa->coloroffset = 3; + } + + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA); + + smesa->specoffset = 0; + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) || + RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { + AGPParseSet |= SiS_PS_HAS_SPECULAR; + + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR); + smesa->specoffset = smesa->coloroffset + 1; + } else { + EMIT_PAD(3); + } + + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F); + } else { + EMIT_PAD(1); + } + } + + /* projective textures are not supported by the hardware */ + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) { + if (VB->TexCoordPtr[0]->size > 2) + tex_fallback = GL_TRUE; + EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F); + AGPParseSet |= SiS_PS_HAS_UV0; + } + /* Will only hit tex1 on SiS300 */ + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) { + if (VB->TexCoordPtr[1]->size > 2) + tex_fallback = GL_TRUE; + EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F); + AGPParseSet |= SiS_PS_HAS_UV1; + } + FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback); + + if (!RENDERINPUTS_EQUAL( smesa->last_tcl_state_bitset, index_bitset )) { + smesa->AGPParseSet = AGPParseSet; + + smesa->vertex_size = _tnl_install_attrs( ctx, smesa->vertex_attrs, + smesa->vertex_attr_count, smesa->hw_viewport, 0 ); + + smesa->vertex_size >>= 2; + smesa->AGPParseSet |= smesa->vertex_size << 28; + } } static void sisRenderFinish( GLcontext *ctx ) { } -/* Update SpaceLeft after an engine or current write pointer update */ -static void sisUpdateAGP( sisContextPtr smesa ) -{ - /* ReadPtr == WritePtr is the empty case */ - if (AGP_ReadPtr <= AGP_WritePtr) - AGP_SpaceLeft = (long)smesa->AGPCmdBufBase + (long)smesa->AGPCmdBufSize - - (long)AGP_WritePtr; - else - AGP_SpaceLeft = AGP_ReadPtr - AGP_WritePtr - 4; -} +/**********************************************************************/ +/* AGP/PCI vertex submission */ +/**********************************************************************/ -/* Fires a set of vertices that have been written from AGP_StartPtr to - * AGP_WritePtr, using the smesa->AGPParseSet format. - */ void -sisFireVertsAGP( sisContextPtr smesa ) +sisFlushPrimsLocked(sisContextPtr smesa) { - if (AGP_WritePtr == AGP_StartPtr) + if (smesa->vb_cur == smesa->vb_last) return; - mWait3DCmdQueue(5); - mEndPrimitive(); - MMIO(REG_3D_AGPCmBase, (long)AGP_StartPtr - (long)smesa->AGPCmdBufBase + - (long)smesa->AGPCmdBufAddr); - MMIO(REG_3D_AGPTtDwNum, (((long)AGP_WritePtr - (long)AGP_StartPtr) >> 2) | - 0x50000000); - MMIO(REG_3D_ParsingSet, smesa->AGPParseSet); - - MMIO(REG_3D_AGPCmFire, (GLint)(-1)); - mEndPrimitive(); - - *(smesa->pAGPCmdBufNext) = (((long)AGP_WritePtr - - (long)smesa->AGPCmdBufBase) + 0xf) & ~0xf; - AGP_StartPtr = AGP_WritePtr; - sisUpdateAGP( smesa ); -} + if (smesa->is6326) + sis6326UpdateHWState(smesa->glCtx); + else + sisUpdateHWState(smesa->glCtx); -/* Make sure there are more than num dwords left in the AGP queue. */ -static void -sisMakeRoomAGP( sisContextPtr smesa, GLint num ) -{ - int size = num * 4; - - if (size <= AGP_SpaceLeft) { - AGP_SpaceLeft -= size; - return; - } - /* Wrapping */ - if (AGP_WritePtr + num > (GLfloat *)(smesa->AGPCmdBufBase + - smesa->AGPCmdBufSize)) - { - sisFireVertsAGP( smesa ); - AGP_WritePtr = (GLfloat *)smesa->AGPCmdBufBase; - AGP_StartPtr = AGP_WritePtr; - sisUpdateAGP( smesa ); - WaitEngIdle( smesa ); /* XXX Why is this necessary? */ - } + if (smesa->using_agp) { + mWait3DCmdQueue(8); + mEndPrimitive(); + MMIO(REG_3D_AGPCmBase, (smesa->vb_last - smesa->vb) + + smesa->vb_agp_offset); + MMIO(REG_3D_AGPTtDwNum, ((smesa->vb_cur - smesa->vb_last) / 4) | + 0x50000000); + MMIO(REG_3D_ParsingSet, smesa->AGPParseSet); + MMIO(REG_3D_AGPCmFire, (GLint)(-1)); + mEndPrimitive(); + } else { + int mmio_index = 0, incr = 0; + void (*sis_emit_func)(sisContextPtr smesa, char *verts) = NULL; + + if (smesa->AGPParseSet & MASK_PsShadingSmooth) + mmio_index |= VERT_SMOOTH; + if (smesa->AGPParseSet & SiS_PS_HAS_SPECULAR) + mmio_index |= VERT_SPEC; + if (smesa->AGPParseSet & SiS_PS_HAS_W) + mmio_index |= VERT_W; + if (smesa->AGPParseSet & SiS_PS_HAS_UV0) + mmio_index |= VERT_UV0; + if (smesa->AGPParseSet & SiS_PS_HAS_UV1) + mmio_index |= VERT_UV1; + if (smesa->is6326) + mmio_index |= VERT_6326; + + switch (smesa->AGPParseSet & MASK_PsDataType) { + case MASK_PsPointList: + incr = smesa->vertex_size * 4; + sis_emit_func = sis_point_func_mmio[mmio_index]; + break; + case MASK_PsLineList: + incr = smesa->vertex_size * 4 * 2; + sis_emit_func = sis_line_func_mmio[mmio_index]; + break; + case MASK_PsTriangleList: + incr = smesa->vertex_size * 4 * 3; + sis_emit_func = sis_tri_func_mmio[mmio_index]; + break; + } - if (size > AGP_SpaceLeft) { - /* Update the cached engine read pointer */ - AGP_ReadPtr = (GLfloat *)((long)MMIO_READ(REG_3D_AGPCmBase) - - (long)smesa->AGPCmdBufAddr + (long)smesa->AGPCmdBufBase); - sisUpdateAGP( smesa ); - while (size > AGP_SpaceLeft) { - /* Spin until space is available. */ - AGP_ReadPtr = (GLfloat *)((long)MMIO_READ(REG_3D_AGPCmBase) - - (long)smesa->AGPCmdBufAddr + (long)smesa->AGPCmdBufBase); - sisUpdateAGP( smesa ); + if (!smesa->is6326) { + mWait3DCmdQueue(1); + MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet); + } + while (smesa->vb_last < smesa->vb_cur) { + sis_emit_func(smesa, (char *)smesa->vb_last); + smesa->vb_last += incr; } + mWait3DCmdQueue(1); + mEndPrimitive(); + + /* With PCI, we can just start writing to the start of the VB again. */ + smesa->vb_cur = smesa->vb; } - AGP_SpaceLeft -= size; + smesa->vb_last = smesa->vb_cur; +} + +void sisFlushPrims(sisContextPtr smesa) +{ + LOCK_HARDWARE(); + sisFlushPrimsLocked(smesa); + UNLOCK_HARDWARE(); } /**********************************************************************/ /* Transition to/from hardware rasterization. */ /**********************************************************************/ +static const char * const fallbackStrings[] = { + "Texture mode", + "Texture 0 mode", + "Texture 1 mode", + "Texture 0 env", /* Note: unused */ + "Texture 1 env", /* Note: unused */ + "glDrawBuffer(GL_FRONT_AND_BACK)", + "glEnable(GL_STENCIL) without hw stencil buffer", + "write mask", + "no_rast", +}; + +static const char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) { TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -896,8 +1048,13 @@ void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) if (mode) { smesa->Fallback |= bit; if (oldfallback == 0) { + SIS_FIREVERTICES(smesa); _swsetup_Wakeup( ctx ); smesa->RenderIndex = ~0; + if (SIS_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "SiS begin rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } } } else { @@ -907,9 +1064,23 @@ void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) tnl->Driver.Render.Start = sisRenderStart; tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive; tnl->Driver.Render.Finish = sisRenderFinish; - tnl->Driver.Render.BuildVertices = sisBuildVertices; - smesa->NewGLState |= (_SIS_NEW_RENDER_STATE| - _SIS_NEW_VERTEX_STATE); + + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + _tnl_install_attrs( ctx, + smesa->vertex_attrs, + smesa->vertex_attr_count, + smesa->hw_viewport, 0 ); + + smesa->NewGLState |= _SIS_NEW_RENDER_STATE; + if (SIS_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "SiS end rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } } } } @@ -930,29 +1101,54 @@ void sisInitTriFuncs( GLcontext *ctx ) firsttime = 0; sis_vert_init_none(); + sis_vert_init_g(); + sis_vert_init_w(); + sis_vert_init_gw(); sis_vert_init_s(); + sis_vert_init_gs(); + sis_vert_init_ws(); + sis_vert_init_gws(); sis_vert_init_t0(); + sis_vert_init_gt0(); + sis_vert_init_wt0(); + sis_vert_init_gwt0(); sis_vert_init_st0(); + sis_vert_init_gst0(); + sis_vert_init_wst0(); + sis_vert_init_gwst0(); sis_vert_init_t1(); + sis_vert_init_gt1(); + sis_vert_init_wt1(); + sis_vert_init_gwt1(); sis_vert_init_st1(); + sis_vert_init_gst1(); + sis_vert_init_wst1(); + sis_vert_init_gwst1(); sis_vert_init_t0t1(); + sis_vert_init_gt0t1(); + sis_vert_init_wt0t1(); + sis_vert_init_gwt0t1(); sis_vert_init_st0t1(); + sis_vert_init_gst0t1(); + sis_vert_init_wst0t1(); + sis_vert_init_gwst0t1(); } + smesa->RenderIndex = ~0; + smesa->NewGLState |= _SIS_NEW_RENDER_STATE; + tnl->Driver.RunPipeline = sisRunPipeline; tnl->Driver.Render.Start = sisRenderStart; tnl->Driver.Render.Finish = sisRenderFinish; tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive; tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.Render.BuildVertices = sisBuildVertices; - tnl->Driver.Render.Multipass = NULL; - if (driQueryOptionb(&smesa->optionCache, "fallback_force")) - sisFallback(ctx, SIS_FALLBACK_FORCE, 1); - else - sisFallback(ctx, SIS_FALLBACK_FORCE, 0); + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; - smesa->RenderIndex = ~0; - smesa->NewGLState |= (_SIS_NEW_RENDER_STATE| - _SIS_NEW_VERTEX_STATE); + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) ); + + smesa->verts = (char *)tnl->clipspace.vertex_buf; }