diff options
Diffstat (limited to 'src/mesa/tnl/t_pipeline.c')
-rw-r--r-- | src/mesa/tnl/t_pipeline.c | 146 |
1 files changed, 66 insertions, 80 deletions
diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c index 1e9b686789b..914121969c9 100644 --- a/src/mesa/tnl/t_pipeline.c +++ b/src/mesa/tnl/t_pipeline.c @@ -37,33 +37,26 @@ #include "t_context.h" #include "t_pipeline.h" - +#include "t_vp_build.h" void _tnl_install_pipeline( GLcontext *ctx, const struct tnl_pipeline_stage **stages ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_pipeline *pipe = &tnl->pipeline; GLuint i; - ASSERT(pipe->nr_stages == 0); - - pipe->run_state_changes = ~0; - pipe->run_input_changes = ~0; - pipe->build_state_changes = ~0; - pipe->build_state_trigger = 0; - pipe->inputs = 0; + tnl->pipeline.new_state = ~0; /* Create a writeable copy of each stage. */ for (i = 0 ; i < MAX_PIPELINE_STAGES && stages[i] ; i++) { - MEMCPY( &pipe->stages[i], stages[i], sizeof( **stages )); - pipe->build_state_trigger |= pipe->stages[i].check_state; + struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; + MEMCPY(s, stages[i], sizeof(*s)); + if (s->create) + s->create(ctx, s); } - MEMSET( &pipe->stages[i], 0, sizeof( **stages )); - - pipe->nr_stages = i; + tnl->pipeline.nr_stages = i; } void _tnl_destroy_pipeline( GLcontext *ctx ) @@ -71,100 +64,89 @@ void _tnl_destroy_pipeline( GLcontext *ctx ) TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; - for (i = 0 ; i < tnl->pipeline.nr_stages ; i++) - tnl->pipeline.stages[i].destroy( &tnl->pipeline.stages[i] ); + for (i = 0 ; i < tnl->pipeline.nr_stages ; i++) { + struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; + if (s->destroy) + s->destroy(s); + } tnl->pipeline.nr_stages = 0; } -/* TODO: merge validate with run. - */ -void _tnl_validate_pipeline( GLcontext *ctx ) + + +static GLuint check_input_changes( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_pipeline *pipe = &tnl->pipeline; - struct tnl_pipeline_stage *s = pipe->stages; - GLuint newstate = pipe->build_state_changes; - GLuint generated = 0; - GLuint changed_inputs = 0; - - pipe->inputs = 0; - pipe->build_state_changes = 0; - - for ( ; s->check ; s++) { - - s->changed_inputs |= s->inputs & changed_inputs; - - if (s->check_state & newstate) { - if (s->active) { - GLuint old_outputs = s->outputs; - s->check(ctx, s); - if (!s->active) - changed_inputs |= old_outputs; - } - else - s->check(ctx, s); + GLuint i; + + for (i = 0; i < _TNL_ATTRIB_EDGEFLAG; i++) { + if (tnl->vb.AttribPtr[i]->size != tnl->pipeline.last_attrib_size[i] || + tnl->vb.AttribPtr[i]->stride != tnl->pipeline.last_attrib_stride[i]) { + tnl->pipeline.last_attrib_size[i] = tnl->vb.AttribPtr[i]->size; + tnl->pipeline.last_attrib_stride[i] = tnl->vb.AttribPtr[i]->stride; + tnl->pipeline.input_changes |= 1<<i; } + } + + return tnl->pipeline.input_changes; +} + - if (s->active) { - pipe->inputs |= s->inputs & ~generated; - generated |= s->outputs; +static void check_output_changes( GLcontext *ctx ) +{ +#if 0 + TNLcontext *tnl = TNL_CONTEXT(ctx); + + for (i = 0; i < VERT_RESULT_MAX; i++) { + if (tnl->vb.ResultPtr[i]->size != tnl->last_result_size[i] || + tnl->vb.ResultPtr[i]->stride != tnl->last_result_stride[i]) { + tnl->last_result_size[i] = tnl->vb.ResultPtr[i]->size; + tnl->last_result_stride[i] = tnl->vb.ResultPtr[i]->stride; + tnl->pipeline.output_changes |= 1<<i; } } -} + if (tnl->pipeline.output_changes) + tnl->Driver.NotifyOutputChanges( ctx, tnl->pipeline.output_changes ); +#endif +} void _tnl_run_pipeline( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct tnl_pipeline *pipe = &tnl->pipeline; - struct tnl_pipeline_stage *s = pipe->stages; - GLuint changed_state = pipe->run_state_changes; - GLuint changed_inputs = pipe->run_input_changes; - GLboolean running = GL_TRUE; -#ifdef HAVE_FAST_MATH unsigned short __tmp; -#endif + GLuint i; if (!tnl->vb.Count) return; - pipe->run_state_changes = 0; - pipe->run_input_changes = 0; - - /* Done elsewhere. - */ - ASSERT(pipe->build_state_changes == 0); - -#ifdef HAVE_FAST_MATH - START_FAST_MATH(__tmp); -#endif - - /* If something changes in the pipeline, tag all subsequent stages - * using this value for recalculation. Inactive stages have their - * state and inputs examined to try to keep cached data alive over - * state-changes. + /* Check for changed input sizes or change in stride to/from zero + * (ie const or non-const). */ - for ( ; s->run ; s++) { - s->changed_inputs |= s->inputs & changed_inputs; - - if (s->run_state & changed_state) - s->changed_inputs = s->inputs; + if (check_input_changes( ctx ) || tnl->pipeline.new_state) { + for (i = 0; i < tnl->pipeline.nr_stages ; i++) { + struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; + if (s->validate) + s->validate( ctx, s ); + } + + tnl->pipeline.new_state = 0; + tnl->pipeline.input_changes = 0; + check_output_changes( ctx ); + } - if (s->active && running) { - if (s->changed_inputs) - changed_inputs |= s->outputs; - running = s->run( ctx, s ); + START_FAST_MATH(__tmp); - s->changed_inputs = 0; - } + for (i = 0; i < tnl->pipeline.nr_stages ; i++) { + struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i]; + if (!s->run( ctx, s )) + break; } -#ifdef HAVE_FAST_MATH END_FAST_MATH(__tmp); -#endif } @@ -201,6 +183,9 @@ void _tnl_run_pipeline( GLcontext *ctx ) * case, if it becomes necessary to do so. */ const struct tnl_pipeline_stage *_tnl_default_pipeline[] = { +#if TNL_FIXED_FUNCTION_PROGRAM + &_tnl_arb_vertex_program_stage, +#else &_tnl_vertex_transform_stage, &_tnl_normal_transform_stage, &_tnl_lighting_stage, @@ -211,6 +196,7 @@ const struct tnl_pipeline_stage *_tnl_default_pipeline[] = { #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program) &_tnl_vertex_program_stage, #endif +#endif &_tnl_render_stage, NULL }; |