2000-11-27 09:05:52 +00:00
|
|
|
/* $Id: t_pipeline.c,v 1.6 2000/11/27 09:05:52 joukj Exp $ */
|
2000-11-16 21:05:34 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Mesa 3-D graphics library
|
|
|
|
* Version: 3.5
|
2000-11-22 07:32:16 +00:00
|
|
|
*
|
2000-11-16 21:05:34 +00:00
|
|
|
* Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
|
2000-11-22 07:32:16 +00:00
|
|
|
*
|
2000-11-16 21:05:34 +00:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
2000-11-22 07:32:16 +00:00
|
|
|
*
|
2000-11-16 21:05:34 +00:00
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
2000-11-22 07:32:16 +00:00
|
|
|
*
|
2000-11-16 21:05:34 +00:00
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Dynamic pipelines, support for CVA.
|
|
|
|
* Copyright (C) 1999 Keith Whitwell.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "glheader.h"
|
|
|
|
#include "context.h"
|
|
|
|
#include "mem.h"
|
|
|
|
#include "mmath.h"
|
|
|
|
#include "state.h"
|
2000-11-22 07:32:16 +00:00
|
|
|
#include "mtypes.h"
|
2000-11-16 21:05:34 +00:00
|
|
|
|
|
|
|
#include "math/m_translate.h"
|
|
|
|
#include "math/m_xform.h"
|
|
|
|
|
|
|
|
#include "t_bbox.h"
|
|
|
|
#include "t_clip.h"
|
|
|
|
#include "t_cva.h"
|
2000-11-24 10:25:05 +00:00
|
|
|
#include "t_debug.h"
|
2000-11-16 21:05:34 +00:00
|
|
|
#include "t_fog.h"
|
|
|
|
#include "t_light.h"
|
|
|
|
#include "t_pipeline.h"
|
|
|
|
#include "t_shade.h"
|
|
|
|
#include "t_stages.h"
|
|
|
|
#include "t_vbcull.h"
|
|
|
|
#include "t_vbindirect.h"
|
|
|
|
#include "t_vbrender.h"
|
|
|
|
#include "t_vbxform.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
void _tnl_print_pipe_ops( const char *msg, GLuint flags )
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
2000-11-22 07:32:16 +00:00
|
|
|
fprintf(stderr,
|
2000-11-27 09:05:52 +00:00
|
|
|
"%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
|
2000-11-16 21:05:34 +00:00
|
|
|
msg,
|
|
|
|
flags,
|
|
|
|
(flags & PIPE_OP_CVA_PREPARE) ? "cva-prepare, " : "",
|
|
|
|
(flags & PIPE_OP_VERT_XFORM) ? "vert-xform, " : "",
|
|
|
|
(flags & PIPE_OP_NORM_XFORM) ? "norm-xform, " : "",
|
|
|
|
(flags & PIPE_OP_LIGHT) ? "light, " : "",
|
|
|
|
(flags & PIPE_OP_FOG) ? "fog, " : "",
|
2000-11-24 15:21:59 +00:00
|
|
|
(flags & PIPE_OP_TEX) ? "tex-gen/tex-mat, " : "",
|
2000-11-16 21:05:34 +00:00
|
|
|
(flags & PIPE_OP_RAST_SETUP_0) ? "rast-0, " : "",
|
|
|
|
(flags & PIPE_OP_RAST_SETUP_1) ? "rast-1, " : "",
|
|
|
|
(flags & PIPE_OP_RENDER) ? "render, " : "");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Have to reset only those parts of the vb which are being recalculated.
|
|
|
|
*/
|
2000-11-24 10:25:05 +00:00
|
|
|
void _tnl_reset_cva_vb( struct vertex_buffer *VB, GLuint stages )
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
GLcontext *ctx = VB->ctx;
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
|
|
|
|
|
|
if (MESA_VERBOSE&VERBOSE_PIPELINE)
|
2000-11-24 10:25:05 +00:00
|
|
|
_tnl_print_pipe_ops( "reset cva vb", stages );
|
2000-11-16 21:05:34 +00:00
|
|
|
|
2000-11-22 07:32:16 +00:00
|
|
|
if (stages & PIPE_OP_VERT_XFORM)
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
if (VB->ClipOrMask & CLIP_USER_BIT)
|
|
|
|
MEMSET(VB->UserClipMask, 0, VB->Count);
|
|
|
|
|
|
|
|
VB->ClipOrMask = 0;
|
|
|
|
VB->ClipAndMask = CLIP_ALL_BITS;
|
|
|
|
VB->CullMode = 0;
|
|
|
|
VB->CullFlag[0] = VB->CullFlag[1] = 0;
|
|
|
|
VB->Culled = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stages & PIPE_OP_NORM_XFORM) {
|
|
|
|
VB->NormalPtr = &tnl->CVA.v.Normal;
|
|
|
|
}
|
|
|
|
|
2000-11-22 07:32:16 +00:00
|
|
|
if (stages & PIPE_OP_LIGHT)
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
VB->ColorPtr = VB->Color[0] = VB->Color[1] = &tnl->CVA.v.Color;
|
|
|
|
VB->IndexPtr = VB->Index[0] = VB->Index[1] = &tnl->CVA.v.Index;
|
|
|
|
}
|
2000-11-22 07:32:16 +00:00
|
|
|
else if (stages & PIPE_OP_FOG)
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
if (ctx->Light.Enabled) {
|
|
|
|
VB->Color[0] = VB->LitColor[0];
|
2000-11-22 07:32:16 +00:00
|
|
|
VB->Color[1] = VB->LitColor[1];
|
2000-11-16 21:05:34 +00:00
|
|
|
VB->Index[0] = VB->LitIndex[0];
|
2000-11-22 07:32:16 +00:00
|
|
|
VB->Index[1] = VB->LitIndex[1];
|
2000-11-16 21:05:34 +00:00
|
|
|
} else {
|
|
|
|
VB->Color[0] = VB->Color[1] = &tnl->CVA.v.Color;
|
|
|
|
VB->Index[0] = VB->Index[1] = &tnl->CVA.v.Index;
|
|
|
|
}
|
|
|
|
VB->ColorPtr = VB->Color[0];
|
|
|
|
VB->IndexPtr = VB->Index[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void pipeline_ctr( struct gl_pipeline *p, GLcontext *ctx, GLuint type )
|
|
|
|
{
|
|
|
|
GLuint i;
|
|
|
|
(void) ctx;
|
|
|
|
|
|
|
|
p->state_change = 0;
|
|
|
|
p->cva_state_change = 0;
|
|
|
|
p->inputs = 0;
|
|
|
|
p->outputs = 0;
|
|
|
|
p->type = type;
|
|
|
|
p->ops = 0;
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
for (i = 0 ; i < _tnl_default_nr_stages ; i++)
|
|
|
|
p->state_change |= _tnl_default_pipeline[i].state_change;
|
2000-11-16 21:05:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void _tnl_pipeline_init( GLcontext *ctx )
|
|
|
|
{
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
MEMCPY( tnl->PipelineStage,
|
|
|
|
_tnl_default_pipeline,
|
|
|
|
sizeof(*_tnl_default_pipeline) * _tnl_default_nr_stages );
|
|
|
|
|
|
|
|
tnl->NrPipelineStages = _tnl_default_nr_stages;
|
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
pipeline_ctr( &tnl->CVA.elt, ctx, PIPE_IMMEDIATE);
|
|
|
|
pipeline_ctr( &tnl->CVA.pre, ctx, PIPE_PRECALC );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-11-24 15:21:59 +00:00
|
|
|
#define MINIMAL_VERT_DATA (VERT_DATA & ~VERT_EVAL_ANY)
|
2000-11-16 21:05:34 +00:00
|
|
|
|
2000-11-24 15:21:59 +00:00
|
|
|
#define VERT_CURRENT_DATA (VERT_TEX_ANY | \
|
2000-11-16 21:05:34 +00:00
|
|
|
VERT_RGBA | \
|
|
|
|
VERT_SPEC_RGB | \
|
|
|
|
VERT_FOG_COORD | \
|
|
|
|
VERT_INDEX | \
|
|
|
|
VERT_EDGE | \
|
|
|
|
VERT_NORM | \
|
|
|
|
VERT_MATERIAL)
|
|
|
|
|
|
|
|
/* Called prior to every recomputation of the CVA precalc data, except where
|
|
|
|
* the driver is able to calculate the pipeline unassisted.
|
|
|
|
*/
|
|
|
|
static void build_full_precalc_pipeline( GLcontext *ctx )
|
|
|
|
{
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
|
|
struct gl_pipeline_stage *pipeline = tnl->PipelineStage;
|
|
|
|
struct gl_cva *cva = &tnl->CVA;
|
2000-11-22 07:32:16 +00:00
|
|
|
struct gl_pipeline *pre = &cva->pre;
|
2000-11-16 21:05:34 +00:00
|
|
|
struct gl_pipeline_stage **stages = pre->stages;
|
|
|
|
GLuint i;
|
|
|
|
GLuint newstate = pre->new_state;
|
|
|
|
GLuint changed_ops = 0;
|
|
|
|
GLuint oldoutputs = pre->outputs;
|
|
|
|
GLuint oldinputs = pre->inputs;
|
2000-11-24 15:21:59 +00:00
|
|
|
GLuint fallback = (VERT_CURRENT_DATA &
|
2000-11-16 21:05:34 +00:00
|
|
|
~tnl->_ArraySummary);
|
2000-11-22 07:32:16 +00:00
|
|
|
GLuint changed_outputs = (tnl->_ArrayNewState |
|
2000-11-16 21:05:34 +00:00
|
|
|
(fallback & cva->orflag));
|
|
|
|
GLuint available = fallback | tnl->_ArrayFlags;
|
|
|
|
|
|
|
|
pre->cva_state_change = 0;
|
|
|
|
pre->ops = 0;
|
|
|
|
pre->outputs = 0;
|
|
|
|
pre->inputs = 0;
|
|
|
|
pre->forbidden_inputs = 0;
|
|
|
|
pre->fallback = 0;
|
|
|
|
|
|
|
|
/* KW: Disable data reuse during Mesa reorg. Make this more readable...
|
|
|
|
*/
|
|
|
|
newstate = ~0;
|
|
|
|
|
2000-11-22 07:32:16 +00:00
|
|
|
if (tnl->_ArraySummary & VERT_ELT)
|
2000-11-16 21:05:34 +00:00
|
|
|
cva->orflag &= VERT_MATERIAL;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
cva->orflag &= ~(tnl->_ArraySummary & ~VERT_OBJ_ANY);
|
|
|
|
available &= ~cva->orflag;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
pre->outputs = available;
|
|
|
|
pre->inputs = available;
|
|
|
|
|
|
|
|
if (MESA_VERBOSE & VERBOSE_PIPELINE) {
|
|
|
|
fprintf(stderr, ": Rebuild pipeline\n");
|
2000-11-24 10:25:05 +00:00
|
|
|
_tnl_print_vert_flags("orflag", cva->orflag);
|
2000-11-16 21:05:34 +00:00
|
|
|
}
|
2000-11-22 07:32:16 +00:00
|
|
|
|
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
|
|
|
|
/* If something changes in the pipeline, tag all subsequent stages
|
|
|
|
* using this value for recalcuation. Also used to build the full
|
|
|
|
* pipeline by setting newstate and newinputs to ~0.
|
|
|
|
*
|
|
|
|
* Because all intermediate values are buffered, the new inputs
|
|
|
|
* are enough to fully specify what needs to be calculated, and a
|
|
|
|
* single pass identifies all stages requiring recalculation.
|
|
|
|
*/
|
2000-11-22 07:32:16 +00:00
|
|
|
for (i = 0 ; i < tnl->NrPipelineStages ; i++)
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
pipeline[i].check(ctx, &pipeline[i]);
|
|
|
|
|
2000-11-22 07:32:16 +00:00
|
|
|
if (pipeline[i].type & PIPE_PRECALC)
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
if ((newstate & pipeline[i].cva_state_change) ||
|
|
|
|
(changed_outputs & pipeline[i].inputs) ||
|
|
|
|
!pipeline[i].inputs)
|
2000-11-22 07:32:16 +00:00
|
|
|
{
|
2000-11-16 21:05:34 +00:00
|
|
|
changed_ops |= pipeline[i].ops;
|
|
|
|
changed_outputs |= pipeline[i].outputs;
|
|
|
|
pipeline[i].active &= ~PIPE_PRECALC;
|
|
|
|
|
|
|
|
if ((pipeline[i].inputs & ~available) == 0 &&
|
|
|
|
(pipeline[i].ops & pre->ops) == 0)
|
|
|
|
{
|
|
|
|
pipeline[i].active |= PIPE_PRECALC;
|
|
|
|
*stages++ = &pipeline[i];
|
2000-11-22 07:32:16 +00:00
|
|
|
}
|
2000-11-16 21:05:34 +00:00
|
|
|
}
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
/* Incompatible with multiple stages structs implementing
|
|
|
|
* the same stage.
|
|
|
|
*/
|
|
|
|
available &= ~pipeline[i].outputs;
|
|
|
|
pre->outputs &= ~pipeline[i].outputs;
|
|
|
|
|
|
|
|
if (pipeline[i].active & PIPE_PRECALC) {
|
|
|
|
pre->ops |= pipeline[i].ops;
|
|
|
|
pre->outputs |= pipeline[i].outputs;
|
|
|
|
available |= pipeline[i].outputs;
|
|
|
|
pre->forbidden_inputs |= pipeline[i].pre_forbidden_inputs;
|
|
|
|
}
|
2000-11-22 07:32:16 +00:00
|
|
|
}
|
|
|
|
else if (pipeline[i].active & PIPE_PRECALC)
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
pipeline[i].active &= ~PIPE_PRECALC;
|
|
|
|
changed_outputs |= pipeline[i].outputs;
|
|
|
|
changed_ops |= pipeline[i].ops;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*stages = 0;
|
|
|
|
|
|
|
|
pre->new_outputs = pre->outputs & (changed_outputs | ~oldoutputs);
|
|
|
|
pre->new_inputs = pre->inputs & ~oldinputs;
|
|
|
|
pre->fallback = pre->inputs & fallback;
|
|
|
|
pre->forbidden_inputs |= pre->inputs & fallback;
|
|
|
|
|
|
|
|
pre->changed_ops = changed_ops;
|
|
|
|
}
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
void _tnl_build_precalc_pipeline( GLcontext *ctx )
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
2000-11-22 07:32:16 +00:00
|
|
|
struct gl_pipeline *pre = &tnl->CVA.pre;
|
|
|
|
struct gl_pipeline *elt = &tnl->CVA.elt;
|
2000-11-16 21:05:34 +00:00
|
|
|
|
|
|
|
if (!ctx->Driver.BuildPrecalcPipeline ||
|
|
|
|
!ctx->Driver.BuildPrecalcPipeline( ctx ))
|
|
|
|
build_full_precalc_pipeline( ctx );
|
|
|
|
|
|
|
|
pre->data_valid = 0;
|
|
|
|
pre->pipeline_valid = 1;
|
|
|
|
elt->pipeline_valid = 0;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
tnl->CVA.orflag = 0;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
if (MESA_VERBOSE&VERBOSE_PIPELINE)
|
2000-11-24 10:25:05 +00:00
|
|
|
_tnl_print_pipeline( ctx, pre );
|
2000-11-16 21:05:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void build_full_immediate_pipeline( GLcontext *ctx )
|
|
|
|
{
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
|
|
struct gl_pipeline_stage *pipeline = tnl->PipelineStage;
|
|
|
|
struct gl_cva *cva = &tnl->CVA;
|
2000-11-22 07:32:16 +00:00
|
|
|
struct gl_pipeline *pre = &cva->pre;
|
2000-11-16 21:05:34 +00:00
|
|
|
struct gl_pipeline *elt = &cva->elt;
|
|
|
|
struct gl_pipeline_stage **stages = elt->stages;
|
|
|
|
GLuint i;
|
|
|
|
GLuint newstate = elt->new_state;
|
|
|
|
GLuint active_ops = 0;
|
|
|
|
GLuint available = cva->orflag | MINIMAL_VERT_DATA;
|
|
|
|
GLuint generated = 0;
|
|
|
|
GLuint is_elt = 0;
|
|
|
|
|
|
|
|
if (pre->data_valid && tnl->CompileCVAFlag) {
|
|
|
|
is_elt = 1;
|
|
|
|
active_ops = cva->pre.ops;
|
|
|
|
available |= pre->outputs | VERT_PRECALC_DATA;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
elt->outputs = 0; /* not used */
|
|
|
|
elt->inputs = 0;
|
|
|
|
|
|
|
|
for (i = 0 ; i < tnl->NrPipelineStages ; i++) {
|
|
|
|
pipeline[i].active &= ~PIPE_IMMEDIATE;
|
|
|
|
|
|
|
|
if ((pipeline[i].state_change & newstate) ||
|
2000-11-22 07:32:16 +00:00
|
|
|
(pipeline[i].elt_forbidden_inputs & available))
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
pipeline[i].check(ctx, &pipeline[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((pipeline[i].type & PIPE_IMMEDIATE) &&
|
2000-11-22 07:32:16 +00:00
|
|
|
(pipeline[i].ops & active_ops) == 0 &&
|
2000-11-16 21:05:34 +00:00
|
|
|
(pipeline[i].elt_forbidden_inputs & available) == 0
|
|
|
|
)
|
|
|
|
{
|
2000-11-22 07:32:16 +00:00
|
|
|
if (pipeline[i].inputs & ~available)
|
2000-11-16 21:05:34 +00:00
|
|
|
elt->forbidden_inputs |= pipeline[i].inputs & ~available;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
elt->inputs |= pipeline[i].inputs & ~generated;
|
|
|
|
elt->forbidden_inputs |= pipeline[i].elt_forbidden_inputs;
|
|
|
|
pipeline[i].active |= PIPE_IMMEDIATE;
|
|
|
|
*stages++ = &pipeline[i];
|
|
|
|
generated |= pipeline[i].outputs;
|
|
|
|
available |= pipeline[i].outputs;
|
|
|
|
active_ops |= pipeline[i].ops;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*stages = 0;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
elt->copy_transformed_data = 1;
|
|
|
|
elt->replay_copied_vertices = 0;
|
|
|
|
|
|
|
|
if (is_elt) {
|
|
|
|
cva->merge = elt->inputs & pre->outputs;
|
|
|
|
elt->ops = active_ops & ~pre->ops;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
void _tnl_build_immediate_pipeline( GLcontext *ctx )
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
2000-11-22 07:32:16 +00:00
|
|
|
struct gl_pipeline *elt = &tnl->CVA.elt;
|
2000-11-16 21:05:34 +00:00
|
|
|
|
|
|
|
if (!ctx->Driver.BuildEltPipeline ||
|
|
|
|
!ctx->Driver.BuildEltPipeline( ctx )) {
|
|
|
|
build_full_immediate_pipeline( ctx );
|
|
|
|
}
|
|
|
|
|
|
|
|
elt->pipeline_valid = 1;
|
|
|
|
tnl->CVA.orflag = 0;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
if (MESA_VERBOSE&VERBOSE_PIPELINE)
|
2000-11-24 10:25:05 +00:00
|
|
|
_tnl_print_pipeline( ctx, elt );
|
2000-11-16 21:05:34 +00:00
|
|
|
}
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
#define INTERESTED ~0
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
void _tnl_update_pipelines( GLcontext *ctx )
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
|
|
|
GLuint newstate = ctx->NewState;
|
|
|
|
struct gl_cva *cva = &tnl->CVA;
|
|
|
|
|
|
|
|
newstate &= INTERESTED;
|
|
|
|
|
|
|
|
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_STATE))
|
|
|
|
gl_print_enable_flags("enabled", ctx->_Enabled);
|
|
|
|
|
|
|
|
if (newstate ||
|
|
|
|
cva->lock_changed ||
|
|
|
|
cva->orflag != cva->last_orflag ||
|
|
|
|
tnl->_ArrayFlags != cva->last_array_flags)
|
2000-11-22 07:32:16 +00:00
|
|
|
{
|
2000-11-24 15:21:59 +00:00
|
|
|
GLuint j;
|
2000-11-16 21:05:34 +00:00
|
|
|
GLuint flags = VERT_WIN;
|
|
|
|
|
|
|
|
if (ctx->Visual.RGBAflag) {
|
|
|
|
flags |= VERT_RGBA;
|
|
|
|
if (ctx->_TriangleCaps && DD_SEPERATE_SPECULAR)
|
|
|
|
flags |= VERT_SPEC_RGB;
|
2000-11-22 07:32:16 +00:00
|
|
|
} else
|
2000-11-16 21:05:34 +00:00
|
|
|
flags |= VERT_INDEX;
|
|
|
|
|
2000-11-24 15:21:59 +00:00
|
|
|
for (j = 0 ; j < ctx->Const.MaxTextureUnits ; j++) {
|
|
|
|
if (ctx->Texture.Unit[j]._ReallyEnabled)
|
|
|
|
flags |= VERT_TEX(j);
|
|
|
|
}
|
2000-11-22 07:32:16 +00:00
|
|
|
|
|
|
|
if (ctx->Polygon._Unfilled)
|
2000-11-16 21:05:34 +00:00
|
|
|
flags |= VERT_EDGE;
|
2000-11-22 07:32:16 +00:00
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
|
|
|
|
flags |= VERT_FOG_COORD;
|
|
|
|
|
|
|
|
if (ctx->RenderMode==GL_FEEDBACK) {
|
2000-11-24 15:21:59 +00:00
|
|
|
flags = (VERT_WIN | VERT_RGBA | VERT_INDEX | VERT_NORM |
|
|
|
|
VERT_EDGE | VERT_TEX_ANY);
|
2000-11-16 21:05:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tnl->_RenderFlags = flags;
|
|
|
|
|
|
|
|
cva->elt.new_state |= newstate;
|
|
|
|
cva->elt.pipeline_valid = 0;
|
|
|
|
|
|
|
|
cva->pre.new_state |= newstate;
|
|
|
|
cva->pre.forbidden_inputs = 0;
|
|
|
|
cva->pre.pipeline_valid = 0;
|
|
|
|
cva->lock_changed = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tnl->_ArrayNewState != cva->last_array_new_state)
|
|
|
|
cva->pre.pipeline_valid = 0;
|
|
|
|
|
|
|
|
cva->pre.data_valid = 0;
|
|
|
|
cva->last_array_new_state = tnl->_ArrayNewState;
|
|
|
|
cva->last_orflag = cva->orflag;
|
|
|
|
cva->last_array_flags = tnl->_ArrayFlags;
|
|
|
|
}
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
void _tnl_run_pipeline( struct vertex_buffer *VB )
|
2000-11-16 21:05:34 +00:00
|
|
|
{
|
|
|
|
struct gl_pipeline *pipe = VB->pipeline;
|
|
|
|
struct gl_pipeline_stage **stages = pipe->stages;
|
|
|
|
unsigned short x;
|
|
|
|
|
|
|
|
pipe->data_valid = 1; /* optimized stages might want to reset this. */
|
|
|
|
|
2000-11-24 10:25:05 +00:00
|
|
|
if (0) _tnl_print_pipeline( VB->ctx, pipe );
|
|
|
|
|
2000-11-16 21:05:34 +00:00
|
|
|
START_FAST_MATH(x);
|
2000-11-22 07:32:16 +00:00
|
|
|
|
|
|
|
for ( VB->Culled = 0; *stages && !VB->Culled ; stages++ )
|
2000-11-16 21:05:34 +00:00
|
|
|
(*stages)->run( VB );
|
|
|
|
|
|
|
|
END_FAST_MATH(x);
|
|
|
|
|
|
|
|
pipe->new_state = 0;
|
|
|
|
}
|
|
|
|
|