/* * Author: Max Lingua */ #include #include #include #include "s3v_context.h" #include "s3v_vb.h" #include "s3v_tris.h" #include "main/glheader.h" #include "main/mtypes.h" #include "main/macros.h" #include "main/colormac.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" /*********************************************************************** * Build hardware rasterization functions * ***********************************************************************/ #define DO_TRI 1 #define HAVE_RGBA 1 #define HAVE_SPEC 0 #define HAVE_BACK_COLORS 0 #define HAVE_HW_FLATSHADE 1 #define VERTEX s3vVertex #define TAB rast_tab #define VERT_SET_RGBA( v, c ) \ do { \ UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c); \ /* *(v->ub4[4]) = c; \ */ \ } while (0) #define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4] /* #define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4] */ #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4] #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx] #define S3V_OFFSET_BIT 0x01 #define S3V_TWOSIDE_BIT 0x02 #define S3V_UNFILLED_BIT 0x04 #define S3V_FALLBACK_BIT 0x08 #define S3V_MAX_TRIFUNC 0x10 static struct { tnl_points_func points; tnl_line_func line; tnl_triangle_func triangle; tnl_quad_func quad; } rast_tab[S3V_MAX_TRIFUNC]; #define S3V_RAST_CULL_BIT 0x01 #define S3V_RAST_FLAT_BIT 0x02 #define S3V_RAST_TEX_BIT 0x04 static s3v_point_func s3v_point_tab[0x8]; static s3v_line_func s3v_line_tab[0x8]; static s3v_tri_func s3v_tri_tab[0x8]; static s3v_quad_func s3v_quad_tab[0x8]; #define IND (0) #define TAG(x) x #include "s3v_tritmp.h" #define IND (S3V_RAST_CULL_BIT) #define TAG(x) x##_cull #include "s3v_tritmp.h" #define IND (S3V_RAST_FLAT_BIT) #define TAG(x) x##_flat #include "s3v_tritmp.h" #define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT) #define TAG(x) x##_cull_flat #include "s3v_tritmp.h" #define IND (S3V_RAST_TEX_BIT) #define TAG(x) x##_tex #include "s3v_tritmp.h" #define IND (S3V_RAST_CULL_BIT|S3V_RAST_TEX_BIT) #define TAG(x) x##_cull_tex #include "s3v_tritmp.h" #define IND (S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT) #define TAG(x) x##_flat_tex #include "s3v_tritmp.h" #define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT) #define TAG(x) x##_cull_flat_tex #include "s3v_tritmp.h" static void init_rast_tab( void ) { DEBUG(("*** init_rast_tab ***\n")); s3v_init(); s3v_init_cull(); s3v_init_flat(); s3v_init_cull_flat(); s3v_init_tex(); s3v_init_cull_tex(); s3v_init_flat_tex(); s3v_init_cull_flat_tex(); } /*********************************************************************** * Rasterization fallback helpers * ***********************************************************************/ /* This code is hit only when a mix of accelerated and unaccelerated * primitives are being drawn, and only for the unaccelerated * primitives. */ #if 0 static void s3v_fallback_quad( s3vContextPtr vmesa, const s3vVertex *v0, const s3vVertex *v1, const s3vVertex *v2, const s3vVertex *v3 ) { GLcontext *ctx = vmesa->glCtx; SWvertex v[4]; s3v_translate_vertex( ctx, v0, &v[0] ); s3v_translate_vertex( ctx, v1, &v[1] ); s3v_translate_vertex( ctx, v2, &v[2] ); s3v_translate_vertex( ctx, v3, &v[3] ); DEBUG(("s3v_fallback_quad\n")); /* _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] ); */ } static void s3v_fallback_tri( s3vContextPtr vmesa, const s3vVertex *v0, const s3vVertex *v1, const s3vVertex *v2 ) { GLcontext *ctx = vmesa->glCtx; SWvertex v[3]; s3v_translate_vertex( ctx, v0, &v[0] ); s3v_translate_vertex( ctx, v1, &v[1] ); s3v_translate_vertex( ctx, v2, &v[2] ); DEBUG(("s3v_fallback_tri\n")); /* _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); */ } static void s3v_fallback_line( s3vContextPtr vmesa, const s3vVertex *v0, const s3vVertex *v1 ) { GLcontext *ctx = vmesa->glCtx; SWvertex v[2]; s3v_translate_vertex( ctx, v0, &v[0] ); s3v_translate_vertex( ctx, v1, &v[1] ); DEBUG(("s3v_fallback_line\n")); _swrast_Line( ctx, &v[0], &v[1] ); } /* static void s3v_fallback_point( s3vContextPtr vmesa, const s3vVertex *v0 ) { GLcontext *ctx = vmesa->glCtx; SWvertex v[1]; s3v_translate_vertex( ctx, v0, &v[0] ); _swrast_Point( ctx, &v[0] ); } */ #endif /*********************************************************************** * Choose rasterization functions * ***********************************************************************/ #define _S3V_NEW_RASTER_STATE (_NEW_FOG | \ _NEW_TEXTURE | \ _DD_NEW_TRI_SMOOTH | \ _DD_NEW_LINE_SMOOTH | \ _DD_NEW_POINT_SMOOTH | \ _DD_NEW_TRI_STIPPLE | \ _DD_NEW_LINE_STIPPLE) #define LINE_FALLBACK (0) #define TRI_FALLBACK (0) static void s3v_nodraw_triangle(GLcontext *ctx, s3vVertex *v0, s3vVertex *v1, s3vVertex *v2) { (void) (ctx && v0 && v1 && v2); } static void s3v_nodraw_quad(GLcontext *ctx, s3vVertex *v0, s3vVertex *v1, s3vVertex *v2, s3vVertex *v3) { (void) (ctx && v0 && v1 && v2 && v3); } void s3vChooseRasterState(GLcontext *ctx); void s3vChooseRasterState(GLcontext *ctx) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint ind = 0; DEBUG(("*** s3vChooseRasterState ***\n")); if (ctx->Polygon.CullFlag) { if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) { vmesa->draw_tri = (s3v_tri_func)s3v_nodraw_triangle; vmesa->draw_quad = (s3v_quad_func)s3v_nodraw_quad; return; } ind |= S3V_RAST_CULL_BIT; /* s3v_update_cullsign(ctx); */ } /* else vmesa->backface_sign = 0; */ if ( flags & DD_FLATSHADE ) ind |= S3V_RAST_FLAT_BIT; if ( ctx->Texture.Unit[0]._ReallyEnabled ) { ind |= S3V_RAST_TEX_BIT; } DEBUG(("ind = %i\n", ind)); vmesa->draw_line = s3v_line_tab[ind]; vmesa->draw_tri = s3v_tri_tab[ind]; vmesa->draw_quad = s3v_quad_tab[ind]; vmesa->draw_point = s3v_point_tab[ind]; #if 0 /* Hook in fallbacks for specific primitives. CURRENTLY DISABLED */ if (flags & LINE_FALLBACK) vmesa->draw_line = s3v_fallback_line; if (flags & TRI_FALLBACK) { DEBUG(("TRI_FALLBACK\n")); vmesa->draw_tri = s3v_fallback_tri; vmesa->draw_quad = s3v_fallback_quad; } #endif } /*********************************************************************** * Macros for t_dd_tritmp.h to draw basic primitives * ***********************************************************************/ #define TRI( v0, v1, v2 ) \ do { \ /* if (DO_FALLBACK) \ vmesa->draw_tri( vmesa, v0, v1, v2 ); \ else */ \ DEBUG(("TRI: max was here\n")); /* \ s3v_draw_tex_triangle( vmesa, v0, v1, v2 ); */ \ vmesa->draw_tri( vmesa, v0, v1, v2 ); \ } while (0) #define QUAD( v0, v1, v2, v3 ) \ do { \ DEBUG(("QUAD: max was here\n")); \ vmesa->draw_quad( vmesa, v0, v1, v2, v3 ); \ } while (0) #define LINE( v0, v1 ) \ do { \ DEBUG(("LINE: max was here\n")); \ vmesa->draw_line( vmesa, v0, v1 ); \ } while (0) #define POINT( v0 ) \ do { \ vmesa->draw_point( vmesa, v0 ); \ } while (0) /*********************************************************************** * Build render functions from dd templates * ***********************************************************************/ /* #define S3V_OFFSET_BIT 0x01 #define S3V_TWOSIDE_BIT 0x02 #define S3V_UNFILLED_BIT 0x04 #define S3V_FALLBACK_BIT 0x08 #define S3V_MAX_TRIFUNC 0x10 static struct { points_func points; line_func line; triangle_func triangle; quad_func quad; } rast_tab[S3V_MAX_TRIFUNC]; */ #define DO_FALLBACK (IND & S3V_FALLBACK_BIT) #define DO_OFFSET (IND & S3V_OFFSET_BIT) #define DO_UNFILLED (IND & S3V_UNFILLED_BIT) #define DO_TWOSIDE (IND & S3V_TWOSIDE_BIT) #define DO_FLAT 0 #define DO_TRI 1 #define DO_QUAD 1 #define DO_LINE 1 #define DO_POINTS 1 #define DO_FULL_QUAD 1 #define HAVE_RGBA 1 #define HAVE_SPEC 0 #define HAVE_BACK_COLORS 0 #define HAVE_HW_FLATSHADE 1 #define VERTEX s3vVertex #define TAB rast_tab #define DEPTH_SCALE 1.0 #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) (vmesa->verts + (e<vertex_stride_shift)) #if 0 #define VERT_SET_RGBA( v, c ) \ do { \ /* UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c) */ \ } while (0) #define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4] /* #define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4] */ #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4] #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx] #endif #define LOCAL_VARS(n) \ s3vContextPtr vmesa = S3V_CONTEXT(ctx); \ GLuint color[n]; \ (void) color; /*********************************************************************** * Helpers for rendering unfilled primitives * ***********************************************************************/ static const GLuint hw_prim[GL_POLYGON+1] = { PrimType_Points, PrimType_Lines, PrimType_Lines, PrimType_Lines, PrimType_Triangles, PrimType_Triangles, PrimType_Triangles, PrimType_Triangles, PrimType_Triangles, PrimType_Triangles }; static void s3vResetLineStipple( GLcontext *ctx ); static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim ); static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim ); /* extern static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end); extern static void s3v_tris_emit(GLcontext *ctx, GLuint start, GLuint end); */ #define RASTERIZE(x) if (vmesa->hw_primitive != hw_prim[x]) \ s3vRasterPrimitive( ctx, hw_prim[x] ) #define RENDER_PRIMITIVE vmesa->render_primitive #define TAG(x) x #define IND S3V_FALLBACK_BIT #include "tnl_dd/t_dd_unfilled.h" #undef IND /*********************************************************************** * Generate GL render functions * ***********************************************************************/ #define IND (0) #define TAG(x) x #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_OFFSET_BIT) #define TAG(x) x##_offset #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_TWOSIDE_BIT) #define TAG(x) x##_twoside #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT) #define TAG(x) x##_twoside_offset #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_UNFILLED_BIT) #define TAG(x) x##_unfilled #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_OFFSET_BIT|S3V_UNFILLED_BIT) #define TAG(x) x##_offset_unfilled #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_TWOSIDE_BIT|S3V_UNFILLED_BIT) #define TAG(x) x##_twoside_unfilled #include "tnl_dd/t_dd_tritmp.h" #define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT|S3V_UNFILLED_BIT) #define TAG(x) x##_twoside_offset_unfilled #include "tnl_dd/t_dd_tritmp.h" static void init_render_tab( void ) { DEBUG(("*** init_render_tab ***\n")); init(); init_offset(); init_twoside(); init_twoside_offset(); init_unfilled(); init_offset_unfilled(); init_twoside_unfilled(); init_twoside_offset_unfilled(); } /**********************************************************************/ /* Render unclipped begin/end objects */ /**********************************************************************/ #define VERT(x) (s3vVertex *)(s3vverts + (x << shift)) #define RENDER_POINTS( start, count ) \ DEBUG(("RENDER_POINTS...(ok)\n")); \ for ( ; start < count ; start++) \ vmesa->draw_line( vmesa, VERT(start), VERT(start) ) /* vmesa->draw_point( vmesa, VERT(start) ) */ #define RENDER_LINE( v0, v1 ) \ /* DEBUG(("RENDER_LINE...(ok)\n")); \ */ \ vmesa->draw_line( vmesa, VERT(v0), VERT(v1) ); \ DEBUG(("RENDER_LINE...(ok)\n")) #define RENDER_TRI( v0, v1, v2 ) \ DEBUG(("RENDER_TRI...(ok)\n")); \ vmesa->draw_tri( vmesa, VERT(v0), VERT(v1), VERT(v2) ) #define RENDER_QUAD( v0, v1, v2, v3 ) \ DEBUG(("RENDER_QUAD...(ok)\n")); \ /* s3v_draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2),VERT(v3) ) */\ /* s3v_draw_triangle( vmesa, VERT(v0), VERT(v1), VERT(v2) ); \ s3v_draw_triangle( vmesa, VERT(v0), VERT(v2), VERT(v3) ) */ \ vmesa->draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) #define INIT(x) s3vRenderPrimitive( ctx, x ); #undef LOCAL_VARS #define LOCAL_VARS \ s3vContextPtr vmesa = S3V_CONTEXT(ctx); \ const GLuint shift = vmesa->vertex_stride_shift; \ const char *s3vverts = (char *)vmesa->verts; \ const GLboolean stipple = ctx->Line.StippleFlag; \ (void) stipple; #define RESET_STIPPLE if ( stipple ) s3vResetLineStipple( ctx ); #define RESET_OCCLUSION #define PRESERVE_VB_DEFS #define ELT(x) (x) #define TAG(x) s3v_##x##_verts #include "tnl_dd/t_dd_rendertmp.h" /**********************************************************************/ /* Render clipped primitives */ /**********************************************************************/ static void s3vRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint prim = vmesa->render_primitive; DEBUG(("I AM in: s3vRenderClippedPoly\n")); /* Render the new vertices as an unclipped polygon. */ if (1) { GLuint *tmp = VB->Elts; VB->Elts = (GLuint *)elts; tnl->Driver.Render.PrimTabElts[GL_POLYGON] ( ctx, 0, n, PRIM_BEGIN|PRIM_END ); VB->Elts = tmp; } /* Restore the render primitive */ #if 1 if (prim != GL_POLYGON) { DEBUG(("and prim != GL_POLYGON\n")); tnl->Driver.Render.PrimitiveNotify( ctx, prim ); } #endif } static void s3vRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) { TNLcontext *tnl = TNL_CONTEXT(ctx); /*tnl->Driver.LineFunc = s3v_line_tab[2];*/ /* _swsetup_Line; */ DEBUG(("I AM in: s3vRenderClippedLine\n")); tnl->Driver.Render.Line( ctx, ii, jj ); } /**********************************************************************/ /* Choose render functions */ /**********************************************************************/ #define _S3V_NEW_RENDERSTATE (_DD_NEW_TRI_UNFILLED | \ _DD_NEW_TRI_LIGHT_TWOSIDE | \ _DD_NEW_TRI_OFFSET) #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) static void s3vChooseRenderState(GLcontext *ctx) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint index = 0; DEBUG(("s3vChooseRenderState\n")); if (flags & ANY_RASTER_FLAGS) { if (flags & DD_TRI_LIGHT_TWOSIDE) index |= S3V_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= S3V_OFFSET_BIT; if (flags & DD_TRI_UNFILLED) index |= S3V_UNFILLED_BIT; } DEBUG(("vmesa->RenderIndex = %i\n", vmesa->RenderIndex)); DEBUG(("index = %i\n", index)); if (vmesa->RenderIndex != index) { vmesa->RenderIndex = index; tnl->Driver.Render.Points = rast_tab[index].points; tnl->Driver.Render.Line = rast_tab[index].line; tnl->Driver.Render.Triangle = rast_tab[index].triangle; tnl->Driver.Render.Quad = rast_tab[index].quad; if (vmesa->RenderIndex == 0) tnl->Driver.Render.PrimTabVerts = s3v_render_tab_verts; else tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.ClippedLine = s3vRenderClippedLine; tnl->Driver.Render.ClippedPolygon = s3vRenderClippedPoly; } } /**********************************************************************/ /* High level hooks for t_vb_render.c */ /**********************************************************************/ /* Determine the rasterized primitive when not drawing unfilled * polygons. * * Used only for the default render stage which always decomposes * primitives to trianges/lines/points. For the accelerated stage, * which renders strips as strips, the equivalent calculations are * performed in s3v_render.c. */ static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); /* __DRIdrawablePrivate *dPriv = vmesa->driDrawable; */ GLuint cmd = vmesa->CMD; unsigned int _hw_prim = hwprim; DEBUG(("s3vRasterPrimitive: hwprim = 0x%x ", _hw_prim)); /* printf("* vmesa->CMD = 0x%x\n", vmesa->CMD); */ if (vmesa->hw_primitive != _hw_prim) { DEBUG(("(new one) ***\n")); cmd &= ~DO_MASK; cmd &= ~ALPHA_BLEND_MASK; vmesa->hw_primitive = _hw_prim; if (_hw_prim == PrimType_Triangles) { /* TRI */ DEBUG(("->switching to tri\n")); cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]); } else if (_hw_prim == PrimType_Lines || _hw_prim == PrimType_Points) { /* LINE */ DEBUG(("->switching to line\n")); cmd |= (DO_3D_LINE | vmesa->_alpha[0]); } else { /* ugh? */ DEBUG(("->switching to your sis'ass\n")); } DEBUG(("\n")); vmesa->restore_primitive = _hw_prim; /* 0xacc16827: good value -> lightened newave!!! */ vmesa->CMD = cmd; CMDCHANGE(); } } static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = vmesa->driDrawable; GLuint cmd = vmesa->CMD; unsigned int _hw_prim = hw_prim[prim]; vmesa->render_primitive = prim; vmesa->hw_primitive = _hw_prim; DEBUG(("s3vRenderPrimitive #%i ", prim)); DEBUG(("_hw_prim = 0x%x\n", _hw_prim)); /* printf(" vmesa->CMD = 0x%x\n", vmesa->CMD); */ if (_hw_prim != vmesa->restore_primitive) { DEBUG(("_hw_prim != vmesa->restore_primitive (was 0x%x)\n", vmesa->restore_primitive)); #if 1 cmd &= ~DO_MASK; cmd &= ~ALPHA_BLEND_MASK; /* printf(" cmd = 0x%x\n", cmd); printf(" vmesa->_3d_mode=%i; vmesa->_tri[vmesa->_3d_mode]=0x%x\n", vmesa->_3d_mode, vmesa->_tri[vmesa->_3d_mode]); printf("vmesa->alpha[0] = 0x%x; vmesa->alpha[1] = 0x%x\n", vmesa->_alpha[0], vmesa->_alpha[1]); */ if (_hw_prim == PrimType_Triangles) { /* TRI */ DEBUG(("->switching to tri\n")); cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]); DEBUG(("vmesa->TexStride = %i\n", vmesa->TexStride)); DEBUG(("vmesa->TexOffset = %i\n", vmesa->TexOffset)); DMAOUT_CHECK(3DTRI_Z_BASE, 12); } else { /* LINE */ DEBUG(("->switching to line\n")); cmd |= (DO_3D_LINE | vmesa->_alpha[0]); DMAOUT_CHECK(3DLINE_Z_BASE, 12); } DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8); DMAOUT(vmesa->DestBase); /* DMAOUT(vmesa->ScissorLR); */ /* DMAOUT(vmesa->ScissorTB); */ /* NOTE: we need to restore all these values since we * are coming back from a vmesa->restore_primitive */ DMAOUT( (0 << 16) | (dPriv->w-1) ); DMAOUT( (0 << 16) | (dPriv->h-1) ); DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride ); DMAOUT(vmesa->SrcStride); DMAOUT(vmesa->TexOffset); DMAOUT(vmesa->TextureBorderColor); DMAOUT(0); /* FOG */ DMAOUT(0); DMAOUT(0); DMAOUT(cmd); /* 0xacc16827: good value -> lightened newave!!! */ DMAFINISH(); vmesa->CMD = cmd; #endif } DEBUG(("\n")); vmesa->restore_primitive = _hw_prim; } static void s3vRunPipeline( GLcontext *ctx ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); DEBUG(("*** s3vRunPipeline ***\n")); if ( vmesa->new_state ) s3vDDUpdateHWState( ctx ); if (vmesa->new_gl_state) { if (vmesa->new_gl_state & _NEW_TEXTURE) { s3vUpdateTextureState( ctx ); } if (!vmesa->Fallback) { if (vmesa->new_gl_state & _S3V_NEW_VERTEX) s3vChooseVertexState( ctx ); if (vmesa->new_gl_state & _S3V_NEW_RASTER_STATE) s3vChooseRasterState( ctx ); if (vmesa->new_gl_state & _S3V_NEW_RENDERSTATE) s3vChooseRenderState( ctx ); } vmesa->new_gl_state = 0; } _tnl_run_pipeline( ctx ); } static void s3vRenderStart( GLcontext *ctx ) { /* Check for projective texturing. Make sure all texcoord * pointers point to something. (fix in mesa?) */ DEBUG(("s3vRenderStart\n")); /* s3vCheckTexSizes( ctx ); */ } static void s3vRenderFinish( GLcontext *ctx ) { if (0) _swrast_flush( ctx ); /* never needed */ } static void s3vResetLineStipple( GLcontext *ctx ) { /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */ /* Reset the hardware stipple counter. */ /* CHECK_DMA_BUFFER(vmesa, 1); WRITE(vmesa->buf, UpdateLineStippleCounters, 0); */ } /**********************************************************************/ /* Transition to/from hardware rasterization. */ /**********************************************************************/ void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode ) { GLcontext *ctx = vmesa->glCtx; TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint oldfallback = vmesa->Fallback; DEBUG(("*** s3vFallback: ")); if (mode) { vmesa->Fallback |= bit; if (oldfallback == 0) { DEBUG(("oldfallback == 0 ***\n")); _swsetup_Wakeup( ctx ); _tnl_need_projected_coords( ctx, GL_TRUE ); vmesa->RenderIndex = ~0; } } else { DEBUG(("***\n")); vmesa->Fallback &= ~bit; if (oldfallback == bit) { _swrast_flush( ctx ); tnl->Driver.Render.Start = s3vRenderStart; tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive; tnl->Driver.Render.Finish = s3vRenderFinish; tnl->Driver.Render.BuildVertices = s3vBuildVertices; tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple; vmesa->new_gl_state |= (_S3V_NEW_RENDERSTATE| _S3V_NEW_RASTER_STATE| _S3V_NEW_VERTEX); } } } /**********************************************************************/ /* Initialization. */ /**********************************************************************/ void s3vInitTriFuncs( GLcontext *ctx ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); static int firsttime = 1; if (firsttime) { init_rast_tab(); init_render_tab(); firsttime = 0; } vmesa->RenderIndex = ~0; tnl->Driver.RunPipeline = s3vRunPipeline; tnl->Driver.Render.Start = s3vRenderStart; tnl->Driver.Render.Finish = s3vRenderFinish; tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive; tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple; /* tnl->Driver.RenderInterp = _swsetup_RenderInterp; tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV; */ tnl->Driver.Render.BuildVertices = s3vBuildVertices; }