diff options
author | Keith Whitwell <[email protected]> | 2000-12-26 05:09:27 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2000-12-26 05:09:27 +0000 |
commit | cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290 (patch) | |
tree | 45385bd755d8e3876c54b2b0113636f5ceb7976a /src/mesa/tnl/t_vb_vertex.c | |
parent | d1ff1f6798b003a820f5de9fad835ff352f31afe (diff) |
Major rework of tnl module
New array_cache module
Support 8 texture units in core mesa (now support 8 everywhere)
Rework core mesa statechange operations to avoid flushing on many
noop statechanges.
Diffstat (limited to 'src/mesa/tnl/t_vb_vertex.c')
-rw-r--r-- | src/mesa/tnl/t_vb_vertex.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c new file mode 100644 index 00000000000..7667d423a8b --- /dev/null +++ b/src/mesa/tnl/t_vb_vertex.c @@ -0,0 +1,311 @@ +/* $Id: t_vb_vertex.c,v 1.1 2000/12/26 05:09:33 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul 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 + * 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. + * + * Author: + * Keith Whitwell <[email protected]> + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + + + +struct vertex_stage_data { + GLvector4f eye; + GLvector4f clip; + GLvector4f proj; + 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_projptr; +}; + +#define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->private) + + + + +/* This function implements cliptesting for user-defined clip planes. + * The clipping of primitives to these planes is implemented in + * t_render_clip.h. + */ +#define USER_CLIPTEST(NAME, SZ) \ +static void NAME( GLcontext *ctx, \ + GLvector4f *clip, \ + GLubyte *clipmask, \ + GLubyte *clipormask, \ + GLubyte *clipandmask ) \ +{ \ + GLuint p; \ + \ + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) \ + if (ctx->Transform.ClipEnabled[p]) { \ + GLuint nr, i; \ + const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \ + const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \ + const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; \ + const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; \ + GLfloat *coord = (GLfloat *)clip->data; \ + GLuint stride = clip->stride; \ + GLuint count = clip->count; \ + \ + for (nr = 0, i = 0 ; i < count ; i++) { \ + GLfloat dp = coord[0] * a + coord[1] * b; \ + if (SZ > 2) dp += coord[2] * c; \ + if (SZ > 3) dp += coord[3] * d; else dp += d; \ + \ + if (dp < 0) { \ + nr++; \ + clipmask[i] |= CLIP_USER_BIT; \ + } \ + \ + STRIDE_F(coord, stride); \ + } \ + \ + if (nr > 0) { \ + *clipormask |= CLIP_USER_BIT; \ + if (nr == count) { \ + *clipandmask |= CLIP_USER_BIT; \ + return; \ + } \ + } \ + } \ +} + + +USER_CLIPTEST(userclip2, 2) +USER_CLIPTEST(userclip3, 3) +USER_CLIPTEST(userclip4, 4) + +static void (*(usercliptab[5]))( GLcontext *, + GLvector4f *, GLubyte *, + GLubyte *, GLubyte * ) = +{ + 0, + 0, + userclip2, + userclip3, + userclip4 +}; + + + +static GLboolean run_vertex_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_stage_data *store = (struct vertex_stage_data *)stage->private; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (stage->changed_inputs) + { +/* VB->ObjPtr->size = 4; */ + + if (ctx->_NeedEyeCoords) { + /* Seperate modelview and project transformations: + */ + if (ctx->ModelView.type == MATRIX_IDENTITY) + VB->EyePtr = VB->ObjPtr; + else + VB->EyePtr = TransformRaw( &store->eye, &ctx->ModelView, + VB->ObjPtr); + + if (ctx->ProjectionMatrix.type == MATRIX_IDENTITY) + VB->ClipPtr = VB->EyePtr; + else + VB->ClipPtr = TransformRaw( &store->clip, &ctx->ProjectionMatrix, + VB->EyePtr ); + } + else + { + /* Combined modelviewproject transform: + */ + if (ctx->_ModelProjectMatrix.type == MATRIX_IDENTITY) + VB->ClipPtr = VB->ObjPtr; + else + 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; + + VB->ProjectedClipPtr = + gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &store->proj, + 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._AnyClip) { + usercliptab[VB->ClipPtr->size]( ctx, + VB->ClipPtr, + store->clipmask, + &store->ormask, + &store->andmask ); + + if (store->andmask) + return GL_FALSE; + } + + VB->ClipOrMask = store->ormask; + VB->ClipMask = store->clipmask; + + if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ)) + VB->importable_data |= VERT_CLIP; + + /* Drivers expect this to be size 4... + */ + if (VB->ProjectedClipPtr->size < 4) { + ASSERT(VB->ProjectedClipPtr == VB->ClipPtr); + if (VB->ProjectedClipPtr->flags & VEC_NOT_WRITEABLE) { + ASSERT(VB->ProjectedClipPtr == VB->ObjPtr); + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + VB->ProjectedClipPtr = VB->ClipPtr = VB->ObjPtr; + } + if (VB->ClipPtr->size == 2) + gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); + gl_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); + VB->ClipPtr->size = 4; + } + + store->save_eyeptr = VB->EyePtr; + store->save_clipptr = VB->ClipPtr; + store->save_projptr = VB->ProjectedClipPtr; + } + else { + /* Replay the sideeffects. + */ + VB->EyePtr = store->save_eyeptr; + VB->ClipPtr = store->save_clipptr; + VB->ProjectedClipPtr = store->save_projptr; + VB->ClipMask = store->clipmask; + VB->ClipOrMask = store->ormask; + if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ)) + VB->importable_data |= VERT_CLIP; + if (store->andmask) + return GL_FALSE; + } + + return GL_TRUE; +} + + +static void check_vertex( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + (void) ctx; + (void) stage; +} + +static GLboolean init_vertex_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct vertex_stage_data *store; + GLuint size = VB->Size; + + stage->private = CALLOC(sizeof(*store)); + store = VERTEX_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + gl_vector4f_alloc( &store->eye, 0, size, 32 ); + gl_vector4f_alloc( &store->clip, 0, size, 32 ); + gl_vector4f_alloc( &store->proj, 0, size, 32 ); + + store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 ); + + if (!store->clipmask || + !store->eye.data || + !store->clip.data || + !store->proj.data) + return GL_FALSE; + + /* Now run the stage. + */ + stage->run = run_vertex_stage; + return stage->run( ctx, stage ); +} + +static void dtr( struct gl_pipeline_stage *stage ) +{ + struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage); + + if (store) { + gl_vector4f_free( &store->eye ); + gl_vector4f_free( &store->clip ); + gl_vector4f_free( &store->proj ); + ALIGN_FREE( store->clipmask ); + FREE(store); + stage->private = 0; + stage->run = init_vertex_stage; + } +} + + +const struct gl_pipeline_stage _tnl_vertex_transform_stage = +{ + "modelview/project/cliptest/divide", + 0, /* re-check -- always on */ + _NEW_MODELVIEW| + _NEW_PROJECTION| + _NEW_TRANSFORM, /* re-run */ + GL_TRUE, /* active */ + VERT_OBJ, /* inputs */ + VERT_EYE|VERT_CLIP, /* outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + check_vertex, /* check */ + init_vertex_stage /* run -- initially set to init */ +}; + + |