📄 ffb_tris.c
字号:
#define TAG(x) x##_tricull#include "ffb_rendertmp.h"#define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)#define TAG(x) x##_flat_tricull#include "ffb_rendertmp.h"#define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)#define TAG(x) x##_alpha_tricull#include "ffb_rendertmp.h"#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)#define TAG(x) x##_flat_alpha_tricull#include "ffb_rendertmp.h"#undef ELT#define ELT(x) elt[x]#define IND 0#define TAG(x) x##_elt#include "ffb_rendertmp.h"#define IND (FFB_FLAT_BIT)#define TAG(x) x##_flat_elt#include "ffb_rendertmp.h"#define IND (FFB_ALPHA_BIT)#define TAG(x) x##_alpha_elt#include "ffb_rendertmp.h"#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)#define TAG(x) x##_flat_alpha_elt#include "ffb_rendertmp.h"#define IND (FFB_TRI_CULL_BIT)#define TAG(x) x##_tricull_elt#include "ffb_rendertmp.h"#define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)#define TAG(x) x##_flat_tricull_elt#include "ffb_rendertmp.h"#define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)#define TAG(x) x##_alpha_tricull_elt#include "ffb_rendertmp.h"#define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)#define TAG(x) x##_flat_alpha_tricull_elt#include "ffb_rendertmp.h"static void *render_tabs[MAX_FFB_RENDER_FUNCS];static void *render_tabs_elt[MAX_FFB_RENDER_FUNCS];static void init_render_tab(void){ int i; render_tabs[0] = render_tab; render_tabs[FFB_FLAT_BIT] = render_tab_flat; render_tabs[FFB_ALPHA_BIT] = render_tab_alpha; render_tabs[FFB_FLAT_BIT|FFB_ALPHA_BIT] = render_tab_flat_alpha; render_tabs[FFB_TRI_CULL_BIT] = render_tab_tricull; render_tabs[FFB_FLAT_BIT|FFB_TRI_CULL_BIT] = render_tab_flat_tricull; render_tabs[FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] = render_tab_alpha_tricull; render_tabs[FFB_FLAT_BIT|FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] = render_tab_flat_alpha_tricull; render_tabs_elt[0] = render_tab_elt; render_tabs_elt[FFB_FLAT_BIT] = render_tab_flat_elt; render_tabs_elt[FFB_ALPHA_BIT] = render_tab_alpha_elt; render_tabs_elt[FFB_FLAT_BIT|FFB_ALPHA_BIT] = render_tab_flat_alpha_elt; render_tabs_elt[FFB_TRI_CULL_BIT] = render_tab_tricull_elt; render_tabs_elt[FFB_FLAT_BIT|FFB_TRI_CULL_BIT] = render_tab_flat_tricull_elt; render_tabs_elt[FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] = render_tab_alpha_tricull_elt; render_tabs_elt[FFB_FLAT_BIT|FFB_ALPHA_BIT|FFB_TRI_CULL_BIT] = render_tab_flat_alpha_tricull_elt; for (i = 0; i < MAX_FFB_RENDER_FUNCS; i++) { tnl_render_func *rf = render_tabs[i]; tnl_render_func *rfe = render_tabs_elt[i]; if (i & FFB_TRI_CULL_BIT) { int from_idx = (i & ~FFB_TRI_CULL_BIT); tnl_render_func *rf_from = render_tabs[from_idx]; tnl_render_func *rfe_from = render_tabs_elt[from_idx]; int j; for (j = GL_POINTS; j < GL_TRIANGLES; j++) { rf[j] = rf_from[j]; rfe[j] = rfe_from[j]; } } }}/**********************************************************************//* Choose render functions *//**********************************************************************/#ifdef FFB_RENDER_TRACEstatic void ffbPrintRenderFlags(GLuint index, GLuint render_index){ fprintf(stderr, "ffbChooseRenderState: " "index(%s%s%s) " "render_index(%s%s%s)\n", ((index & FFB_TWOSIDE_BIT) ? "twoside " : ""), ((index & FFB_OFFSET_BIT) ? "offset " : ""), ((index & FFB_UNFILLED_BIT) ? "unfilled " : ""), ((render_index & FFB_FLAT_BIT) ? "flat " : ""), ((render_index & FFB_ALPHA_BIT) ? "alpha " : ""), ((render_index & FFB_TRI_CULL_BIT) ? "tricull " : ""));}#endifvoid ffbChooseRenderState(GLcontext *ctx){ GLuint flags = ctx->_TriangleCaps; TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint index = 0; /* Per-primitive fallbacks and the selection of fmesa->draw_* are * handled elsewhere. */ if (flags & DD_TRI_LIGHT_TWOSIDE) index |= FFB_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= FFB_OFFSET_BIT; if (flags & DD_TRI_UNFILLED) index |= FFB_UNFILLED_BIT; tnl->Driver.Render.Triangle = rast_tab[index].triangle; tnl->Driver.Render.Quad = rast_tab[index].quad; if (index == 0) { GLuint render_index = 0; if (flags & DD_FLATSHADE) render_index |= FFB_FLAT_BIT; if (ctx->Color.BlendEnabled || ctx->Color.AlphaEnabled) render_index |= FFB_ALPHA_BIT; if (ctx->Polygon.CullFlag) render_index |= FFB_TRI_CULL_BIT;#ifdef FFB_RENDER_TRACE ffbPrintRenderFlags(index, render_index);#endif tnl->Driver.Render.PrimTabVerts = render_tabs[render_index]; tnl->Driver.Render.PrimTabElts = render_tabs_elt[render_index]; } else {#ifdef FFB_RENDER_TRACE ffbPrintRenderFlags(index, 0);#endif tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; } tnl->Driver.Render.ClippedPolygon = ffbRenderClippedPolygon; tnl->Driver.Render.ClippedLine = ffbRenderClippedLine;}static void ffbRunPipeline(GLcontext *ctx){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); if (fmesa->bad_fragment_attrs == 0 && fmesa->new_gl_state) { if (fmesa->new_gl_state & _FFB_NEW_TRIANGLE) ffbChooseTriangleState(ctx); if (fmesa->new_gl_state & _FFB_NEW_LINE) ffbChooseLineState(ctx); if (fmesa->new_gl_state & _FFB_NEW_POINT) ffbChoosePointState(ctx); if (fmesa->new_gl_state & _FFB_NEW_RENDER) ffbChooseRenderState(ctx); if (fmesa->new_gl_state & _FFB_NEW_VERTEX) ffbChooseVertexState(ctx); fmesa->new_gl_state = 0; } _tnl_run_pipeline(ctx);}static void ffbRenderStart(GLcontext *ctx){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); LOCK_HARDWARE(fmesa); fmesa->hw_locked = 1; if (fmesa->state_dirty != 0) ffbSyncHardware(fmesa);}static void ffbRenderFinish(GLcontext *ctx){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); UNLOCK_HARDWARE(fmesa); fmesa->hw_locked = 0;}/* Even when doing full software rendering we need to * wrap render{start,finish} so that the hardware is kept * in sync (because multipass rendering changes the write * buffer etc.) */static void ffbSWRenderStart(GLcontext *ctx){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); LOCK_HARDWARE(fmesa); fmesa->hw_locked = 1; if (fmesa->state_dirty != 0) ffbSyncHardware(fmesa);}static void ffbSWRenderFinish(GLcontext *ctx){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); UNLOCK_HARDWARE(fmesa); fmesa->hw_locked = 0;}static void ffbRasterPrimitive(GLcontext *ctx, GLenum rprim){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint drawop, fbc, ppc; int do_sw = 0; fmesa->raster_primitive = rprim; drawop = fmesa->drawop; fbc = fmesa->fbc; ppc = fmesa->ppc & ~(FFB_PPC_ZS_MASK | FFB_PPC_CS_MASK);#ifdef STATE_TRACE fprintf(stderr, "ffbReducedPrimitiveChange: rprim(%d) ", rprim);#endif switch(rprim) { case GL_POINTS:#ifdef STATE_TRACE fprintf(stderr, "GL_POINTS ");#endif if (fmesa->draw_point == ffb_fallback_point) { do_sw = 1; break; } if (ctx->Point.SmoothFlag) { ppc |= (FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST); drawop = FFB_DRAWOP_AADOT; } else { ppc |= (FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST); drawop = FFB_DRAWOP_DOT; } break; case GL_LINES:#ifdef STATE_TRACE fprintf(stderr, "GL_LINES ");#endif if (fmesa->draw_line == ffb_fallback_line) { do_sw = 1; break; } if (ctx->_TriangleCaps & DD_FLATSHADE) { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST; } else { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR; } if (ctx->Line.SmoothFlag) drawop = FFB_DRAWOP_AALINE; else drawop = FFB_DRAWOP_DDLINE; break; case GL_TRIANGLES:#ifdef STATE_TRACE fprintf(stderr, "GL_POLYGON ");#endif if (fmesa->draw_tri == ffb_fallback_triangle) { do_sw = 1; break; } ppc &= ~FFB_PPC_APE_MASK; if (ctx->Polygon.StippleFlag) ppc |= FFB_PPC_APE_ENABLE; else ppc |= FFB_PPC_APE_DISABLE; if (ctx->_TriangleCaps & DD_FLATSHADE) { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_CONST; } else { ppc |= FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR; } drawop = FFB_DRAWOP_TRIANGLE; break; default:#ifdef STATE_TRACE fprintf(stderr, "unknown %d!\n", rprim);#endif return; };#ifdef STATE_TRACE fprintf(stderr, "do_sw(%d) ", do_sw);#endif if (do_sw != 0) { fbc &= ~(FFB_FBC_WB_C); fbc &= ~(FFB_FBC_ZE_MASK | FFB_FBC_RGBE_MASK); fbc |= FFB_FBC_ZE_OFF | FFB_FBC_RGBE_MASK; ppc &= ~(FFB_PPC_XS_MASK | FFB_PPC_ABE_MASK | FFB_PPC_DCE_MASK | FFB_PPC_APE_MASK); ppc |= (FFB_PPC_ZS_VAR | FFB_PPC_CS_VAR | FFB_PPC_XS_WID | FFB_PPC_ABE_DISABLE | FFB_PPC_DCE_DISABLE | FFB_PPC_APE_DISABLE); } else { fbc |= FFB_FBC_WB_C; fbc &= ~(FFB_FBC_RGBE_MASK); fbc |= FFB_FBC_RGBE_MASK; ppc &= ~(FFB_PPC_ABE_MASK | FFB_PPC_XS_MASK); if (ctx->Color.BlendEnabled) { if ((rprim == GL_POINTS && !ctx->Point.SmoothFlag) || (rprim != GL_POINTS && ctx->_TriangleCaps & DD_FLATSHADE)) ppc |= FFB_PPC_ABE_ENABLE | FFB_PPC_XS_CONST; else ppc |= FFB_PPC_ABE_ENABLE | FFB_PPC_XS_VAR; } else { ppc |= FFB_PPC_ABE_DISABLE | FFB_PPC_XS_WID; } }#ifdef STATE_TRACE fprintf(stderr, "fbc(%08x) ppc(%08x)\n", fbc, ppc);#endif FFBFifo(fmesa, 4); if (fmesa->drawop != drawop) fmesa->regs->drawop = fmesa->drawop = drawop; if (fmesa->fbc != fbc) fmesa->regs->fbc = fmesa->fbc = fbc; if (fmesa->ppc != ppc) fmesa->regs->ppc = fmesa->ppc = ppc; if (do_sw != 0) { fmesa->regs->cmp = (fmesa->cmp & ~(0xff<<16)) | (0x80 << 16); } else fmesa->regs->cmp = fmesa->cmp;}static void ffbRenderPrimitive(GLcontext *ctx, GLenum prim){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLuint rprim = reduced_prim[prim]; fmesa->render_primitive = prim; if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; if (fmesa->raster_primitive != rprim) { ffbRasterPrimitive( ctx, rprim ); }}/**********************************************************************//* Transition to/from hardware rasterization. *//**********************************************************************/static char *fallbackStrings[] = { "Fog enabled", "Blend function", "Blend ROP", "Blend equation", "Stencil", "Texture", "LIBGL_SOFTWARE_RENDERING"};static char *getFallbackString(GLuint bit){ int i = 0; while (bit > 1) { i++; bit >>= 1; } return fallbackStrings[i];}void ffbFallback( GLcontext *ctx, GLuint bit, GLboolean mode ){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint oldfallback = fmesa->bad_fragment_attrs; if (mode) { fmesa->bad_fragment_attrs |= bit; if (oldfallback == 0) {/* FFB_FIREVERTICES(fmesa); */ _swsetup_Wakeup( ctx ); if (fmesa->debugFallbacks) fprintf(stderr, "FFB begin software fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } else { fmesa->bad_fragment_attrs &= ~bit; if (oldfallback == bit) { _swrast_flush( ctx ); tnl->Driver.Render.Start = ffbRenderStart; tnl->Driver.Render.PrimitiveNotify = ffbRenderPrimitive; tnl->Driver.Render.Finish = ffbRenderFinish; fmesa->new_gl_state = ~0; /* Just re-choose everything: */ ffbChooseVertexState(ctx); ffbChooseRenderState(ctx); ffbChooseTriangleState(ctx); ffbChooseLineState(ctx); ffbChoosePointState(ctx); if (fmesa->debugFallbacks) fprintf(stderr, "FFB end software fallback: 0x%x %s\n", bit, getFallbackString(bit)); } }}/**********************************************************************//* Initialization. *//**********************************************************************/void ffbDDInitRenderFuncs( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); SWcontext *swrast = SWRAST_CONTEXT(ctx); static int firsttime = 1; if (firsttime) { init_rast_tab(); init_tri_tab(); init_render_tab(); firsttime = 0; } tnl->Driver.RunPipeline = ffbRunPipeline; tnl->Driver.Render.Start = ffbRenderStart; tnl->Driver.Render.Finish = ffbRenderFinish; tnl->Driver.Render.PrimitiveNotify = ffbRenderPrimitive; tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; swrast->Driver.SpanRenderStart = ffbSWRenderStart; swrast->Driver.SpanRenderFinish = ffbSWRenderFinish;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -