Simplify the pipeline_stage structure
- remove input/output fields, input tracking removed. - remove state fields, the validate function now called on every statechange. - add an explicit 'create' function. Add in code to build vertex program to implement current t&l state. Still disabled, but turn on with a #define in t_vp_build.h.
This commit is contained in:
parent
6a13c7da4c
commit
6f973f3367
|
@ -2649,6 +2649,9 @@ struct __GLcontextRec
|
|||
struct gl_fragment_program_state FragmentProgram; /**< GL_NV_fragment_program */
|
||||
struct gl_ati_fragment_shader_state ATIFragmentShader; /**< GL_ATI_fragment_shader */
|
||||
|
||||
struct fragment_program _TexEnvProgram; /**< Texture state as fragment program */
|
||||
struct vertex_program _TnlProgram; /**< Fixed func TNL state as vertex program */
|
||||
|
||||
struct gl_occlusion_state Occlusion; /**< GL_ARB_occlusion_query */
|
||||
|
||||
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
|
||||
|
|
|
@ -118,16 +118,18 @@ TNL_SOURCES = \
|
|||
tnl/t_save_api.c \
|
||||
tnl/t_save_loopback.c \
|
||||
tnl/t_save_playback.c \
|
||||
tnl/t_vb_cull.c \
|
||||
tnl/t_vb_fog.c \
|
||||
tnl/t_vb_light.c \
|
||||
tnl/t_vb_normals.c \
|
||||
tnl/t_vb_points.c \
|
||||
tnl/t_vb_arbprogram.c \
|
||||
tnl/t_vb_program.c \
|
||||
tnl/t_vb_render.c \
|
||||
tnl/t_vb_texgen.c \
|
||||
tnl/t_vb_texmat.c \
|
||||
tnl/t_vb_vertex.c \
|
||||
tnl/t_vb_cull.c \
|
||||
tnl/t_vb_fog.c \
|
||||
tnl/t_vb_light.c \
|
||||
tnl/t_vb_normals.c \
|
||||
tnl/t_vb_points.c \
|
||||
tnl/t_vp_build.c \
|
||||
tnl/t_vertex.c \
|
||||
tnl/t_vertex_c.c \
|
||||
tnl/t_vertex_codegen.c \
|
||||
|
@ -137,6 +139,8 @@ TNL_SOURCES = \
|
|||
tnl/t_vtx_eval.c \
|
||||
tnl/t_vtx_exec.c
|
||||
|
||||
|
||||
|
||||
SHADER_SOURCES = \
|
||||
shader/arbfragparse.c \
|
||||
shader/arbprogparse.c \
|
||||
|
|
|
@ -91,9 +91,6 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
|
|||
struct tnl_prim prim;
|
||||
FLUSH_CURRENT( ctx, 0 );
|
||||
|
||||
if (tnl->pipeline.build_state_changes)
|
||||
_tnl_validate_pipeline( ctx );
|
||||
|
||||
_tnl_vb_bind_arrays( ctx, 0, max_index );
|
||||
|
||||
tnl->vb.Primitive = &prim;
|
||||
|
@ -104,20 +101,7 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
|
|||
|
||||
tnl->vb.Elts = (GLuint *)indices;
|
||||
|
||||
if (ctx->Array.LockCount)
|
||||
tnl->Driver.RunPipeline( ctx );
|
||||
else {
|
||||
/* The lower 16 bits represent the conventional arrays while the
|
||||
* upper 16 bits represent the generic arrays. OR those bits
|
||||
* together to indicate which vertex attribs are in effect.
|
||||
*/
|
||||
GLuint enabledArrays = ctx->Array._Enabled | (ctx->Array._Enabled >> 16);
|
||||
/* Note that arrays may have changed before/after execution.
|
||||
*/
|
||||
tnl->pipeline.run_input_changes |= enabledArrays & 0xffff;
|
||||
tnl->Driver.RunPipeline( ctx );
|
||||
tnl->pipeline.run_input_changes |= enabledArrays & 0xffff;
|
||||
}
|
||||
tnl->Driver.RunPipeline( ctx );
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,7 +115,6 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
|||
GET_CURRENT_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
GLuint thresh = (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) ? 30 : 10;
|
||||
GLuint enabledArrays;
|
||||
|
||||
if (MESA_VERBOSE & VERBOSE_API)
|
||||
_mesa_debug(NULL, "_tnl_DrawArrays %d %d\n", start, count);
|
||||
|
@ -141,9 +124,6 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
|||
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
|
||||
return;
|
||||
|
||||
if (tnl->pipeline.build_state_changes)
|
||||
_tnl_validate_pipeline( ctx );
|
||||
|
||||
assert(!ctx->CompileFlag);
|
||||
|
||||
if (!ctx->Array.LockCount && (GLuint) count < thresh) {
|
||||
|
@ -266,16 +246,7 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
|||
tnl->vb.Primitive[0].count = nr + minimum;
|
||||
tnl->vb.PrimitiveCount = 1;
|
||||
|
||||
/* The lower 16 bits represent the conventional arrays while the
|
||||
* upper 16 bits represent the generic arrays. OR those bits
|
||||
* together to indicate which vertex attribs are in effect.
|
||||
*/
|
||||
enabledArrays = ctx->Array._Enabled | (ctx->Array._Enabled >> 16);
|
||||
/* Note that arrays may have changed before/after execution.
|
||||
*/
|
||||
tnl->pipeline.run_input_changes |= enabledArrays;
|
||||
tnl->Driver.RunPipeline( ctx );
|
||||
tnl->pipeline.run_input_changes |= enabledArrays;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,7 +244,6 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
|
|||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint inputs = tnl->pipeline.inputs;
|
||||
struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
|
||||
GLuint i, index;
|
||||
|
||||
|
@ -269,77 +268,61 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
|
|||
}
|
||||
/* use conventional arrays... */
|
||||
else if (index == VERT_ATTRIB_POS) {
|
||||
if (inputs & _TNL_BIT_POS) {
|
||||
_tnl_import_vertex( ctx, 0, 0 );
|
||||
tmp->Obj.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
|
||||
}
|
||||
_tnl_import_vertex( ctx, 0, 0 );
|
||||
tmp->Obj.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
|
||||
}
|
||||
else if (index == VERT_ATTRIB_NORMAL) {
|
||||
if (inputs & _TNL_BIT_NORMAL) {
|
||||
_tnl_import_normal( ctx, 0, 0 );
|
||||
tmp->Normal.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
|
||||
}
|
||||
_tnl_import_normal( ctx, 0, 0 );
|
||||
tmp->Normal.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
|
||||
}
|
||||
else if (index == VERT_ATTRIB_COLOR0) {
|
||||
if (inputs & _TNL_BIT_COLOR0) {
|
||||
_tnl_import_color( ctx, 0, 0 );
|
||||
tmp->Color.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
|
||||
}
|
||||
_tnl_import_color( ctx, 0, 0 );
|
||||
tmp->Color.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
|
||||
}
|
||||
else if (index == VERT_ATTRIB_COLOR1) {
|
||||
if (inputs & _TNL_BIT_COLOR1) {
|
||||
_tnl_import_secondarycolor( ctx, 0, 0 );
|
||||
tmp->SecondaryColor.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
|
||||
}
|
||||
_tnl_import_secondarycolor( ctx, 0, 0 );
|
||||
tmp->SecondaryColor.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
|
||||
}
|
||||
else if (index == VERT_ATTRIB_FOG) {
|
||||
if (inputs & _TNL_BIT_FOG) {
|
||||
_tnl_import_fogcoord( ctx, 0, 0 );
|
||||
tmp->FogCoord.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
|
||||
}
|
||||
_tnl_import_fogcoord( ctx, 0, 0 );
|
||||
tmp->FogCoord.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
|
||||
}
|
||||
else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
|
||||
if (inputs & _TNL_BITS_TEX_ANY) {
|
||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
|
||||
if (inputs & _TNL_BIT_TEX(i)) {
|
||||
_tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
|
||||
tmp->TexCoord[i].count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &tmp->TexCoord[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
|
||||
_tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
|
||||
tmp->TexCoord[i].count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &tmp->TexCoord[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* odd-ball vertex attributes */
|
||||
if (inputs & _TNL_BIT_INDEX) {
|
||||
{
|
||||
_tnl_import_index( ctx, 0, 0 );
|
||||
tmp->Index.count = VB->Count;
|
||||
VB->AttribPtr[_TNL_ATTRIB_INDEX] = &tmp->Index;
|
||||
}
|
||||
|
||||
if (inputs & _TNL_BIT_EDGEFLAG) {
|
||||
{
|
||||
_tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
|
||||
VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag;
|
||||
}
|
||||
|
||||
/* These are constant & can be precalculated:
|
||||
*/
|
||||
if (inputs & _TNL_BITS_MAT_ANY) {
|
||||
for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
|
||||
tmp->Attribs[i].count = 1;
|
||||
tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
|
||||
tmp->Attribs[i].start = tnl->vtx.current[i];
|
||||
tmp->Attribs[i].size = 4;
|
||||
tmp->Attribs[i].stride = 0;
|
||||
VB->AttribPtr[i] = &tmp->Attribs[i];
|
||||
}
|
||||
}
|
||||
for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
|
||||
tmp->Attribs[i].count = 1;
|
||||
tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
|
||||
tmp->Attribs[i].start = tnl->vtx.current[i];
|
||||
tmp->Attribs[i].size = 4;
|
||||
tmp->Attribs[i].stride = 0;
|
||||
VB->AttribPtr[i] = &tmp->Attribs[i];
|
||||
}
|
||||
|
||||
|
||||
/* Legacy pointers -- remove one day.
|
||||
|
@ -357,5 +340,4 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
|
|||
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
|
||||
VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ _tnl_CreateContext( GLcontext *ctx )
|
|||
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
|
||||
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
|
||||
tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables;
|
||||
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -156,16 +156,9 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
|
|||
|| !tnl->AllowPixelFog;
|
||||
}
|
||||
|
||||
if (new_state & _NEW_ARRAY) {
|
||||
tnl->pipeline.run_input_changes |= ctx->Array.NewState; /* overkill */
|
||||
}
|
||||
|
||||
_ae_invalidate_state(ctx, new_state);
|
||||
|
||||
tnl->pipeline.run_state_changes |= new_state;
|
||||
tnl->pipeline.build_state_changes |= (new_state &
|
||||
tnl->pipeline.build_state_trigger);
|
||||
|
||||
tnl->pipeline.new_state |= new_state;
|
||||
tnl->vtx.eval.new_state |= new_state;
|
||||
|
||||
/* Calculate tnl->render_inputs:
|
||||
|
@ -217,7 +210,6 @@ _tnl_wakeup_exec( GLcontext *ctx )
|
|||
/* Assume we haven't been getting state updates either:
|
||||
*/
|
||||
_tnl_InvalidateState( ctx, ~0 );
|
||||
tnl->pipeline.run_input_changes = ~0;
|
||||
|
||||
if (ctx->Light.ColorMaterialEnabled) {
|
||||
_mesa_update_color_material( ctx,
|
||||
|
|
|
@ -82,18 +82,15 @@
|
|||
|
||||
#define MAX_PIPELINE_STAGES 30
|
||||
|
||||
|
||||
/*
|
||||
* Note: The first attributes match the VERT_ATTRIB_* definitions
|
||||
* in mtypes.h. However, the tnl module has additional attributes
|
||||
* for materials, color indexes, edge flags, etc.
|
||||
*/
|
||||
/* Note: These are currently being used to define both inputs and
|
||||
* outputs from the tnl pipeline. A better solution (which would also
|
||||
* releive the congestion to slightly prolong the life of the bitmask
|
||||
* below) is to have the fixed function pipeline populate a set of
|
||||
* arrays named after those produced by the vertex program stage, and
|
||||
* have the rest the mesa backend work on those.
|
||||
/* Although it's nice to use these as bit indexes in a DWORD flag, we
|
||||
* could manage without if necessary. Another limit currently is the
|
||||
* number of bits allocated for these numbers in places like vertex
|
||||
* program instruction formats and register layouts.
|
||||
*/
|
||||
enum {
|
||||
_TNL_ATTRIB_POS = 0,
|
||||
|
@ -463,43 +460,23 @@ struct vertex_buffer
|
|||
struct tnl_pipeline_stage
|
||||
{
|
||||
const char *name;
|
||||
GLuint check_state; /* All state referenced in check() --
|
||||
* When is the pipeline_stage struct
|
||||
* itself invalidated? Must be
|
||||
* constant.
|
||||
*/
|
||||
|
||||
/* Usually constant or set by the 'check' callback:
|
||||
*/
|
||||
GLuint run_state; /* All state referenced in run() --
|
||||
* When is the cached output of the
|
||||
* stage invalidated?
|
||||
*/
|
||||
|
||||
GLboolean active; /* True if runnable in current state */
|
||||
GLuint inputs; /* VERT_* inputs to the stage */
|
||||
GLuint outputs; /* VERT_* outputs of the stage */
|
||||
|
||||
/* Set in _tnl_run_pipeline():
|
||||
*/
|
||||
GLuint changed_inputs; /* Generated value -- inputs to the
|
||||
* stage that have changed since last
|
||||
* call to 'run'.
|
||||
*/
|
||||
|
||||
|
||||
/* Private data for the pipeline stage:
|
||||
*/
|
||||
void *privatePtr;
|
||||
|
||||
/* Free private data. May not be null.
|
||||
/* Allocate private data
|
||||
*/
|
||||
GLboolean (*create)( GLcontext *ctx, struct tnl_pipeline_stage * );
|
||||
|
||||
/* Free private data.
|
||||
*/
|
||||
void (*destroy)( struct tnl_pipeline_stage * );
|
||||
|
||||
/* Called from _tnl_validate_pipeline(). Must update all fields in
|
||||
* the pipeline_stage struct for the current state.
|
||||
/* Called on any statechange or input array size change or
|
||||
* input array change to/from zero stride.
|
||||
*/
|
||||
void (*check)( GLcontext *ctx, struct tnl_pipeline_stage * );
|
||||
void (*validate)( GLcontext *ctx, struct tnl_pipeline_stage * );
|
||||
|
||||
/* Called from _tnl_run_pipeline(). The stage.changed_inputs value
|
||||
* encodes all inputs to thee struct which have changed. If
|
||||
|
@ -512,15 +489,18 @@ struct tnl_pipeline_stage
|
|||
GLboolean (*run)( GLcontext *ctx, struct tnl_pipeline_stage * );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Contains the array of all pipeline stages.
|
||||
* The default values are defined at the end of t_pipeline.c */
|
||||
* The default values are defined at the end of t_pipeline.c
|
||||
*/
|
||||
struct tnl_pipeline {
|
||||
GLuint build_state_trigger; /**< state changes which require build */
|
||||
GLuint build_state_changes; /**< state changes since last build */
|
||||
GLuint run_state_changes; /**< state changes since last run */
|
||||
GLuint run_input_changes; /**< VERT_* changes since last run */
|
||||
GLuint inputs; /**< VERT_* inputs to pipeline */
|
||||
/** This array has to end with a NULL-pointer. */
|
||||
|
||||
GLuint last_attrib_stride[_TNL_ATTRIB_MAX];
|
||||
GLuint last_attrib_size[_TNL_ATTRIB_MAX];
|
||||
GLuint input_changes;
|
||||
GLuint new_state;
|
||||
|
||||
struct tnl_pipeline_stage stages[MAX_PIPELINE_STAGES+1];
|
||||
GLuint nr_stages;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
if (s->active) {
|
||||
pipe->inputs |= s->inputs & ~generated;
|
||||
generated |= s->outputs;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
/* Check for changed input sizes or change in stride to/from zero
|
||||
* (ie const or non-const).
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
for ( ; s->run ; s++) {
|
||||
s->changed_inputs |= s->inputs & changed_inputs;
|
||||
|
||||
if (s->run_state & changed_state)
|
||||
s->changed_inputs = s->inputs;
|
||||
|
||||
if (s->active && running) {
|
||||
if (s->changed_inputs)
|
||||
changed_inputs |= s->outputs;
|
||||
|
||||
running = s->run( ctx, s );
|
||||
|
||||
s->changed_inputs = 0;
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
START_FAST_MATH(__tmp);
|
||||
|
||||
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,
|
||||
|
@ -210,6 +195,7 @@ const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
|
|||
&_tnl_point_attenuation_stage,
|
||||
#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
|
||||
&_tnl_vertex_program_stage,
|
||||
#endif
|
||||
#endif
|
||||
&_tnl_render_stage,
|
||||
NULL
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
extern void _tnl_run_pipeline( GLcontext *ctx );
|
||||
|
||||
extern void _tnl_validate_pipeline( GLcontext *ctx );
|
||||
|
||||
extern void _tnl_destroy_pipeline( GLcontext *ctx );
|
||||
|
||||
extern void _tnl_install_pipeline( GLcontext *ctx,
|
||||
|
@ -54,6 +52,7 @@ extern const struct tnl_pipeline_stage _tnl_fog_coordinate_stage;
|
|||
extern const struct tnl_pipeline_stage _tnl_texgen_stage;
|
||||
extern const struct tnl_pipeline_stage _tnl_texture_transform_stage;
|
||||
extern const struct tnl_pipeline_stage _tnl_point_attenuation_stage;
|
||||
extern const struct tnl_pipeline_stage _tnl_arb_vertex_program_stage;
|
||||
extern const struct tnl_pipeline_stage _tnl_vertex_program_stage;
|
||||
extern const struct tnl_pipeline_stage _tnl_render_stage;
|
||||
|
||||
|
|
|
@ -204,16 +204,9 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
|
|||
return;
|
||||
}
|
||||
|
||||
if (tnl->pipeline.build_state_changes)
|
||||
_tnl_validate_pipeline( ctx );
|
||||
|
||||
_tnl_bind_vertex_list( ctx, node );
|
||||
|
||||
/* Invalidate all stored data before and after run:
|
||||
*/
|
||||
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
|
||||
tnl->Driver.RunPipeline( ctx );
|
||||
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
|
||||
}
|
||||
|
||||
/* Copy to current?
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "math/m_translate.h"
|
||||
#include "t_context.h"
|
||||
#include "t_pipeline.h"
|
||||
#include "t_vp_build.h"
|
||||
|
||||
|
||||
|
||||
|
@ -416,7 +417,7 @@ static void do_PAR( struct arb_vp_machine *m, union instruction op )
|
|||
}
|
||||
|
||||
|
||||
#define RELADDR_MASK MAX_NV_VERTEX_PROGRAM_PARAMS
|
||||
#define RELADDR_MASK (MAX_NV_VERTEX_PROGRAM_PARAMS-1)
|
||||
|
||||
static void do_PRL( struct arb_vp_machine *m, union instruction op )
|
||||
{
|
||||
|
@ -1458,17 +1459,25 @@ static void
|
|||
validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
struct arb_vp_machine *m = ARB_VP_MACHINE(stage);
|
||||
struct vertex_program *program = (ctx->VertexProgram._Enabled ?
|
||||
ctx->VertexProgram.Current :
|
||||
&ctx->_TnlProgram);
|
||||
struct vertex_program *program =
|
||||
(ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : 0);
|
||||
|
||||
compile_vertex_program( m, program );
|
||||
#if TNL_FIXED_FUNCTION_PROGRAM
|
||||
if (!program) {
|
||||
_tnl_UpdateFixedFunctionProgram( ctx );
|
||||
program = &ctx->_TnlProgram;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Grab the state GL state and put into registers:
|
||||
*/
|
||||
m->File[PROGRAM_LOCAL_PARAM] = program->Base.LocalParams;
|
||||
m->File[PROGRAM_ENV_PARAM] = ctx->VertexProgram.Parameters;
|
||||
m->File[PROGRAM_STATE_VAR] = 0;
|
||||
if (program) {
|
||||
compile_vertex_program( m, program );
|
||||
|
||||
/* Grab the state GL state and put into registers:
|
||||
*/
|
||||
m->File[PROGRAM_LOCAL_PARAM] = program->Base.LocalParams;
|
||||
m->File[PROGRAM_ENV_PARAM] = ctx->VertexProgram.Parameters;
|
||||
m->File[PROGRAM_STATE_VAR] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1481,8 +1490,8 @@ validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
|||
* Called the first time stage->run is called. In effect, don't
|
||||
* allocate data until the first time the stage is run.
|
||||
*/
|
||||
static void init_vertex_program( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
static GLboolean init_vertex_program( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &(tnl->vb);
|
||||
|
@ -1493,7 +1502,7 @@ static void init_vertex_program( GLcontext *ctx,
|
|||
stage->privatePtr = MALLOC(sizeof(*m));
|
||||
m = ARB_VP_MACHINE(stage);
|
||||
if (!m)
|
||||
return;
|
||||
return GL_FALSE;
|
||||
|
||||
/* arb_vertex_machine struct should subsume the VB:
|
||||
*/
|
||||
|
@ -1509,6 +1518,14 @@ static void init_vertex_program( GLcontext *ctx,
|
|||
/* a few other misc allocations */
|
||||
_mesa_vector4f_alloc( &m->ndcCoords, 0, size, 32 );
|
||||
m->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
|
||||
|
||||
|
||||
#if TNL_FIXED_FUNCTION_PROGRAM
|
||||
_mesa_allow_light_in_model( ctx, GL_FALSE );
|
||||
#endif
|
||||
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,10 @@ static GLboolean run_cull_stage( GLcontext *ctx,
|
|||
GLuint count = VB->Count;
|
||||
GLuint i;
|
||||
|
||||
if (ctx->VertexProgram._Enabled ||
|
||||
!ctx->Transform.CullVertexFlag)
|
||||
return GL_TRUE;
|
||||
|
||||
VB->ClipOrMask &= ~CLIP_CULL_BIT;
|
||||
VB->ClipAndMask |= CLIP_CULL_BIT;
|
||||
|
||||
|
@ -81,31 +85,13 @@ static GLboolean run_cull_stage( GLcontext *ctx,
|
|||
}
|
||||
|
||||
|
||||
static void check_cull( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
stage->active = (!ctx->VertexProgram._Enabled &&
|
||||
ctx->Transform.CullVertexFlag);
|
||||
}
|
||||
|
||||
|
||||
static void dtr( struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const struct tnl_pipeline_stage _tnl_vertex_cull_stage =
|
||||
{
|
||||
"EXT_cull_vertex",
|
||||
_NEW_PROGRAM |
|
||||
_NEW_TRANSFORM,
|
||||
_NEW_TRANSFORM,
|
||||
GL_TRUE, /* active */
|
||||
_TNL_BIT_NORMAL |
|
||||
_TNL_BIT_POS, /* inputs */
|
||||
_TNL_BIT_POS, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private data */
|
||||
dtr, /* destructor */
|
||||
check_cull, /* check */
|
||||
NULL, /* ctr */
|
||||
NULL, /* destructor */
|
||||
NULL,
|
||||
run_cull_stage /* run -- initially set to init */
|
||||
};
|
||||
|
|
|
@ -148,9 +148,10 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
|||
struct fog_stage_data *store = FOG_STAGE_DATA(stage);
|
||||
GLvector4f *input;
|
||||
|
||||
if (stage->changed_inputs == 0)
|
||||
if (!ctx->Fog.Enabled || ctx->VertexProgram._Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
|
||||
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) {
|
||||
/* Fog is computed from vertex or fragment Z values */
|
||||
/* source = VB->ObjPtr or VB->EyePtr coords */
|
||||
|
@ -213,17 +214,6 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
check_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
||||
{
|
||||
stage->active = ctx->Fog.Enabled && !ctx->VertexProgram._Enabled;
|
||||
|
||||
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT)
|
||||
stage->inputs = _TNL_BIT_POS;
|
||||
else
|
||||
stage->inputs = _TNL_BIT_FOG;
|
||||
}
|
||||
|
||||
|
||||
/* Called the first time stage->run() is invoked.
|
||||
*/
|
||||
|
@ -243,10 +233,7 @@ alloc_fog_data(GLcontext *ctx, struct tnl_pipeline_stage *stage)
|
|||
if (!inited)
|
||||
init_static_data();
|
||||
|
||||
/* Now run the stage.
|
||||
*/
|
||||
stage->run = run_fog_stage;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,14 +252,9 @@ free_fog_data(struct tnl_pipeline_stage *stage)
|
|||
const struct tnl_pipeline_stage _tnl_fog_coordinate_stage =
|
||||
{
|
||||
"build fog coordinates", /* name */
|
||||
_NEW_FOG|_NEW_PROGRAM, /* check_state */
|
||||
_NEW_FOG, /* run_state */
|
||||
GL_FALSE, /* active? */
|
||||
0, /* inputs */
|
||||
_TNL_BIT_FOG, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private_data */
|
||||
alloc_fog_data, /* dtr */
|
||||
free_fog_data, /* dtr */
|
||||
check_fog_stage, /* check */
|
||||
alloc_fog_data /* run -- initially set to init. */
|
||||
NULL, /* check */
|
||||
run_fog_stage /* run -- initially set to init. */
|
||||
};
|
||||
|
|
|
@ -180,7 +180,7 @@ static light_func _tnl_light_ci_tab[MAX_LIGHT_FUNC];
|
|||
#include "t_vb_lighttmp.h"
|
||||
|
||||
|
||||
static void init_lighting( void )
|
||||
static void init_lighting_tables( void )
|
||||
{
|
||||
static int done;
|
||||
|
||||
|
@ -203,33 +203,34 @@ static GLboolean run_lighting( GLcontext *ctx,
|
|||
GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
|
||||
GLuint idx;
|
||||
|
||||
if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
/* Make sure we can talk about position x,y and z:
|
||||
*/
|
||||
if (stage->changed_inputs & _TNL_BIT_POS) {
|
||||
if (input->size <= 2 && input == VB->ObjPtr) {
|
||||
if (input->size <= 2 && input == VB->ObjPtr) {
|
||||
|
||||
_math_trans_4f( store->Input.data,
|
||||
VB->ObjPtr->data,
|
||||
VB->ObjPtr->stride,
|
||||
GL_FLOAT,
|
||||
VB->ObjPtr->size,
|
||||
0,
|
||||
VB->Count );
|
||||
_math_trans_4f( store->Input.data,
|
||||
VB->ObjPtr->data,
|
||||
VB->ObjPtr->stride,
|
||||
GL_FLOAT,
|
||||
VB->ObjPtr->size,
|
||||
0,
|
||||
VB->Count );
|
||||
|
||||
if (input->size <= 2) {
|
||||
/* Clean z.
|
||||
*/
|
||||
_mesa_vector4f_clean_elem(&store->Input, VB->Count, 2);
|
||||
}
|
||||
|
||||
if (input->size <= 1) {
|
||||
/* Clean y.
|
||||
*/
|
||||
_mesa_vector4f_clean_elem(&store->Input, VB->Count, 1);
|
||||
}
|
||||
|
||||
input = &store->Input;
|
||||
if (input->size <= 2) {
|
||||
/* Clean z.
|
||||
*/
|
||||
_mesa_vector4f_clean_elem(&store->Input, VB->Count, 2);
|
||||
}
|
||||
|
||||
if (input->size <= 1) {
|
||||
/* Clean y.
|
||||
*/
|
||||
_mesa_vector4f_clean_elem(&store->Input, VB->Count, 1);
|
||||
}
|
||||
|
||||
input = &store->Input;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
|
@ -255,11 +256,14 @@ static GLboolean run_lighting( GLcontext *ctx,
|
|||
|
||||
/* Called in place of do_lighting when the light table may have changed.
|
||||
*/
|
||||
static GLboolean run_validate_lighting( GLcontext *ctx,
|
||||
static void validate_lighting( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
light_func *tab;
|
||||
|
||||
if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled)
|
||||
return;
|
||||
|
||||
if (ctx->Visual.rgbMode) {
|
||||
if (ctx->Light._NeedVertices) {
|
||||
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
|
||||
|
@ -283,11 +287,6 @@ static GLboolean run_validate_lighting( GLcontext *ctx,
|
|||
/* This and the above should only be done on _NEW_LIGHT:
|
||||
*/
|
||||
TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
|
||||
|
||||
/* Now run the stage...
|
||||
*/
|
||||
stage->run = run_lighting;
|
||||
return stage->run( ctx, stage );
|
||||
}
|
||||
|
||||
|
||||
|
@ -295,8 +294,8 @@ static GLboolean run_validate_lighting( GLcontext *ctx,
|
|||
/* Called the first time stage->run is called. In effect, don't
|
||||
* allocate data until the first time the stage is run.
|
||||
*/
|
||||
static GLboolean run_init_lighting( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
static GLboolean init_lighting( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct light_stage_data *store;
|
||||
|
@ -309,7 +308,7 @@ static GLboolean run_init_lighting( GLcontext *ctx,
|
|||
|
||||
/* Do onetime init.
|
||||
*/
|
||||
init_lighting();
|
||||
init_lighting_tables();
|
||||
|
||||
_mesa_vector4f_alloc( &store->Input, 0, size, 32 );
|
||||
_mesa_vector4f_alloc( &store->LitColor[0], 0, size, 32 );
|
||||
|
@ -329,36 +328,11 @@ static GLboolean run_init_lighting( GLcontext *ctx,
|
|||
store->LitIndex[1].size = 1;
|
||||
store->LitIndex[1].stride = sizeof(GLfloat);
|
||||
|
||||
/* Now validate the stage derived data...
|
||||
*/
|
||||
stage->run = run_validate_lighting;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Check if lighting is enabled. If so, configure the pipeline stage's
|
||||
* type, inputs, and outputs.
|
||||
*/
|
||||
static void check_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
stage->active = ctx->Light.Enabled && !ctx->VertexProgram._Enabled;
|
||||
if (stage->active) {
|
||||
if (stage->privatePtr)
|
||||
stage->run = run_validate_lighting;
|
||||
stage->inputs = _TNL_BIT_NORMAL|_TNL_BITS_MAT_ANY;
|
||||
if (ctx->Light._NeedVertices)
|
||||
stage->inputs |= _TNL_BIT_POS;
|
||||
if (ctx->Light.ColorMaterialEnabled)
|
||||
stage->inputs |= _TNL_BIT_COLOR0;
|
||||
|
||||
stage->outputs = _TNL_BIT_COLOR0;
|
||||
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
|
||||
stage->outputs |= _TNL_BIT_COLOR1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dtr( struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
|
@ -380,16 +354,9 @@ static void dtr( struct tnl_pipeline_stage *stage )
|
|||
const struct tnl_pipeline_stage _tnl_lighting_stage =
|
||||
{
|
||||
"lighting", /* name */
|
||||
_NEW_LIGHT|_NEW_PROGRAM, /* recheck */
|
||||
_NEW_LIGHT|_NEW_MODELVIEW, /* recalc -- modelview dependency
|
||||
* otherwise not captured by inputs
|
||||
* (which may be _TNL_BIT_POS) */
|
||||
GL_FALSE, /* active? */
|
||||
0, /* inputs */
|
||||
0, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private_data */
|
||||
init_lighting,
|
||||
dtr, /* destroy */
|
||||
check_lighting, /* check */
|
||||
run_init_lighting /* run -- initially set to ctr */
|
||||
validate_lighting,
|
||||
run_lighting
|
||||
};
|
||||
|
|
|
@ -82,10 +82,6 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
|
|||
sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
|
||||
#endif
|
||||
|
||||
/* Side-effects done, can we finish now?
|
||||
*/
|
||||
if (stage->changed_inputs == 0)
|
||||
return;
|
||||
|
||||
store->LitColor[0].stride = 16;
|
||||
store->LitColor[1].stride = 16;
|
||||
|
@ -271,9 +267,6 @@ static void TAG(light_rgba)( GLcontext *ctx,
|
|||
sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
|
||||
#endif
|
||||
|
||||
if (stage->changed_inputs == 0)
|
||||
return;
|
||||
|
||||
store->LitColor[0].stride = 16;
|
||||
store->LitColor[1].stride = 16;
|
||||
|
||||
|
@ -461,9 +454,6 @@ static void TAG(light_fast_rgba_single)( GLcontext *ctx,
|
|||
VB->ColorPtr[1] = &store->LitColor[1];
|
||||
#endif
|
||||
|
||||
if (stage->changed_inputs == 0)
|
||||
return;
|
||||
|
||||
if (nr > 1) {
|
||||
store->LitColor[0].stride = 16;
|
||||
store->LitColor[1].stride = 16;
|
||||
|
@ -574,9 +564,6 @@ static void TAG(light_fast_rgba)( GLcontext *ctx,
|
|||
VB->ColorPtr[1] = &store->LitColor[1];
|
||||
#endif
|
||||
|
||||
if (stage->changed_inputs == 0)
|
||||
return;
|
||||
|
||||
if (nr > 1) {
|
||||
store->LitColor[0].stride = 16;
|
||||
store->LitColor[1].stride = 16;
|
||||
|
@ -683,9 +670,6 @@ static void TAG(light_ci)( GLcontext *ctx,
|
|||
VB->IndexPtr[1] = &store->LitIndex[1];
|
||||
#endif
|
||||
|
||||
if (stage->changed_inputs == 0)
|
||||
return;
|
||||
|
||||
indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;
|
||||
#if IDX & LIGHT_TWOSIDE
|
||||
indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;
|
||||
|
|
|
@ -55,31 +55,30 @@ static GLboolean run_normal_stage( GLcontext *ctx,
|
|||
{
|
||||
struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
const GLfloat *lengths;
|
||||
|
||||
ASSERT(store->NormalTransform);
|
||||
if (!store->NormalTransform)
|
||||
return GL_TRUE;
|
||||
|
||||
if (stage->changed_inputs) {
|
||||
/* We can only use the display list's saved normal lengths if we've
|
||||
* got a transformation matrix with uniform scaling.
|
||||
*/
|
||||
const GLfloat *lengths;
|
||||
if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE)
|
||||
lengths = NULL;
|
||||
else
|
||||
lengths = VB->NormalLengthPtr;
|
||||
/* We can only use the display list's saved normal lengths if we've
|
||||
* got a transformation matrix with uniform scaling.
|
||||
*/
|
||||
if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE)
|
||||
lengths = NULL;
|
||||
else
|
||||
lengths = VB->NormalLengthPtr;
|
||||
|
||||
store->NormalTransform( ctx->ModelviewMatrixStack.Top,
|
||||
ctx->_ModelViewInvScale,
|
||||
VB->NormalPtr, /* input normals */
|
||||
lengths,
|
||||
&store->normal ); /* resulting normals */
|
||||
store->NormalTransform( ctx->ModelviewMatrixStack.Top,
|
||||
ctx->_ModelViewInvScale,
|
||||
VB->NormalPtr, /* input normals */
|
||||
lengths,
|
||||
&store->normal ); /* resulting normals */
|
||||
|
||||
if (VB->NormalPtr->count > 1) {
|
||||
store->normal.stride = 16;
|
||||
}
|
||||
else {
|
||||
store->normal.stride = 0;
|
||||
}
|
||||
if (VB->NormalPtr->count > 1) {
|
||||
store->normal.stride = 16;
|
||||
}
|
||||
else {
|
||||
store->normal.stride = 0;
|
||||
}
|
||||
|
||||
VB->NormalPtr = &store->normal;
|
||||
|
@ -90,12 +89,19 @@ static GLboolean run_normal_stage( GLcontext *ctx,
|
|||
}
|
||||
|
||||
|
||||
static GLboolean run_validate_normal_stage( GLcontext *ctx,
|
||||
static void validate_normal_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
|
||||
|
||||
|
||||
if (ctx->VertexProgram._Enabled ||
|
||||
(!ctx->Light.Enabled &&
|
||||
!(ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))) {
|
||||
store->NormalTransform = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ctx->_NeedEyeCoords) {
|
||||
GLuint transform = NORM_TRANSFORM_NO_ROT;
|
||||
|
||||
|
@ -129,29 +135,9 @@ static GLboolean run_validate_normal_stage( GLcontext *ctx,
|
|||
store->NormalTransform = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (store->NormalTransform) {
|
||||
stage->run = run_normal_stage;
|
||||
return stage->run( ctx, stage );
|
||||
} else {
|
||||
stage->active = GL_FALSE; /* !!! */
|
||||
return GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void check_normal_transform( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
stage->active = !ctx->VertexProgram._Enabled &&
|
||||
(ctx->Light.Enabled || (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS));
|
||||
|
||||
/* Don't clobber the initialize function:
|
||||
*/
|
||||
if (stage->privatePtr)
|
||||
stage->run = run_validate_normal_stage;
|
||||
}
|
||||
|
||||
|
||||
static GLboolean alloc_normal_data( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
|
@ -164,11 +150,7 @@ static GLboolean alloc_normal_data( GLcontext *ctx,
|
|||
return GL_FALSE;
|
||||
|
||||
_mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 );
|
||||
|
||||
/* Now run the stage.
|
||||
*/
|
||||
stage->run = run_validate_normal_stage;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,25 +165,13 @@ static void free_normal_data( struct tnl_pipeline_stage *stage )
|
|||
}
|
||||
}
|
||||
|
||||
#define _TNL_NEW_NORMAL_TRANSFORM (_NEW_MODELVIEW| \
|
||||
_NEW_TRANSFORM| \
|
||||
_NEW_PROGRAM| \
|
||||
_MESA_NEW_NEED_NORMALS| \
|
||||
_MESA_NEW_NEED_EYE_COORDS)
|
||||
|
||||
|
||||
|
||||
const struct tnl_pipeline_stage _tnl_normal_transform_stage =
|
||||
{
|
||||
"normal transform", /* name */
|
||||
_TNL_NEW_NORMAL_TRANSFORM, /* re-check */
|
||||
_TNL_NEW_NORMAL_TRANSFORM, /* re-run */
|
||||
GL_FALSE, /* active? */
|
||||
_TNL_BIT_NORMAL, /* inputs */
|
||||
_TNL_BIT_NORMAL, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private data */
|
||||
alloc_normal_data,
|
||||
free_normal_data, /* destructor */
|
||||
check_normal_transform, /* check */
|
||||
alloc_normal_data /* run -- initially set to alloc */
|
||||
validate_normal_stage, /* check */
|
||||
run_normal_stage
|
||||
};
|
||||
|
|
|
@ -44,39 +44,31 @@ struct point_stage_data {
|
|||
static GLboolean run_point_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
struct point_stage_data *store = POINT_STAGE_DATA(stage);
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data;
|
||||
const GLfloat p0 = ctx->Point.Params[0];
|
||||
const GLfloat p1 = ctx->Point.Params[1];
|
||||
const GLfloat p2 = ctx->Point.Params[2];
|
||||
const GLfloat pointSize = ctx->Point._Size;
|
||||
GLfloat (*size)[4] = store->PointSize.data;
|
||||
GLuint i;
|
||||
if (ctx->Point._Attenuated && !ctx->VertexProgram._Enabled) {
|
||||
struct point_stage_data *store = POINT_STAGE_DATA(stage);
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data;
|
||||
const GLfloat p0 = ctx->Point.Params[0];
|
||||
const GLfloat p1 = ctx->Point.Params[1];
|
||||
const GLfloat p2 = ctx->Point.Params[2];
|
||||
const GLfloat pointSize = ctx->Point._Size;
|
||||
GLfloat (*size)[4] = store->PointSize.data;
|
||||
GLuint i;
|
||||
|
||||
if (stage->changed_inputs) {
|
||||
/* XXX do threshold and min/max clamping here? */
|
||||
for (i = 0; i < VB->Count; i++) {
|
||||
const GLfloat dist = -eye[i][2];
|
||||
/* GLfloat dist = SQRTF(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);*/
|
||||
size[i][0] = pointSize / (p0 + dist * (p1 + dist * p2));
|
||||
}
|
||||
}
|
||||
|
||||
VB->PointSizePtr = &store->PointSize;
|
||||
VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize;
|
||||
VB->PointSizePtr = &store->PointSize;
|
||||
VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* If point size attenuation is on we'll compute the point size for
|
||||
* each vertex in a special pipeline stage.
|
||||
*/
|
||||
static void check_point_size( GLcontext *ctx, struct tnl_pipeline_stage *d )
|
||||
{
|
||||
d->active = ctx->Point._Attenuated && !ctx->VertexProgram._Enabled;
|
||||
}
|
||||
|
||||
static GLboolean alloc_point_data( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
|
@ -89,11 +81,7 @@ static GLboolean alloc_point_data( GLcontext *ctx,
|
|||
return GL_FALSE;
|
||||
|
||||
_mesa_vector4f_alloc( &store->PointSize, 0, VB->Size, 32 );
|
||||
|
||||
/* Now run the stage.
|
||||
*/
|
||||
stage->run = run_point_stage;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,14 +98,9 @@ static void free_point_data( struct tnl_pipeline_stage *stage )
|
|||
const struct tnl_pipeline_stage _tnl_point_attenuation_stage =
|
||||
{
|
||||
"point size attenuation", /* name */
|
||||
_NEW_POINT|_NEW_PROGRAM, /* check_state */
|
||||
_NEW_POINT, /* run_state */
|
||||
GL_FALSE, /* active */
|
||||
_TNL_BIT_POS, /* inputs */
|
||||
_TNL_BIT_POS, /* outputs */
|
||||
0, /* changed_inputs (temporary value) */
|
||||
NULL, /* stage private data */
|
||||
alloc_point_data, /* alloc data */
|
||||
free_point_data, /* destructor */
|
||||
check_point_size, /* check */
|
||||
alloc_point_data /* run -- initially set to alloc data */
|
||||
NULL,
|
||||
run_point_stage /* run */
|
||||
};
|
||||
|
|
|
@ -51,26 +51,6 @@
|
|||
#include "t_pipeline.h"
|
||||
|
||||
|
||||
/**
|
||||
* \warning These values _MUST_ match the values in the OutputRegisters[]
|
||||
* array in vpparse.c!!!
|
||||
*/
|
||||
#define VERT_RESULT_HPOS 0
|
||||
#define VERT_RESULT_COL0 1
|
||||
#define VERT_RESULT_COL1 2
|
||||
#define VERT_RESULT_BFC0 3
|
||||
#define VERT_RESULT_BFC1 4
|
||||
#define VERT_RESULT_FOGC 5
|
||||
#define VERT_RESULT_PSIZ 6
|
||||
#define VERT_RESULT_TEX0 7
|
||||
#define VERT_RESULT_TEX1 8
|
||||
#define VERT_RESULT_TEX2 9
|
||||
#define VERT_RESULT_TEX3 10
|
||||
#define VERT_RESULT_TEX4 11
|
||||
#define VERT_RESULT_TEX5 12
|
||||
#define VERT_RESULT_TEX6 13
|
||||
#define VERT_RESULT_TEX7 14
|
||||
|
||||
|
||||
/*!
|
||||
* Private storage for the vertex program pipeline stage.
|
||||
|
@ -100,6 +80,9 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
|||
struct vertex_program *program = ctx->VertexProgram.Current;
|
||||
GLuint i;
|
||||
|
||||
if (!ctx->VertexProgram._Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
/* load program parameter registers (they're read-only) */
|
||||
_mesa_init_vp_per_primitive_registers(ctx);
|
||||
|
||||
|
@ -223,61 +206,14 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function validates stuff.
|
||||
*/
|
||||
static GLboolean run_validate_program( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
#if 000
|
||||
/* XXX do we need any validation for vertex programs? */
|
||||
GLuint ind = 0;
|
||||
light_func *tab;
|
||||
|
||||
if (ctx->Visual.rgbMode) {
|
||||
if (ctx->Light._NeedVertices) {
|
||||
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
|
||||
tab = _tnl_light_spec_tab;
|
||||
else
|
||||
tab = _tnl_light_tab;
|
||||
}
|
||||
else {
|
||||
if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
|
||||
tab = _tnl_light_fast_single_tab;
|
||||
else
|
||||
tab = _tnl_light_fast_tab;
|
||||
}
|
||||
}
|
||||
else
|
||||
tab = _tnl_light_ci_tab;
|
||||
|
||||
if (ctx->Light.ColorMaterialEnabled)
|
||||
ind |= LIGHT_COLORMATERIAL;
|
||||
|
||||
if (ctx->Light.Model.TwoSide)
|
||||
ind |= LIGHT_TWOSIDE;
|
||||
|
||||
VP_STAGE_DATA(stage)->light_func_tab = &tab[ind];
|
||||
|
||||
/* This and the above should only be done on _NEW_LIGHT:
|
||||
*/
|
||||
_mesa_validate_all_lighting_tables( ctx );
|
||||
#endif
|
||||
|
||||
/* Now run the stage...
|
||||
*/
|
||||
stage->run = run_vp;
|
||||
return stage->run( ctx, stage );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called the first time stage->run is called. In effect, don't
|
||||
* allocate data until the first time the stage is run.
|
||||
*/
|
||||
static GLboolean run_init_vp( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
static GLboolean init_vp( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &(tnl->vb);
|
||||
|
@ -300,29 +236,11 @@ static GLboolean run_init_vp( GLcontext *ctx,
|
|||
_mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
|
||||
store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
|
||||
|
||||
/* Now validate the stage derived data...
|
||||
*/
|
||||
stage->run = run_validate_program;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if vertex program mode is enabled.
|
||||
* If so, configure the pipeline stage's type, inputs, and outputs.
|
||||
*/
|
||||
static void check_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
stage->active = ctx->VertexProgram._Enabled;
|
||||
|
||||
if (stage->active) {
|
||||
/* Set stage->inputs equal to the bitmask of vertex attributes
|
||||
* which the program needs for inputs.
|
||||
*/
|
||||
stage->inputs = ctx->VertexProgram.Current->InputsRead;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -336,7 +254,7 @@ static void dtr( struct tnl_pipeline_stage *stage )
|
|||
GLuint i;
|
||||
|
||||
/* free the vertex program result arrays */
|
||||
for (i = 0; i < 15; i++)
|
||||
for (i = 0; i < VERT_RESULT_MAX; i++)
|
||||
_mesa_vector4f_free( &store->attribs[i] );
|
||||
|
||||
/* free misc arrays */
|
||||
|
@ -354,14 +272,9 @@ static void dtr( struct tnl_pipeline_stage *stage )
|
|||
const struct tnl_pipeline_stage _tnl_vertex_program_stage =
|
||||
{
|
||||
"vertex-program",
|
||||
_NEW_ALL, /*XXX FIX */ /* recheck */
|
||||
_NEW_ALL, /*XXX FIX */ /* recalc */
|
||||
GL_FALSE, /* active */
|
||||
0, /* inputs - calculated on the fly */
|
||||
_TNL_BITS_PROG_ANY, /* outputs -- could calculate */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private_data */
|
||||
init_vp, /* create */
|
||||
dtr, /* destroy */
|
||||
check_vp, /* check */
|
||||
run_init_vp /* run -- initially set to ctr */
|
||||
NULL, /* validate */
|
||||
run_vp /* run -- initially set to ctr */
|
||||
};
|
||||
|
|
|
@ -268,7 +268,6 @@ static GLboolean run_render( GLcontext *ctx,
|
|||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
GLuint new_inputs = stage->changed_inputs;
|
||||
tnl_render_func *tab;
|
||||
GLint pass = 0;
|
||||
|
||||
|
@ -293,7 +292,7 @@ static GLboolean run_render( GLcontext *ctx,
|
|||
ASSERT(tnl->Driver.Render.ClippedPolygon);
|
||||
ASSERT(tnl->Driver.Render.Finish);
|
||||
|
||||
tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs );
|
||||
tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 );
|
||||
|
||||
if (VB->ClipOrMask) {
|
||||
tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
|
||||
|
@ -340,42 +339,14 @@ static GLboolean run_render( GLcontext *ctx,
|
|||
|
||||
|
||||
|
||||
/* Quite a bit of work involved in finding out the inputs for the
|
||||
* render stage.
|
||||
*/
|
||||
static void check_render( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void dtr( struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
(void) stage;
|
||||
}
|
||||
|
||||
|
||||
const struct tnl_pipeline_stage _tnl_render_stage =
|
||||
{
|
||||
"render", /* name */
|
||||
(_NEW_BUFFERS |
|
||||
_DD_NEW_SEPARATE_SPECULAR |
|
||||
_DD_NEW_FLATSHADE |
|
||||
_NEW_TEXTURE|
|
||||
_NEW_LIGHT|
|
||||
_NEW_POINT|
|
||||
_NEW_FOG|
|
||||
_DD_NEW_TRI_UNFILLED |
|
||||
_NEW_RENDERMODE), /* re-check (new inputs, interp function) */
|
||||
0, /* re-run (always runs) */
|
||||
GL_TRUE, /* active? */
|
||||
0, /* inputs (set in check_render) */
|
||||
0, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private data */
|
||||
dtr, /* destructor */
|
||||
check_render, /* check */
|
||||
NULL, /* creator */
|
||||
NULL, /* destructor */
|
||||
NULL, /* validate */
|
||||
run_render /* run */
|
||||
};
|
||||
|
|
|
@ -480,34 +480,42 @@ static void texgen( GLcontext *ctx,
|
|||
|
||||
|
||||
|
||||
|
||||
static GLboolean run_texgen_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage );
|
||||
struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
|
||||
GLuint i;
|
||||
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
|
||||
if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) {
|
||||
if (stage->changed_inputs & (_TNL_BIT_POS | _TNL_BIT_NORMAL | _TNL_BIT_TEX(i)))
|
||||
store->TexgenFunc[i]( ctx, store, i );
|
||||
if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
|
||||
|
||||
if (texUnit->TexGenEnabled) {
|
||||
|
||||
store->TexgenFunc[i]( ctx, store, i );
|
||||
|
||||
VB->AttribPtr[VERT_ATTRIB_TEX0+i] =
|
||||
VB->TexCoordPtr[i] = &store->texcoord[i];
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static GLboolean run_validate_texgen_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
static void validate_texgen_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
|
||||
GLuint i;
|
||||
|
||||
if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Enabled)
|
||||
return;
|
||||
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
|
||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
|
||||
|
||||
|
@ -541,48 +549,9 @@ static GLboolean run_validate_texgen_stage( GLcontext *ctx,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage->run = run_texgen_stage;
|
||||
return stage->run( ctx, stage );
|
||||
}
|
||||
|
||||
|
||||
static void check_texgen( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
GLuint i;
|
||||
stage->active = 0;
|
||||
|
||||
if (ctx->Texture._TexGenEnabled && !ctx->VertexProgram._Enabled) {
|
||||
GLuint inputs = 0;
|
||||
GLuint outputs = 0;
|
||||
|
||||
if (ctx->Texture._GenFlags & (TEXGEN_OBJ_LINEAR | TEXGEN_NEED_EYE_COORD))
|
||||
inputs |= _TNL_BIT_POS;
|
||||
|
||||
if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
|
||||
inputs |= _TNL_BIT_NORMAL;
|
||||
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
|
||||
if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i))
|
||||
{
|
||||
outputs |= _TNL_BIT_TEX(i);
|
||||
|
||||
/* Need the original input in case it contains a Q coord:
|
||||
* (sigh)
|
||||
*/
|
||||
inputs |= _TNL_BIT_TEX(i);
|
||||
|
||||
/* Something for Feedback? */
|
||||
}
|
||||
|
||||
if (stage->privatePtr)
|
||||
stage->run = run_validate_texgen_stage;
|
||||
stage->active = 1;
|
||||
stage->inputs = inputs;
|
||||
stage->outputs = outputs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -606,10 +575,7 @@ static GLboolean alloc_texgen_data( GLcontext *ctx,
|
|||
store->tmp_f = (GLfloat (*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3);
|
||||
store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat));
|
||||
|
||||
/* Now validate and run the stage.
|
||||
*/
|
||||
stage->run = run_validate_texgen_stage;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -637,14 +603,9 @@ static void free_texgen_data( struct tnl_pipeline_stage *stage )
|
|||
const struct tnl_pipeline_stage _tnl_texgen_stage =
|
||||
{
|
||||
"texgen", /* name */
|
||||
_NEW_TEXTURE|_NEW_PROGRAM, /* when to call check() */
|
||||
_NEW_TEXTURE, /* when to invalidate stored data */
|
||||
GL_FALSE, /* active? */
|
||||
0, /* inputs */
|
||||
0, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private data */
|
||||
alloc_texgen_data, /* destructor */
|
||||
free_texgen_data, /* destructor */
|
||||
check_texgen, /* check */
|
||||
alloc_texgen_data /* run -- initially set to alloc data */
|
||||
validate_texgen_stage, /* check */
|
||||
run_texgen_stage /* run -- initially set to alloc data */
|
||||
};
|
||||
|
|
|
@ -52,23 +52,7 @@ struct texmat_stage_data {
|
|||
|
||||
#define TEXMAT_STAGE_DATA(stage) ((struct texmat_stage_data *)stage->privatePtr)
|
||||
|
||||
static void check_texmat( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
GLuint i;
|
||||
stage->active = 0;
|
||||
|
||||
if (ctx->Texture._TexMatEnabled && !ctx->VertexProgram._Enabled) {
|
||||
GLuint flags = 0;
|
||||
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
|
||||
if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i))
|
||||
flags |= _TNL_BIT_TEX(i);
|
||||
|
||||
stage->active = 1;
|
||||
stage->inputs = flags;
|
||||
stage->outputs = flags;
|
||||
}
|
||||
}
|
||||
|
||||
static GLboolean run_texmat_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
|
@ -77,19 +61,23 @@ static GLboolean run_texmat_stage( GLcontext *ctx,
|
|||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
GLuint i;
|
||||
|
||||
if (!ctx->Texture._TexMatEnabled || ctx->VertexProgram._Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
/* ENABLE_TEXMAT implies that the texture matrix is not the
|
||||
* identity, so we don't have to check that here.
|
||||
*/
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
|
||||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
|
||||
if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) {
|
||||
if (stage->changed_inputs & _TNL_BIT_TEX(i))
|
||||
(void) TransformRaw( &store->texcoord[i],
|
||||
ctx->TextureMatrixStack[i].Top,
|
||||
VB->TexCoordPtr[i]);
|
||||
(void) TransformRaw( &store->texcoord[i],
|
||||
ctx->TextureMatrixStack[i].Top,
|
||||
VB->TexCoordPtr[i]);
|
||||
|
||||
VB->AttribPtr[VERT_ATTRIB_TEX0+i] =
|
||||
VB->TexCoordPtr[i] = &store->texcoord[i];
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -111,10 +99,7 @@ static GLboolean alloc_texmat_data( GLcontext *ctx,
|
|||
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
|
||||
_mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
|
||||
|
||||
/* Now run the stage.
|
||||
*/
|
||||
stage->run = run_texmat_stage;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,14 +122,9 @@ static void free_texmat_data( struct tnl_pipeline_stage *stage )
|
|||
const struct tnl_pipeline_stage _tnl_texture_transform_stage =
|
||||
{
|
||||
"texture transform", /* name */
|
||||
_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|_NEW_PROGRAM, /* check_state */
|
||||
_NEW_TEXTURE|_NEW_TEXTURE_MATRIX, /* run_state */
|
||||
GL_FALSE, /* active? */
|
||||
0, /* inputs */
|
||||
0, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private data */
|
||||
alloc_texmat_data,
|
||||
free_texmat_data, /* destructor */
|
||||
check_texmat, /* check */
|
||||
alloc_texmat_data, /* run -- initially set to init */
|
||||
NULL,
|
||||
run_texmat_stage,
|
||||
};
|
||||
|
|
|
@ -47,14 +47,6 @@ struct vertex_stage_data {
|
|||
GLubyte *clipmask;
|
||||
GLubyte ormask;
|
||||
GLubyte andmask;
|
||||
|
||||
|
||||
/* Need these because it's difficult to replay the sideeffects
|
||||
* analytically.
|
||||
*/
|
||||
GLvector4f *save_eyeptr;
|
||||
GLvector4f *save_clipptr;
|
||||
GLvector4f *save_ndcptr;
|
||||
};
|
||||
|
||||
#define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr)
|
||||
|
@ -134,137 +126,90 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
|
|||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
|
||||
ASSERT(!ctx->VertexProgram._Enabled);
|
||||
if (ctx->VertexProgram._Enabled)
|
||||
return GL_TRUE;
|
||||
|
||||
if (stage->changed_inputs) {
|
||||
|
||||
if (ctx->_NeedEyeCoords) {
|
||||
/* Separate modelview transformation:
|
||||
* Use combined ModelProject to avoid some depth artifacts
|
||||
*/
|
||||
if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
|
||||
VB->EyePtr = VB->ObjPtr;
|
||||
else
|
||||
VB->EyePtr = TransformRaw( &store->eye,
|
||||
ctx->ModelviewMatrixStack.Top,
|
||||
VB->ObjPtr);
|
||||
#if 0
|
||||
/* examine some eye coordinates */
|
||||
{
|
||||
GLuint i;
|
||||
GLfloat *v = VB->EyePtr->start;
|
||||
for (i = 0; i < 4; i++) {
|
||||
_mesa_printf("eye[%d] = %g, %g, %g, %g\n",
|
||||
i, v[0], v[1], v[2], v[3]);
|
||||
v += 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
VB->ClipPtr = TransformRaw( &store->clip,
|
||||
&ctx->_ModelProjectMatrix,
|
||||
VB->ObjPtr );
|
||||
|
||||
/* Drivers expect this to be clean to element 4...
|
||||
if (ctx->_NeedEyeCoords) {
|
||||
/* Separate modelview transformation:
|
||||
* Use combined ModelProject to avoid some depth artifacts
|
||||
*/
|
||||
switch (VB->ClipPtr->size) {
|
||||
case 1:
|
||||
/* impossible */
|
||||
case 2:
|
||||
_mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
|
||||
/* fall-through */
|
||||
case 3:
|
||||
_mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
|
||||
/* fall-through */
|
||||
case 4:
|
||||
break;
|
||||
}
|
||||
if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
|
||||
VB->EyePtr = VB->ObjPtr;
|
||||
else
|
||||
VB->EyePtr = TransformRaw( &store->eye,
|
||||
ctx->ModelviewMatrixStack.Top,
|
||||
VB->ObjPtr);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* examine some clip coordinates */
|
||||
{
|
||||
GLuint i;
|
||||
GLfloat *v = VB->ClipPtr->start;
|
||||
for (i = 0; i < 4; i++) {
|
||||
_mesa_printf("clip[%d] = %g, %g, %g, %g\n",
|
||||
i, v[0], v[1], v[2], v[3]);
|
||||
v += 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
VB->ClipPtr = TransformRaw( &store->clip,
|
||||
&ctx->_ModelProjectMatrix,
|
||||
VB->ObjPtr );
|
||||
|
||||
/* Cliptest and perspective divide. Clip functions must clear
|
||||
* the clipmask.
|
||||
*/
|
||||
store->ormask = 0;
|
||||
store->andmask = CLIP_ALL_BITS;
|
||||
|
||||
if (tnl->NeedNdcCoords) {
|
||||
VB->NdcPtr =
|
||||
_mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
|
||||
&store->proj,
|
||||
store->clipmask,
|
||||
&store->ormask,
|
||||
&store->andmask );
|
||||
}
|
||||
else {
|
||||
VB->NdcPtr = NULL;
|
||||
_mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
|
||||
NULL,
|
||||
store->clipmask,
|
||||
&store->ormask,
|
||||
&store->andmask );
|
||||
}
|
||||
|
||||
if (store->andmask)
|
||||
return GL_FALSE;
|
||||
/* Drivers expect this to be clean to element 4...
|
||||
*/
|
||||
switch (VB->ClipPtr->size) {
|
||||
case 1:
|
||||
/* impossible */
|
||||
case 2:
|
||||
_mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
|
||||
/* fall-through */
|
||||
case 3:
|
||||
_mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
|
||||
/* fall-through */
|
||||
case 4:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Test userclip planes. This contributes to VB->ClipMask, so
|
||||
* is essentially required to be in this stage.
|
||||
*/
|
||||
if (ctx->Transform.ClipPlanesEnabled) {
|
||||
usercliptab[VB->ClipPtr->size]( ctx,
|
||||
VB->ClipPtr,
|
||||
store->clipmask,
|
||||
&store->ormask,
|
||||
&store->andmask );
|
||||
/* Cliptest and perspective divide. Clip functions must clear
|
||||
* the clipmask.
|
||||
*/
|
||||
store->ormask = 0;
|
||||
store->andmask = CLIP_ALL_BITS;
|
||||
|
||||
if (store->andmask)
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
VB->ClipAndMask = store->andmask;
|
||||
VB->ClipOrMask = store->ormask;
|
||||
VB->ClipMask = store->clipmask;
|
||||
|
||||
store->save_eyeptr = VB->EyePtr;
|
||||
store->save_clipptr = VB->ClipPtr;
|
||||
store->save_ndcptr = VB->NdcPtr;
|
||||
if (tnl->NeedNdcCoords) {
|
||||
VB->NdcPtr =
|
||||
_mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
|
||||
&store->proj,
|
||||
store->clipmask,
|
||||
&store->ormask,
|
||||
&store->andmask );
|
||||
}
|
||||
else {
|
||||
/* Replay the sideeffects.
|
||||
*/
|
||||
VB->EyePtr = store->save_eyeptr;
|
||||
VB->ClipPtr = store->save_clipptr;
|
||||
VB->NdcPtr = store->save_ndcptr;
|
||||
VB->ClipMask = store->clipmask;
|
||||
VB->ClipAndMask = store->andmask;
|
||||
VB->ClipOrMask = store->ormask;
|
||||
VB->NdcPtr = NULL;
|
||||
_mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
|
||||
NULL,
|
||||
store->clipmask,
|
||||
&store->ormask,
|
||||
&store->andmask );
|
||||
}
|
||||
|
||||
if (store->andmask)
|
||||
return GL_FALSE;
|
||||
|
||||
|
||||
/* Test userclip planes. This contributes to VB->ClipMask, so
|
||||
* is essentially required to be in this stage.
|
||||
*/
|
||||
if (ctx->Transform.ClipPlanesEnabled) {
|
||||
usercliptab[VB->ClipPtr->size]( ctx,
|
||||
VB->ClipPtr,
|
||||
store->clipmask,
|
||||
&store->ormask,
|
||||
&store->andmask );
|
||||
|
||||
if (store->andmask)
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
VB->ClipAndMask = store->andmask;
|
||||
VB->ClipOrMask = store->ormask;
|
||||
VB->ClipMask = store->clipmask;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void check_vertex( GLcontext *ctx, struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
stage->active = !ctx->VertexProgram._Enabled;
|
||||
}
|
||||
|
||||
static GLboolean init_vertex_stage( GLcontext *ctx,
|
||||
struct tnl_pipeline_stage *stage )
|
||||
{
|
||||
|
@ -289,10 +234,7 @@ static GLboolean init_vertex_stage( GLcontext *ctx,
|
|||
!store->proj.data)
|
||||
return GL_FALSE;
|
||||
|
||||
/* Now run the stage.
|
||||
*/
|
||||
stage->run = run_vertex_stage;
|
||||
return stage->run( ctx, stage );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void dtr( struct tnl_pipeline_stage *stage )
|
||||
|
@ -314,18 +256,9 @@ static void dtr( struct tnl_pipeline_stage *stage )
|
|||
const struct tnl_pipeline_stage _tnl_vertex_transform_stage =
|
||||
{
|
||||
"modelview/project/cliptest/divide",
|
||||
_NEW_PROGRAM, /* check_state: only care about vertex prog */
|
||||
_MESA_NEW_NEED_EYE_COORDS | /* run_state: when to invalidate / re-run */
|
||||
_NEW_MODELVIEW|
|
||||
_NEW_PROJECTION|
|
||||
_NEW_PROGRAM|
|
||||
_NEW_TRANSFORM,
|
||||
GL_TRUE, /* active */
|
||||
_TNL_BIT_POS, /* inputs */
|
||||
_TNL_BIT_POS, /* outputs */
|
||||
0, /* changed_inputs */
|
||||
NULL, /* private data */
|
||||
init_vertex_stage,
|
||||
dtr, /* destructor */
|
||||
check_vertex, /* check */
|
||||
init_vertex_stage /* run -- initially set to init */
|
||||
NULL,
|
||||
run_vertex_stage /* run -- initially set to init */
|
||||
};
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
* generated program with line/function references for each
|
||||
* instruction back into this file:
|
||||
*/
|
||||
#define DISASSEM 1
|
||||
#define DISASSEM 0
|
||||
|
||||
/* Use uregs to represent registers internally, translate to Mesa's
|
||||
* expected formats on emit.
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
*
|
||||
* Copyright (C) 2005 Tungsten Graphics All Rights Reserved.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* TUNGSTEN GRAPHICS 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _T_ARB_BUILD_H
|
||||
#define _T_ARB_BUILD_H
|
||||
|
||||
#include "mtypes.h"
|
||||
|
||||
/* Define to 1 to test fixed-function execution via vertex programs:
|
||||
*/
|
||||
#define TNL_FIXED_FUNCTION_PROGRAM 0
|
||||
|
||||
extern void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx );
|
||||
|
||||
#endif
|
|
@ -272,16 +272,9 @@ void _tnl_flush_vtx( GLcontext *ctx )
|
|||
if (ctx->NewState)
|
||||
_mesa_update_state( ctx );
|
||||
|
||||
if (tnl->pipeline.build_state_changes)
|
||||
_tnl_validate_pipeline( ctx );
|
||||
|
||||
_tnl_vb_bind_vtx( ctx );
|
||||
|
||||
/* Invalidate all stored data before and after run:
|
||||
*/
|
||||
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
|
||||
tnl->Driver.RunPipeline( ctx );
|
||||
tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue