summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c')
-rw-r--r--xc/lib/GL/mesa/src/drv/tdfx/fxfastpath.c405
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;
+}
+