diff options
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c')
-rw-r--r-- | xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c b/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c new file mode 100644 index 000000000..f1c669e9a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c @@ -0,0 +1,405 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c,v 1.1 2000/09/24 13:51:15 alanh Exp $ */ +/* + * 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. + * + * Thank you for your contribution, David! + * + * Please make note of the above copyright/license statement. If you + * contributed code or bug fixes to this code under the previous (GNU + * Library) license and object to the new license, your code will be + * removed at your request. Please see the Mesa docs/COPYRIGHT file + * for more information. + * + * Additional Mesa/3Dfx driver developers: + * Daryll Strauss <daryll@precisioninsight.com> + * Keith Whitwell <keith@precisioninsight.com> + * + * See fxapi.h for more revision/author details. + */ + + +#include "types.h" +#include "cva.h" +#include "mmath.h" +#include "fxdrv.h" +#include "fxtexman.h" +#include "vertices.h" +#ifdef __i386__ +#include "X86/common_x86asm.h" +#endif + + +#if 0 && defined(__i386__) +#define NEGATIVE(f) ((*(int *)&f) < 0) +#define DIFFERENT_SIGNS(a,b) (((*(int *)&a)^(*(int *)&b)) < 0) +#else +#define NEGATIVE(f) (f < 0) +#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) +#endif + +#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) + + +#define CLIP(sgn,v,PLANE) \ +if (mask & PLANE) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]].f; \ + GLfloat dpJ = (sgn J[v]) + J[CLIP_WCOORD]; \ + \ + inlist[0] = vlist1; \ + for (i = n = 0 ; i < nr ; i++) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i].f; \ + GLfloat dpI = (sgn I[v]) + I[CLIP_WCOORD]; \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + GLuint j; \ + \ + clipmask[next_vert] = 0; \ + outdata[n++] = next_vert++; \ + \ + for (j = 0 ; j < SIZE ; j += 2) { \ + O[j] = LINTERP(t, I[j], J[j]); \ + O[j+1] = LINTERP(t, I[j+1], J[j+1]); \ + } \ + } \ + \ + clipmask[elt_i] |= PLANE; /* don't set up */ \ + \ + if (!NEGATIVE(dpI)) { \ + outdata[n++] = elt_i; \ + clipmask[elt_i] &= ~PLANE; /* set up after all */ \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (n < 3) return; \ +} + +#define LINE_CLIP(x,y,z,w,PLANE) \ +if (mask & PLANE) { \ + GLfloat dpI = DOT4V(I,x,y,z,w); \ + GLfloat dpJ = DOT4V(J,x,y,z,w); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + GLuint j; \ + \ + for (j = 0 ; j < SIZE ; j += 2) { \ + O[j] = LINTERP(t, I[j], J[j]); \ + O[j+1] = LINTERP(t, I[j+1], J[j+1]); \ + } \ + \ + clipmask[next_vert] = 0; \ + \ + if (NEGATIVE(dpI)) { \ + clipmask[elts[0]] |= PLANE; \ + I = O; elts[0] = next_vert++; \ + } else { \ + clipmask[elts[1]] |= PLANE; \ + J = O; elts[1] = next_vert++; \ + } \ + } \ + else if (NEGATIVE(dpI)) \ + return; \ +} + + +#define CLIP_POINT( e ) \ + if (mask[e]) \ + *out++ = e + +#define CLIP_LINE( e1, e0 ) \ +do { \ + GLubyte ormask = mask[e0] | mask[e1]; \ + out[0] = e1; \ + out[1] = e0; \ + out+=2; \ + if (ormask) { \ + out-=2; \ + if (!(mask[e0] & mask[e1])) { \ + TAG(fx_line_clip)( &out, verts, mask, &next_vert, ormask); \ + } \ + } \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask; \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + out += 3; \ + ormask = mask[e2] | mask[e1] | mask[e0]; \ + if (ormask) { \ + out -= 3; \ + if ( !(mask[e2] & mask[e1] & mask[e0])) { \ + TAG(fx_tri_clip)( &out, verts, mask, &next_vert, ormask ); \ + } \ + } \ +} while (0) + +#if defined(FX_V2) || defined(DRIVERTS) + +#define VARS_XYZ \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + GLfloat vtx = mat[MAT_TX]; \ + GLfloat vty = mat[MAT_TY]; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZ \ + f[XCOORD] = f[0] * oow * vsx + vtx; \ + f[YCOORD] = f[1] * oow * vsy + vty; \ + f[ZCOORD] = f[2] * oow * vsz + vtz; + +#else +#if defined(HAVE_FAST_MATH) + +#define VARS_XYZ \ + GLfloat vsx = mat[MAT_SX]; \ + GLfloat vsy = mat[MAT_SY]; \ + GLfloat vsz = mat[MAT_SZ]; \ + const GLfloat snapper = (3L << 18); \ + GLfloat vtx = mat[MAT_TX] + snapper; \ + GLfloat vty = mat[MAT_TY] + snapper; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZ \ + f[XCOORD] = f[0] * oow * vsx + vtx; \ + f[XCOORD] -= snapper; \ + f[YCOORD] = f[1] * oow * vsy + vty; \ + f[YCOORD] -= snapper; \ + f[ZCOORD] = f[2] * oow * vsz + vtz; + +#else + +#define VARS_XYZ \ + GLfloat vsx = mat[MAT_SX] * 16.0f; \ + GLfloat vsy = mat[MAT_SY] * 16.0f; \ + GLfloat vsz = mat[MAT_SZ]; \ + GLfloat vtx = mat[MAT_TX] * 16.0f; \ + GLfloat vty = mat[MAT_TY] * 16.0f; \ + GLfloat vtz = mat[MAT_TZ]; + +#define DO_SETUP_XYZ \ + f[XCOORD] = ((int)(f[0]*oow*vsx+vtx)) * (1.0f/16.0f); \ + f[YCOORD] = ((int)(f[1]*oow*vsy+vty)) * (1.0f/16.0f); \ + f[ZCOORD] = f[2]*oow*vsz + vtz; + + +#endif +#endif + + + +struct fx_fast_tab +{ + void (*build_vertices) (struct vertex_buffer * VB, GLuint do_clip); + + void (*clip[GL_POLYGON + 1]) (struct vertex_buffer * VB, + GLuint start, GLuint count, GLuint parity); + + void (*project_clipped_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, + GLuint stride, const GLubyte * mask); + + void (*project_vertices) (GLfloat * first, + GLfloat * last, + const GLfloat * mat, GLuint stride); +}; + +/* Pack either rgba or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_R CLIP_RCOORD +#define CLIP_G CLIP_GCOORD +#define CLIP_B CLIP_BCOORD +#define CLIP_A CLIP_ACOORD +#define CLIP_S0 4 +#define CLIP_T0 5 +#define CLIP_S1 6 +#define CLIP_T1 7 + +#define SIZE 4 +#define TYPE (0) +#define TAG(x) x +#include "fxfasttmp.h" + +#define SIZE 8 +#define TYPE (SETUP_RGBA) +#define TAG(x) x##_RGBA +#include "fxfasttmp.h" + +#define SIZE 6 +#define TYPE (SETUP_TMU0) +#define TAG(x) x##_TMU0 +#include "fxfasttmp.h" + +#define SIZE 8 +#define TYPE (SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_TMU0_TMU1 +#include "fxfasttmp.h" + +#undef CLIP_S1 +#undef CLIP_T1 +#define CLIP_S1 4 +#define CLIP_T1 5 + +#define SIZE 6 +#define TYPE (SETUP_TMU1) +#define TAG(x) x##_TMU1 +#include "fxfasttmp.h" + +/* These three need to use a full 64 byte clip-space vertex. + */ +#undef CLIP_S0 +#undef CLIP_T0 +#undef CLIP_S1 +#undef CLIP_T1 + +#define CLIP_S0 8 +#define CLIP_T0 9 +#define CLIP_S1 10 +#define CLIP_T1 11 + +#define SIZE 10 +#define TYPE (SETUP_RGBA|SETUP_TMU0) +#define TAG(x) x##_RGBA_TMU0 +#include "fxfasttmp.h" + +#define SIZE 12 +#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU0_TMU1 +#include "fxfasttmp.h" + +#undef CLIP_S1 +#undef CLIP_T1 +#define CLIP_S1 8 +#define CLIP_T1 9 + +#define SIZE 10 +#define TYPE (SETUP_RGBA|SETUP_TMU1) +#define TAG(x) x##_RGBA_TMU1 +#include "fxfasttmp.h" + +static struct fx_fast_tab fxFastTab[0x8]; + +void +fxDDFastPathInit() +{ + fx_init_fastpath(&fxFastTab[0]); + fx_init_fastpath_RGBA(&fxFastTab[SETUP_RGBA]); + fx_init_fastpath_TMU0(&fxFastTab[SETUP_TMU0]); + fx_init_fastpath_TMU1(&fxFastTab[SETUP_TMU1]); + fx_init_fastpath_RGBA_TMU0(&fxFastTab[SETUP_RGBA | SETUP_TMU0]); + fx_init_fastpath_RGBA_TMU1(&fxFastTab[SETUP_RGBA | SETUP_TMU1]); + fx_init_fastpath_TMU0_TMU1(&fxFastTab[SETUP_TMU0 | SETUP_TMU1]); + fx_init_fastpath_RGBA_TMU0_TMU1(&fxFastTab[SETUP_RGBA | SETUP_TMU0 | + SETUP_TMU1]); +} + + + +void +fxDDFastPath(struct vertex_buffer *VB) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + struct tfxMesaContext *fxMesa = FX_CONTEXT(ctx); + struct fx_fast_tab *tab = &fxFastTab[fxMesa->setupindex & 0x7]; + GLuint do_clip = 1; + struct tfxMesaVertexBuffer *fxVB = FX_DRIVER_DATA(VB); +#ifdef DRIVERTS + GLfloat tx, ty; +#endif + + fxVertex *first; + GLfloat *mat = ctx->Viewport.WindowMap.m; + + gl_prepare_arrays_cva(VB); /* still need this */ + + if (VB->EltPtr->count * 12 > fxVB->size) { + fxDDResizeVB(VB, VB->EltPtr->count * 12); + do_clip = 1; + } + + tab->build_vertices(VB, do_clip); /* object->clip space */ + + first = FX_DRIVER_DATA(VB)->verts; + +#ifdef DRIVERTS + tx = mat[MAT_TX]; + ty = mat[MAT_TY]; + mat[MAT_TX] = tx + fxMesa->x_offset; + mat[MAT_TY] = ty + fxMesa->y_delta; +#endif + + if (VB->ClipOrMask) { + if (!VB->ClipAndMask) { + GLubyte tmp = VB->ClipOrMask; + + tab->clip[prim] (VB, 0, VB->EltPtr->count, 0); /* clip */ + + tab->project_clipped_vertices(fxVB->verts->f, + fxVB->last_vert->f, + mat, 16 * 4, VB->ClipMask); + + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(FX_DRIVER_DATA(VB)->clipped_elements); + + VB->ClipOrMask = 0; + fxDDRenderElementsDirect(VB); /* render using new list */ + VB->ClipOrMask = tmp; + } + } + else { + tab->project_vertices(fxVB->verts->f, fxVB->last_vert->f, mat, + 16 * 4); + + fxDDRenderElementsDirect(VB); /* render using orig list */ + } + +#ifdef DRIVERTS + mat[MAT_TX] = tx; + mat[MAT_TY] = ty; +#endif + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->pipeline_valid = 0; +} + |