source: trunk/src/opengl/mesa/3dfx/fxfastpath.c

Last change on this file was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 15.1 KB
Line 
1/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
28 * terms stated above.
29 *
30 * Thank you for your contribution, David!
31 *
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
37 *
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
41 *
42 * See fxapi.h for more revision/author details.
43 */
44
45
46#ifdef HAVE_CONFIG_H
47#include "conf.h"
48#endif
49
50
51#if defined(FX)
52
53#include "types.h"
54#include "cva.h"
55#include "mmath.h"
56#include "fxdrv.h"
57#include "vertices.h"
58#include "common_x86asm.h"
59
60
61#if 0 && defined(__i386__)
62#define NEGATIVE(f) ((*(int *)&f) < 0)
63#define DIFFERENT_SIGNS(a,b) (((*(int *)&a)^(*(int *)&b)) < 0)
64#else
65#define NEGATIVE(f) (f < 0)
66#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
67#endif
68
69#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
70
71
72#define CLIP(sgn,v,PLANE) \
73if (mask & PLANE) { \
74 GLuint *indata = inlist[in]; \
75 GLuint *outdata = inlist[in ^= 1]; \
76 GLuint nr = n; \
77 GLfloat *J = verts[indata[nr-1]].f; \
78 GLfloat dpJ = (sgn J[v]) + J[CLIP_WCOORD]; \
79 \
80 inlist[0] = vlist1; \
81 for (i = n = 0 ; i < nr ; i++) { \
82 GLuint elt_i = indata[i]; \
83 GLfloat *I = verts[elt_i].f; \
84 GLfloat dpI = (sgn I[v]) + I[CLIP_WCOORD]; \
85 \
86 if (DIFFERENT_SIGNS(dpI, dpJ)) { \
87 GLfloat *O = verts[next_vert].f; \
88 GLfloat t = dpI / (dpI - dpJ); \
89 GLuint j; \
90 \
91 clipmask[next_vert] = 0; \
92 outdata[n++] = next_vert++; \
93 \
94 for (j = 0 ; j < SIZE ; j += 2) { \
95 O[j] = LINTERP(t, I[j], J[j]); \
96 O[j+1] = LINTERP(t, I[j+1], J[j+1]); \
97 } \
98 } \
99 \
100 clipmask[elt_i] |= PLANE; /* don't set up */ \
101 \
102 if (!NEGATIVE(dpI)) { \
103 outdata[n++] = elt_i; \
104 clipmask[elt_i] &= ~PLANE; /* set up after all */ \
105 } \
106 \
107 J = I; \
108 dpJ = dpI; \
109 } \
110 \
111 if (n < 3) return; \
112}
113
114#define LINE_CLIP(x,y,z,w,PLANE) \
115if (mask & PLANE) { \
116 GLfloat dpI = DOT4V(I,x,y,z,w); \
117 GLfloat dpJ = DOT4V(J,x,y,z,w); \
118 \
119 if (DIFFERENT_SIGNS(dpI, dpJ)) { \
120 GLfloat *O = verts[next_vert].f; \
121 GLfloat t = dpI / (dpI - dpJ); \
122 GLuint j; \
123 \
124 for (j = 0 ; j < SIZE ; j += 2) { \
125 O[j] = LINTERP(t, I[j], J[j]); \
126 O[j+1] = LINTERP(t, I[j+1], J[j+1]); \
127 } \
128 \
129 clipmask[next_vert] = 0; \
130 \
131 if (NEGATIVE(dpI)) { \
132 clipmask[elts[0]] |= PLANE; \
133 I = O; elts[0] = next_vert++; \
134 } else { \
135 clipmask[elts[1]] |= PLANE; \
136 J = O; elts[1] = next_vert++; \
137 } \
138 } \
139 else if (NEGATIVE(dpI)) \
140 return; \
141}
142
143
144#define CLIP_POINT( e ) \
145 if (mask[e]) \
146 *out++ = e
147
148#define CLIP_LINE( e1, e0 ) \
149do { \
150 GLubyte ormask = mask[e0] | mask[e1]; \
151 out[0] = e1; \
152 out[1] = e0; \
153 out+=2; \
154 if (ormask) { \
155 out-=2; \
156 if (!(mask[e0] & mask[e1])) { \
157 TAG(fx_line_clip)( &out, verts, mask, &next_vert, ormask); \
158 } \
159 } \
160} while (0)
161
162#define CLIP_TRIANGLE( e2, e1, e0 ) \
163do { \
164 GLubyte ormask; \
165 out[0] = e2; \
166 out[1] = e1; \
167 out[2] = e0; \
168 out += 3; \
169 ormask = mask[e2] | mask[e1] | mask[e0]; \
170 if (ormask) { \
171 out -= 3; \
172 if ( !(mask[e2] & mask[e1] & mask[e0])) { \
173 TAG(fx_tri_clip)( &out, verts, mask, &next_vert, ormask ); \
174 } \
175 } \
176} while (0)
177
178#if defined(FX_V2) || defined(DRIVERTS)
179
180#define VARS_XYZ \
181 GLfloat vsx = mat[MAT_SX]; \
182 GLfloat vsy = mat[MAT_SY]; \
183 GLfloat vsz = mat[MAT_SZ]; \
184 GLfloat vtx = mat[MAT_TX]; \
185 GLfloat vty = mat[MAT_TY]; \
186 GLfloat vtz = mat[MAT_TZ];
187
188#define DO_SETUP_XYZ \
189 f[XCOORD] = f[0] * oow * vsx + vtx; \
190 f[YCOORD] = f[1] * oow * vsy + vty; \
191 f[ZCOORD] = f[2] * oow * vsz + vtz;
192
193#else
194#if defined(HAVE_FAST_MATH)
195
196#define VARS_XYZ \
197 GLfloat vsx = mat[MAT_SX]; \
198 GLfloat vsy = mat[MAT_SY]; \
199 GLfloat vsz = mat[MAT_SZ]; \
200 const GLfloat snapper = (3L << 18); \
201 GLfloat vtx = mat[MAT_TX] + snapper; \
202 GLfloat vty = mat[MAT_TY] + snapper; \
203 GLfloat vtz = mat[MAT_TZ];
204
205#define DO_SETUP_XYZ \
206 f[XCOORD] = f[0] * oow * vsx + vtx; \
207 f[XCOORD] -= snapper; \
208 f[YCOORD] = f[1] * oow * vsy + vty; \
209 f[YCOORD] -= snapper; \
210 f[ZCOORD] = f[2] * oow * vsz + vtz;
211
212#else
213
214#define VARS_XYZ \
215 GLfloat vsx = mat[MAT_SX] * 16.0f; \
216 GLfloat vsy = mat[MAT_SY] * 16.0f; \
217 GLfloat vsz = mat[MAT_SZ]; \
218 GLfloat vtx = mat[MAT_TX] * 16.0f; \
219 GLfloat vty = mat[MAT_TY] * 16.0f; \
220 GLfloat vtz = mat[MAT_TZ];
221
222#define DO_SETUP_XYZ \
223 f[XCOORD] = ((int)(f[0]*oow*vsx+vtx)) * (1.0f/16.0f); \
224 f[YCOORD] = ((int)(f[1]*oow*vsy+vty)) * (1.0f/16.0f); \
225 f[ZCOORD] = f[2]*oow*vsz + vtz;
226
227
228#endif
229#endif
230
231
232
233struct fx_fast_tab
234{
235 void (*build_vertices)( struct vertex_buffer *VB, GLuint do_clip );
236
237 void (*clip[GL_POLYGON+1])( struct vertex_buffer *VB,
238 GLuint start,
239 GLuint count,
240 GLuint parity );
241
242 void (*project_clipped_vertices)( GLfloat *first,
243 GLfloat *last,
244 const GLfloat *mat,
245 GLuint stride,
246 const GLubyte *mask );
247
248 void (*project_vertices)( GLfloat *first,
249 GLfloat *last,
250 const GLfloat *mat,
251 GLuint stride );
252};
253
254/* Pack either rgba or texture into the remaining half of a 32 byte vertex.
255 */
256#define CLIP_R CLIP_RCOORD
257#define CLIP_G CLIP_GCOORD
258#define CLIP_B CLIP_BCOORD
259#define CLIP_A CLIP_ACOORD
260#define CLIP_S0 4
261#define CLIP_T0 5
262#define CLIP_S1 6
263#define CLIP_T1 7
264
265#define SIZE 4
266#define TYPE (0)
267#define TAG(x) x
268#include "fxfasttmp.h"
269
270#define SIZE 8
271#define TYPE (SETUP_RGBA)
272#define TAG(x) x##_RGBA
273#include "fxfasttmp.h"
274
275#define SIZE 6
276#define TYPE (SETUP_TMU0)
277#define TAG(x) x##_TMU0
278#include "fxfasttmp.h"
279
280#define SIZE 8
281#define TYPE (SETUP_TMU0|SETUP_TMU1)
282#define TAG(x) x##_TMU0_TMU1
283#include "fxfasttmp.h"
284
285#undef CLIP_S1
286#undef CLIP_T1
287#define CLIP_S1 4
288#define CLIP_T1 5
289
290#define SIZE 6
291#define TYPE (SETUP_TMU1)
292#define TAG(x) x##_TMU1
293#include "fxfasttmp.h"
294
295/* These three need to use a full 64 byte clip-space vertex.
296 */
297#undef CLIP_S0
298#undef CLIP_T0
299#undef CLIP_S1
300#undef CLIP_T1
301
302#define CLIP_S0 8
303#define CLIP_T0 9
304#define CLIP_S1 10
305#define CLIP_T1 11
306
307#define SIZE 10
308#define TYPE (SETUP_RGBA|SETUP_TMU0)
309#define TAG(x) x##_RGBA_TMU0
310#include "fxfasttmp.h"
311
312#define SIZE 12
313#define TYPE (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
314#define TAG(x) x##_RGBA_TMU0_TMU1
315#include "fxfasttmp.h"
316
317#undef CLIP_S1
318#undef CLIP_T1
319#define CLIP_S1 8
320#define CLIP_T1 9
321
322#define SIZE 10
323#define TYPE (SETUP_RGBA|SETUP_TMU1)
324#define TAG(x) x##_RGBA_TMU1
325#include "fxfasttmp.h"
326
327static struct fx_fast_tab fxFastTab[0x8];
328
329void fxDDFastPathInit()
330{
331 fx_init_fastpath( &fxFastTab[0] );
332 fx_init_fastpath_RGBA( &fxFastTab[SETUP_RGBA] );
333 fx_init_fastpath_TMU0( &fxFastTab[SETUP_TMU0] );
334 fx_init_fastpath_TMU1( &fxFastTab[SETUP_TMU1] );
335 fx_init_fastpath_RGBA_TMU0( &fxFastTab[SETUP_RGBA|SETUP_TMU0] );
336 fx_init_fastpath_RGBA_TMU1( &fxFastTab[SETUP_RGBA|SETUP_TMU1] );
337 fx_init_fastpath_TMU0_TMU1( &fxFastTab[SETUP_TMU0|SETUP_TMU1] );
338 fx_init_fastpath_RGBA_TMU0_TMU1( &fxFastTab[SETUP_RGBA|SETUP_TMU0|
339 SETUP_TMU1] );
340}
341
342
343
344void fxDDFastPath( struct vertex_buffer *VB )
345{
346 GLcontext *ctx = VB->ctx;
347 GLenum prim = ctx->CVA.elt_mode;
348 struct tfxMesaContext *fxMesa = FX_CONTEXT(ctx);
349 struct fx_fast_tab *tab = &fxFastTab[fxMesa->setupindex & 0x7];
350 GLuint do_clip = 1;
351 struct tfxMesaVertexBuffer *fxVB = FX_DRIVER_DATA(VB);
352#ifdef DRIVERTS
353 GLfloat tx, ty;
354#endif
355
356 fxVertex *first;
357 GLfloat *mat = ctx->Viewport.WindowMap.m;
358
359 gl_prepare_arrays_cva( VB ); /* still need this */
360
361 if (VB->EltPtr->count * 12 > fxVB->size) {
362 fxDDResizeVB( VB, VB->EltPtr->count * 12 );
363 do_clip = 1;
364 }
365
366 tab->build_vertices( VB, do_clip ); /* object->clip space */
367
368 first = FX_DRIVER_DATA(VB)->verts;
369
370#ifdef DRIVERTS
371 tx=mat[MAT_TX];
372 ty=mat[MAT_TY];
373 mat[MAT_TX]=tx+fxMesa->x_offset;
374 mat[MAT_TY]=ty+fxMesa->y_delta;
375#endif
376
377 if (VB->ClipOrMask) {
378 if (!VB->ClipAndMask) {
379 GLubyte tmp = VB->ClipOrMask;
380
381 tab->clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* clip */
382
383 tab->project_clipped_vertices( fxVB->verts->f,
384 fxVB->last_vert->f,
385 mat, 16 * 4,
386 VB->ClipMask );
387
388 ctx->CVA.elt_mode = gl_reduce_prim[prim];
389 VB->EltPtr = &(FX_DRIVER_DATA(VB)->clipped_elements);
390
391 VB->ClipOrMask = 0;
392 fxDDRenderElementsDirect( VB ); /* render using new list */
393 VB->ClipOrMask = tmp;
394 }
395 } else {
396 tab->project_vertices( fxVB->verts->f,
397 fxVB->last_vert->f,
398 mat, 16 * 4 );
399
400 fxDDRenderElementsDirect( VB ); /* render using orig list */
401 }
402
403#ifdef DRIVERTS
404 mat[MAT_TX]=tx;
405 mat[MAT_TY]=ty;
406#endif
407
408 /* This indicates that there is no cached data to reuse.
409 */
410 VB->pipeline->data_valid = 0;
411 VB->pipeline->pipeline_valid = 0;
412}
413
414
415#else
416
417/*
418 * Need this to provide at least one external definition.
419 */
420int gl_fxfastpath_dummy(void)
421{
422 return 0;
423}
424
425#endif
Note: See TracBrowser for help on using the repository browser.