tdfx_tris.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,294 行 · 第 1/3 页
C
1,294 行
#define INIT(x) tdfxRenderPrimitive( ctx, x )#undef LOCAL_VARS#define LOCAL_VARS \ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ tdfxVertex *vertptr = fxMesa->verts; \ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ (void) elt;#define RESET_STIPPLE #define RESET_OCCLUSION #define PRESERVE_VB_DEFS/* Elts, no clipping. */#undef ELT#undef TAG#define TAG(x) tdfx_##x##_elts#define ELT(x) elt[x]#include "tnl_dd/t_dd_rendertmp.h"/* Verts, no clipping. */#undef ELT#undef TAG#define TAG(x) tdfx_##x##_verts#define ELT(x) x/*#include "tnl_dd/t_dd_rendertmp.h"*//**********************************************************************//* Render clipped primitives *//**********************************************************************/static void tdfxRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint prim = fxMesa->render_primitive; /* 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; } /* Restore the render primitive */ if (prim != GL_POLYGON) tnl->Driver.Render.PrimitiveNotify( ctx, prim );}static void tdfxRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ){ TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->Driver.Render.Line( ctx, ii, jj );}static void tdfxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ){ int i; tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); tdfxVertex *vertptr = fxMesa->verts; if (n == 3) { fxMesa->Glide.grDrawTriangle( VERT(elts[0]), VERT(elts[1]), VERT(elts[2]) ); } else if (n <= 32) { tdfxVertex *newvptr[32]; for (i = 0 ; i < n ; i++) { newvptr[i] = VERT(elts[i]); } fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, n, newvptr); } else { const tdfxVertex *start = VERT(elts[0]); for (i = 2 ; i < n ; i++) { fxMesa->Glide.grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); } }}/**********************************************************************//* Choose render functions *//**********************************************************************/#define POINT_FALLBACK (DD_POINT_SMOOTH)#define LINE_FALLBACK (DD_LINE_STIPPLE)#define TRI_FALLBACK (DD_TRI_SMOOTH)#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE)#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \ DD_TRI_UNFILLED)/* All state referenced below: */#define _TDFX_NEW_RENDERSTATE (_DD_NEW_POINT_SMOOTH | \ _DD_NEW_LINE_STIPPLE | \ _DD_NEW_TRI_SMOOTH | \ _DD_NEW_FLATSHADE | \ _DD_NEW_TRI_UNFILLED | \ _DD_NEW_TRI_LIGHT_TWOSIDE | \ _DD_NEW_TRI_OFFSET | \ _DD_NEW_TRI_STIPPLE | \ _NEW_POLYGONSTIPPLE)static void tdfxChooseRenderState(GLcontext *ctx){ TNLcontext *tnl = TNL_CONTEXT(ctx); tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint index = 0; if (0) { fxMesa->draw_point = tdfx_draw_point; fxMesa->draw_line = tdfx_draw_line; fxMesa->draw_triangle = tdfx_draw_triangle; index |= TDFX_FALLBACK_BIT; } if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { if (flags & ANY_RASTER_FLAGS) { if (flags & DD_TRI_LIGHT_TWOSIDE) index |= TDFX_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= TDFX_OFFSET_BIT; if (flags & DD_TRI_UNFILLED) index |= TDFX_UNFILLED_BIT; if (flags & DD_FLATSHADE) index |= TDFX_FLAT_BIT; } fxMesa->draw_point = tdfx_draw_point; fxMesa->draw_line = tdfx_draw_line; fxMesa->draw_triangle = tdfx_draw_triangle; /* Hook in fallbacks for specific primitives. * * DD_TRI_UNFILLED is here because the unfilled_tri functions use * fxMesa->draw_tri *always*, and thus can't use the multipass * approach to cliprects. * */ if (flags & (POINT_FALLBACK| LINE_FALLBACK| TRI_FALLBACK| DD_TRI_STIPPLE| DD_TRI_UNFILLED)) { if (flags & POINT_FALLBACK) fxMesa->draw_point = tdfx_fallback_point; if (flags & LINE_FALLBACK) fxMesa->draw_line = tdfx_fallback_line; if (flags & TRI_FALLBACK) fxMesa->draw_triangle = tdfx_fallback_tri; if ((flags & DD_TRI_STIPPLE) && !fxMesa->haveHwStipple) fxMesa->draw_triangle = tdfx_fallback_tri; index |= TDFX_FALLBACK_BIT; } } if (fxMesa->RenderIndex != index) { fxMesa->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 (index == 0) { tnl->Driver.Render.PrimTabVerts = tdfx_render_tab_verts; tnl->Driver.Render.PrimTabElts = tdfx_render_tab_elts; tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ tnl->Driver.Render.ClippedPolygon = tdfxFastRenderClippedPoly; } else { tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.ClippedLine = tdfxRenderClippedLine; tnl->Driver.Render.ClippedPolygon = tdfxRenderClippedPoly; } }}/**********************************************************************//* Use multipass rendering for cliprects *//**********************************************************************//* TODO: Benchmark this. * TODO: Use single back-buffer cliprect where possible. * NOTE: <pass> starts at 1, not zero! */static GLboolean multipass_cliprect( GLcontext *ctx, GLuint pass ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if (pass >= fxMesa->numClipRects) return GL_FALSE; else { fxMesa->Glide.grClipWindow(fxMesa->pClipRects[pass].x1, fxMesa->screen_height - fxMesa->pClipRects[pass].y2, fxMesa->pClipRects[pass].x2, fxMesa->screen_height - fxMesa->pClipRects[pass].y1); return GL_TRUE; }}/**********************************************************************//* Runtime render state and callbacks *//**********************************************************************/static void tdfxRunPipeline( GLcontext *ctx ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if (fxMesa->new_state) { tdfxDDUpdateHwState( ctx ); } if (!fxMesa->Fallback && fxMesa->new_gl_state) { if (fxMesa->new_gl_state & _TDFX_NEW_RASTERSETUP) tdfxChooseVertexState( ctx ); if (fxMesa->new_gl_state & _TDFX_NEW_RENDERSTATE) tdfxChooseRenderState( ctx ); fxMesa->new_gl_state = 0; } _tnl_run_pipeline( ctx );}static void tdfxRenderStart( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxCheckTexSizes( ctx ); LOCK_HARDWARE(fxMesa); /* Make sure vertex format changes get uploaded before we start * sending triangles. */ if (fxMesa->dirty) { tdfxEmitHwStateLocked( fxMesa ); } if (fxMesa->numClipRects && !(fxMesa->RenderIndex & TDFX_FALLBACK_BIT)) { fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1, fxMesa->screen_height - fxMesa->pClipRects[0].y2, fxMesa->pClipRects[0].x2, fxMesa->screen_height - fxMesa->pClipRects[0].y1); if (fxMesa->numClipRects > 1) tnl->Driver.Render.Multipass = multipass_cliprect; else tnl->Driver.Render.Multipass = NULL; } else tnl->Driver.Render.Multipass = NULL;}/* Always called between RenderStart and RenderFinish --> We already * hold the lock. */static void tdfxRasterPrimitive( GLcontext *ctx, GLenum prim ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); FLUSH_BATCH( fxMesa ); fxMesa->raster_primitive = prim; tdfxUpdateCull(ctx); if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) { fxMesa->Glide.grCullMode( fxMesa->CullMode ); fxMesa->dirty &= ~TDFX_UPLOAD_CULL; } tdfxUpdateStipple(ctx); if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE ) { fxMesa->Glide.grStipplePattern ( fxMesa->Stipple.Pattern ); fxMesa->Glide.grStippleMode ( fxMesa->Stipple.Mode ); fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE; }}/* 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 tdfx_render.c. */static void tdfxRenderPrimitive( GLcontext *ctx, GLenum prim ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GLuint rprim = reduced_prim[prim]; fxMesa->render_primitive = prim; if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; if (fxMesa->raster_primitive != rprim) { tdfxRasterPrimitive( ctx, rprim ); }}static void tdfxRenderFinish( GLcontext *ctx ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if (fxMesa->RenderIndex & TDFX_FALLBACK_BIT) _swrast_flush( ctx ); UNLOCK_HARDWARE(fxMesa);}/**********************************************************************//* Manage total rasterization fallbacks *//**********************************************************************/static char *fallbackStrings[] = { "3D/Rect/Cube Texture map", "glDrawBuffer(GL_FRONT_AND_BACK)", "Separate specular color", "glEnable/Disable(GL_STENCIL_TEST)", "glRenderMode(selection or feedback)", "glLogicOp()", "Texture env mode", "Texture border", "glColorMask", "blend mode", "line stipple", "Rasterization disable"};static char *getFallbackString(GLuint bit){ int i = 0; while (bit > 1) { i++; bit >>= 1; } return fallbackStrings[i];}void tdfxFallback( GLcontext *ctx, GLuint bit, GLboolean mode ){ TNLcontext *tnl = TNL_CONTEXT(ctx); tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GLuint oldfallback = fxMesa->Fallback; if (mode) { fxMesa->Fallback |= bit; if (oldfallback == 0) { /*printf("Go to software rendering, bit = 0x%x\n", bit);*/ FLUSH_BATCH(fxMesa); _swsetup_Wakeup( ctx ); fxMesa->RenderIndex = ~0; if (TDFX_DEBUG & DEBUG_VERBOSE_FALL) { fprintf(stderr, "Tdfx begin software fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } } else { fxMesa->Fallback &= ~bit; if (oldfallback == bit) { /*printf("Go to hardware rendering, bit = 0x%x\n", bit);*/ _swrast_flush( ctx ); tnl->Driver.Render.Start = tdfxRenderStart; tnl->Driver.Render.PrimitiveNotify = tdfxRenderPrimitive; tnl->Driver.Render.Finish = tdfxRenderFinish; tnl->Driver.Render.BuildVertices = tdfxBuildVertices; fxMesa->new_gl_state |= (_TDFX_NEW_RENDERSTATE| _TDFX_NEW_RASTERSETUP); if (TDFX_DEBUG & DEBUG_VERBOSE_FALL) { fprintf(stderr, "Tdfx end software fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } }}void tdfxDDInitTriFuncs( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); static int firsttime = 1; if (firsttime) { init_rast_tab(); firsttime = 0; } fxMesa->RenderIndex = ~0; tnl->Driver.RunPipeline = tdfxRunPipeline; tnl->Driver.Render.Start = tdfxRenderStart; tnl->Driver.Render.Finish = tdfxRenderFinish; tnl->Driver.Render.PrimitiveNotify = tdfxRenderPrimitive; tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; tnl->Driver.Render.BuildVertices = tdfxBuildVertices; tnl->Driver.Render.Multipass = NULL; (void) tdfx_print_vertex;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?