📄 radeon_tcl.c
字号:
#define EXP_FOG_MAX .0006595#define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE)static GLfloat exp_table[FOG_EXP_TABLE_SIZE];#if 1#define NEG_EXP( result, narg ) \do { \ GLfloat f = (GLfloat) (narg * (1.0/FOG_INCR)); \ GLint k = (GLint) f; \ if (k > FOG_EXP_TABLE_SIZE-2) \ result = (GLfloat) EXP_FOG_MAX; \ else \ result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]); \} while (0)#else#define NEG_EXP( result, narg ) \do { \ result = exp(-narg); \} while (0)#endif/** * Initialize the exp_table[] lookup table for approximating exp(). */voidradeonInitStaticFogData( void ){ GLfloat f = 0.0F; GLint i = 0; for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) { exp_table[i] = (GLfloat) exp(-f); }}/** * Compute per-vertex fog blend factors from fog coordinates by * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function. * Fog coordinates are distances from the eye (typically between the * near and far clip plane distances). * Note the fog (eye Z) coords may be negative so we use ABS(z) below. * Fog blend factors are in the range [0,1]. */floatradeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord ){ GLfloat end = ctx->Fog.End; GLfloat d, temp; const GLfloat z = FABSF(fogcoord); switch (ctx->Fog.Mode) { case GL_LINEAR: if (ctx->Fog.Start == ctx->Fog.End) d = 1.0F; else d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); temp = (end - z) * d; return CLAMP(temp, 0.0F, 1.0F); break; case GL_EXP: d = ctx->Fog.Density; NEG_EXP( temp, d * z ); return temp; break; case GL_EXP2: d = ctx->Fog.Density*ctx->Fog.Density; NEG_EXP( temp, d * z * z ); return temp; break; default: _mesa_problem(ctx, "Bad fog mode in make_fog_coord"); return 0; }}/**********************************************************************//* Render pipeline stage *//**********************************************************************//* TCL render. */static GLboolean radeon_run_tcl_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0; GLuint i; /* TODO: separate this from the swtnl pipeline */ if (rmesa->TclFallback) return GL_TRUE; /* fallback to software t&l */ if (VB->Count == 0) return GL_FALSE; /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ if (ctx->Light.Enabled) { inputs |= VERT_BIT_NORMAL; } if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { inputs |= VERT_BIT_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { inputs |= VERT_BIT_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { /* TODO: probably should not emit texture coords when texgen is enabled */ if (rmesa->TexGenNeedNormals[i]) { inputs |= VERT_BIT_NORMAL; } inputs |= VERT_BIT_TEX(i); } } radeonReleaseArrays( ctx, ~0 ); radeonEmitArrays( ctx, inputs ); rmesa->tcl.Elts = VB->Elts; for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; if (!length) continue; if (rmesa->tcl.Elts) radeonEmitEltPrimitive( ctx, start, start+length, prim ); else radeonEmitPrimitive( ctx, start, start+length, prim ); } return GL_FALSE; /* finished the pipe */}/* Initial state for tcl stage. */const struct tnl_pipeline_stage _radeon_tcl_stage ={ "radeon render", NULL, NULL, NULL, NULL, radeon_run_tcl_render /* run */};/**********************************************************************//* Validate state at pipeline start *//**********************************************************************//*----------------------------------------------------------------------- * Manage TCL fallbacks */static void transition_to_swtnl( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint se_cntl; RADEON_NEWPRIM( rmesa ); rmesa->swtcl.vertex_format = 0; radeonChooseVertexState( ctx ); radeonChooseRenderState( ctx ); _mesa_validate_all_lighting_tables( ctx ); tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; radeonReleaseArrays( ctx, ~0 ); se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL]; se_cntl |= RADEON_FLAT_SHADE_VTX_LAST; if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) { RADEON_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl; }}static void transition_to_hwtnl( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; se_coord_fmt &= ~(RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | RADEON_VTX_W0_IS_NOT_1_OVER_W0); se_coord_fmt |= RADEON_VTX_W0_IS_NOT_1_OVER_W0; if ( se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT] ) { RADEON_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt; _tnl_need_projected_coords( ctx, GL_FALSE ); } radeonUpdateMaterial( ctx ); tnl->Driver.NotifyMaterialChange = radeonUpdateMaterial; if ( rmesa->dma.flush ) rmesa->dma.flush( rmesa ); rmesa->dma.flush = NULL; rmesa->swtcl.vertex_format = 0; if (rmesa->swtcl.indexed_verts.buf) radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ); if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "Radeon end tcl fallback\n");}static char *fallbackStrings[] = { "Rasterization fallback", "Unfilled triangles", "Twosided lighting, differing materials", "Materials in VB (maybe between begin/end)", "Texgen unit 0", "Texgen unit 1", "Texgen unit 2", "User disable", "Fogcoord with separate specular lighting"};static char *getFallbackString(GLuint bit){ int i = 0; while (bit > 1) { i++; bit >>= 1; } return fallbackStrings[i];}void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint oldfallback = rmesa->TclFallback; if (mode) { rmesa->TclFallback |= bit; if (oldfallback == 0) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "Radeon begin tcl fallback %s\n", getFallbackString( bit )); transition_to_swtnl( ctx ); } } else { rmesa->TclFallback &= ~bit; if (oldfallback == bit) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "Radeon end tcl fallback %s\n", getFallbackString( bit )); transition_to_hwtnl( ctx ); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -