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); }
/* Destroy the Mesa and driver specific context data. */ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate; r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL; /* check if we're deleting the currently bound context */ if (rmesa == current) { R200_FIREVERTICES( rmesa ); _mesa_make_current(NULL, NULL, NULL); } /* Free r200 context resources */ assert(rmesa); /* should never be null */ if ( rmesa ) { GLboolean release_texture_heaps; release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); r200DestroySwtcl( rmesa->glCtx ); r200ReleaseArrays( rmesa->glCtx, ~0 ); if (rmesa->dma.current.buf) { r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); r200FlushCmdBuf( rmesa, __FUNCTION__ ); } if (rmesa->state.scissor.pClipRects) { FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = NULL; } if ( release_texture_heaps ) { /* This share group is about to go away, free our private * texture object data. */ int i; for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); rmesa->texture_heaps[ i ] = NULL; } assert( is_empty_list( & rmesa->swapped ) ); } /* free the Mesa context */ rmesa->glCtx->DriverCtx = NULL; _mesa_destroy_context( rmesa->glCtx ); /* free the option cache */ driDestroyOptionCache (&rmesa->optionCache); FREE( rmesa ); } }
/* 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 */ }