📄 r200_tcl.c
字号:
}/** * 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]. */floatr200ComputeFogBlendFactor( 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 r200_run_tcl_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint i; GLubyte *vimap_rev;/* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3, color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use more than 12 of those at the same time. */ GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; /* TODO: separate this from the swtnl pipeline */ if (rmesa->TclFallback) return GL_TRUE; /* fallback to software t&l */ if (R200_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__); if (VB->Count == 0) return GL_FALSE; /* Validate state: */ if (rmesa->NewGLState) r200ValidateState( ctx ); if (!ctx->VertexProgram._Enabled) { /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ map_rev_fixed[0] = VERT_ATTRIB_POS; /* technically there is no reason we always need VA_COLOR0. In theory could disable it depending on lighting, color materials, texturing... */ map_rev_fixed[4] = VERT_ATTRIB_COLOR0; if (ctx->Light.Enabled) { map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } /* this also enables VA_COLOR1 when using separate specular lighting model, which is unnecessary. FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses the secondary color (if lighting is disabled). The chip seems misconfigured for that though elsewhere (tcl output, might lock up) */ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { map_rev_fixed[5] = VERT_ATTRIB_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { map_rev_fixed[3] = VERT_ATTRIB_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i; } } vimap_rev = &map_rev_fixed[0]; } else { /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment part", since using some vertex interpolator later which is not in out_vtxfmt0/1 will lock up. It seems to be ok to write in vertex prog to a not enabled output however, so just don't mess with it. We only need to change compsel. */ GLuint out_compsel = 0; GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten; vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0]; assert(vp_out & (1 << VERT_RESULT_HPOS)); out_compsel = R200_OUTPUT_XYZW; if (vp_out & (1 << VERT_RESULT_COL0)) { out_compsel |= R200_OUTPUT_COLOR_0; } if (vp_out & (1 << VERT_RESULT_COL1)) { out_compsel |= R200_OUTPUT_COLOR_1; } if (vp_out & (1 << VERT_RESULT_FOGC)) { out_compsel |= R200_OUTPUT_DISCRETE_FOG; } if (vp_out & (1 << VERT_RESULT_PSIZ)) { out_compsel |= R200_OUTPUT_PT_SIZE; } for (i = VERT_RESULT_TEX0; i < VERT_RESULT_TEX6; i++) { if (vp_out & (1 << i)) { out_compsel |= R200_OUTPUT_TEX_0 << (i - VERT_RESULT_TEX0); } } if (rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] != out_compsel) { R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = out_compsel; } } /* Do the actual work: */ r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); r200EmitArrays( ctx, vimap_rev ); 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) r200EmitEltPrimitive( ctx, start, start+length, prim ); else r200EmitPrimitive( ctx, start, start+length, prim ); } return GL_FALSE; /* finished the pipe */}/* Initial state for tcl stage. */const struct tnl_pipeline_stage _r200_tcl_stage ={ "r200 render", NULL, /* private */ NULL, NULL, NULL, r200_run_tcl_render /* run */};/**********************************************************************//* Validate state at pipeline start *//**********************************************************************//*----------------------------------------------------------------------- * Manage TCL fallbacks */static void transition_to_swtnl( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); R200_NEWPRIM( rmesa ); r200ChooseVertexState( ctx ); r200ChooseRenderState( ctx ); _mesa_validate_all_lighting_tables( ctx ); tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; r200ReleaseArrays( ctx, ~0 ); /* Still using the D3D based hardware-rasterizer from the radeon; * need to put the card into D3D mode to make it work: */ R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_TCL_ENABLE|R200_VAP_PROG_VTX_SHADER_ENABLE);}static void transition_to_hwtnl( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); _tnl_need_projected_coords( ctx, GL_FALSE ); r200UpdateMaterial( ctx ); tnl->Driver.NotifyMaterialChange = r200UpdateMaterial; if ( rmesa->dma.flush ) rmesa->dma.flush( rmesa ); rmesa->dma.flush = NULL; if (rmesa->swtcl.indexed_verts.buf) r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, __FUNCTION__ ); R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE; if (ctx->VertexProgram._Enabled) { rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE; } if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK) == R200_FOG_USE_SPEC_ALPHA) && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) { R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK; rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG; } R200_STATECHANGE( rmesa, vte ); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT; if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "R200 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", "Texgen unit 3", "Texgen unit 4", "Texgen unit 5", "User disable", "Bitmap as points", "Vertex program"};static char *getFallbackString(GLuint bit){ int i = 0; while (bit > 1) { i++; bit >>= 1; } return fallbackStrings[i];}void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint oldfallback = rmesa->TclFallback; if (mode) { rmesa->TclFallback |= bit; if (oldfallback == 0) { if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "R200 begin tcl fallback %s\n", getFallbackString( bit )); transition_to_swtnl( ctx ); } } else { rmesa->TclFallback &= ~bit; if (oldfallback == bit) { if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "R200 end tcl fallback %s\n", getFallbackString( bit )); transition_to_hwtnl( ctx ); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -