/* * Mesa 3-D graphics library * Version: 3.3 * * 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. * * * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the * terms stated above. * * Author: * Keith Whitwell */ /* fxvsetup.c - 3Dfx VooDoo vertices setup functions */ #ifdef HAVE_CONFIG_H #include "conf.h" #endif #if defined(FX) #include "fxdrv.h" #include "mmath.h" #include "swrast_setup/swrast_setup.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" void fxPrintSetupFlags( const char *msg, GLuint flags ) { fprintf(stderr, "%s: %d %s%s%s%s%s\n", msg, flags, (flags & SETUP_XYZW) ? " xyzw," : "", (flags & SETUP_SNAP) ? " snap," : "", (flags & SETUP_RGBA) ? " rgba," : "", (flags & SETUP_TMU0) ? " tmu0," : "", (flags & SETUP_TMU1) ? " tmu1," : ""); } static void project_texcoords( fxVertex *v, struct vertex_buffer *VB, GLuint tmu_nr, GLuint tc_nr, GLuint start, GLuint count ) { GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]); GLvector4f *vec = VB->TexCoordPtr[tc_nr]; GLuint i; GLuint stride = vec->stride; GLfloat *data = VEC_ELT(vec, GLfloat, start); for (i = start ; i < count ; i++, STRIDE_F(data, stride), v++) { tmu->oow = v->v.oow * data[3]; tmu = (GrTmuVertex *)((char *)tmu + sizeof(fxVertex)); } } static void copy_w( fxVertex *v, struct vertex_buffer *VB, GLuint tmu_nr, GLuint start, GLuint count ) { GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]); GLuint i; for (i = start ; i < count ; i++, v++) { tmu->oow = v->v.oow; tmu = (GrTmuVertex *)((char *)tmu + sizeof(fxVertex)); } } /* need to compute W values for fogging purposes */ static void fx_fake_fog_w( GLcontext *ctx, fxVertex *verts, struct vertex_buffer *VB, GLuint start, GLuint end ) { const GLfloat m10 = ctx->ProjectionMatrix.m[10]; const GLfloat m14 = ctx->ProjectionMatrix.m[14]; GLfloat (*clip)[4] = VB->ClipPtr->data; GLubyte *clipmask = VB->ClipMask; GLuint i; for ( i = start ; i < end ; i++) { if (clipmask[i] == 0) { verts[i].v.oow = - m10 / (clip[i][2] - m14); /* -1/zEye */ } } } static tfxSetupFunc setupfuncs[MAX_SETUP]; #define IND (SETUP_XYZW) #define INPUTS (VERT_CLIP) #define NAME fxsetupXYZW #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA) #define NAME fxsetupXYZWRGBA #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_TMU0) #define INPUTS (VERT_CLIP|VERT_TEX_ANY) #define NAME fxsetupXYZWT0 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_TMU1) #define INPUTS (VERT_CLIP|VERT_TEX_ANY) #define NAME fxsetupXYZWT1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0) #define INPUTS (VERT_CLIP|VERT_TEX_ANY) #define NAME fxsetupXYZWT0T1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_TMU0|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupXYZWRGBAT0 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupXYZWRGBAT1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupXYZWRGBAT0T1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP) #define INPUTS (VERT_CLIP) #define NAME fxsetupXYZW_SNAP #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA) #define NAME fxsetupXYZW_SNAP_RGBA #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0) #define INPUTS (VERT_CLIP|VERT_TEX_ANY) #define NAME fxsetupXYZW_SNAP_T0 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1) #define INPUTS (VERT_CLIP|VERT_TEX_ANY) #define NAME fxsetupXYZW_SNAP_T1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0) #define INPUTS (VERT_CLIP|VERT_TEX_ANY) #define NAME fxsetupXYZW_SNAP_T0T1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupXYZW_SNAP_RGBAT0 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupXYZW_SNAP_RGBAT1 #include "fxvbtmp.h" #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) #define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupXYZW_SNAP_RGBAT0T1 #include "fxvbtmp.h" #define IND (SETUP_RGBA) #define INPUTS (VERT_RGBA) #define NAME fxsetupRGBA #include "fxvbtmp.h" #define IND (SETUP_TMU0) #define INPUTS (VERT_TEX_ANY) #define NAME fxsetupT0 #include "fxvbtmp.h" #define IND (SETUP_TMU1) #define INPUTS (VERT_TEX_ANY) #define NAME fxsetupT1 #include "fxvbtmp.h" #define IND (SETUP_TMU1|SETUP_TMU0) #define INPUTS (VERT_TEX_ANY) #define NAME fxsetupT0T1 #include "fxvbtmp.h" #define IND (SETUP_TMU0|SETUP_RGBA) #define INPUTS (VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupRGBAT0 #include "fxvbtmp.h" #define IND (SETUP_TMU1|SETUP_RGBA) #define INPUTS (VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupRGBAT1 #include "fxvbtmp.h" #define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA) #define INPUTS (VERT_RGBA|VERT_TEX_ANY) #define NAME fxsetupRGBAT0T1 #include "fxvbtmp.h" static void fxsetup_invalid( GLcontext *ctx, GLuint start, GLuint end ) { fprintf(stderr, "fxMesa: invalid setup function\n"); (void) (ctx && start && end); } void fxDDSetupInit( void ) { GLuint i; for (i = 0 ; i < Elements(setupfuncs) ; i++) setupfuncs[i] = fxsetup_invalid; setupfuncs[SETUP_XYZW] = fxsetupXYZW; setupfuncs[SETUP_XYZW|SETUP_RGBA] = fxsetupXYZWRGBA; setupfuncs[SETUP_XYZW|SETUP_TMU0] = fxsetupXYZWT0; setupfuncs[SETUP_XYZW|SETUP_TMU1] = fxsetupXYZWT1; setupfuncs[SETUP_XYZW|SETUP_TMU0|SETUP_RGBA] = fxsetupXYZWRGBAT0; setupfuncs[SETUP_XYZW|SETUP_TMU1|SETUP_RGBA] = fxsetupXYZWRGBAT1; setupfuncs[SETUP_XYZW|SETUP_TMU1|SETUP_TMU0] = fxsetupXYZWT0T1; setupfuncs[SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA] = fxsetupXYZWRGBAT0T1; setupfuncs[SETUP_XYZW|SETUP_SNAP] = fxsetupXYZW_SNAP; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_RGBA] = fxsetupXYZW_SNAP_RGBA; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU0] = fxsetupXYZW_SNAP_T0; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1] = fxsetupXYZW_SNAP_T1; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA] = fxsetupXYZW_SNAP_RGBAT0; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA] = fxsetupXYZW_SNAP_RGBAT1; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0] = fxsetupXYZW_SNAP_T0T1; setupfuncs[SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA] = fxsetupXYZW_SNAP_RGBAT0T1; setupfuncs[SETUP_RGBA] = fxsetupRGBA; setupfuncs[SETUP_TMU0] = fxsetupT0; setupfuncs[SETUP_TMU1] = fxsetupT1; setupfuncs[SETUP_TMU1|SETUP_TMU0] = fxsetupT0T1; setupfuncs[SETUP_TMU0|SETUP_RGBA] = fxsetupRGBAT0; setupfuncs[SETUP_TMU1|SETUP_RGBA] = fxsetupRGBAT1; setupfuncs[SETUP_TMU1|SETUP_TMU0|SETUP_RGBA] = fxsetupRGBAT0T1; } void fx_validate_BuildProjVerts(GLcontext *ctx, GLuint start, GLuint count, GLuint newinputs ) { fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; if (!fxMesa->is_in_hardware) ctx->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices; else { GLuint setupindex = SETUP_XYZW; fxMesa->tmu_source[0] = 0; fxMesa->tmu_source[1] = 1; fxMesa->tex_dest[0] = SETUP_TMU0; fxMesa->tex_dest[1] = SETUP_TMU1; /* For flat and two-side-lit triangles, colors will always be added * to vertices in the triangle functions. Vertices will *always* * have rbga values, but only sometimes will they come from here. */ if ((ctx->_TriangleCaps & (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE)) == 0) setupindex |= SETUP_RGBA; if (ctx->Texture._ReallyEnabled & TEXTURE0_2D) setupindex |= SETUP_TMU0; if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) { if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) == 0) { fxMesa->tmu_source[0] = 1; fxMesa->tex_dest[0] = SETUP_TMU1; fxMesa->tmu_source[1] = 0; fxMesa->tex_dest[1] = SETUP_TMU0; setupindex |= SETUP_TMU0; } else { setupindex |= SETUP_TMU1; } } if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_PIPELINE|VERBOSE_STATE)) fxPrintSetupFlags("fxmesa: vertex setup function", setupindex); fxMesa->setupindex = setupindex; ctx->Driver.BuildProjectedVertices = fx_BuildProjVerts; } ctx->Driver.BuildProjectedVertices( ctx, start, count, newinputs ); } void fx_BuildProjVerts( GLcontext *ctx, GLuint start, GLuint count, GLuint newinputs ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; if (newinputs == ~0) { /* build interpolated vertices */ setupfuncs[fxMesa->setupindex]( ctx, start, count ); } else { GLuint ind = fxMesa->setup_gone; fxMesa->setup_gone = 0; if (newinputs & VERT_CLIP) ind = fxMesa->setupindex; /* clipmask has potentially changed */ else { if (newinputs & VERT_TEX0) ind |= fxMesa->tex_dest[0]; if (newinputs & VERT_TEX1) ind |= fxMesa->tex_dest[1]; if (newinputs & VERT_RGBA) ind |= SETUP_RGBA; ind &= fxMesa->setupindex; } if (ind) { if (fxMesa->new_state) fxSetupFXUnits( ctx ); /* why? */ if (VB->importable_data & newinputs) VB->import_data( ctx, VB->importable_data & newinputs, VEC_BAD_STRIDE ); setupfuncs[ind]( ctx, start, count ); } } } void fxAllocVB( GLcontext *ctx ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); fxMesa->verts = ALIGN_MALLOC( tnl->vb.Size * sizeof(fxMesa->verts[0]), 32 ); } void fxFreeVB( GLcontext *ctx ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); if (fxMesa->verts) ALIGN_FREE( fxMesa->verts ); fxMesa->verts = 0; } #else /* * Need this to provide at least one external definition. */ extern int gl_fx_dummy_function_vsetup(void); int gl_fx_dummy_function_vsetup(void) { return 0; } #endif /* FX */