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

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

* empty log message *

File size: 15.4 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/* fxcva.c - the CVA related code */
47
48
49#ifdef HAVE_CONFIG_H
50#include "conf.h"
51#endif
52
53#if defined(FX)
54
55#include "fxdrv.h"
56#include "mmath.h"
57#include "vbindirect.h"
58#include "pb.h"
59#include "fxvsetup.h"
60#include "pipeline.h"
61#include "stages.h"
62
63#define PRIM_POINTS 0
64#define PRIM_LINES 1
65#define PRIM_TRIS 2
66#define PRIM_CULLED 3
67
68
69static GLuint reduce_prim[GL_POLYGON+2] = {
70 PRIM_POINTS,
71 PRIM_LINES,
72 PRIM_LINES,
73 PRIM_LINES,
74 PRIM_TRIS,
75 PRIM_TRIS,
76 PRIM_TRIS,
77 PRIM_TRIS,
78 PRIM_TRIS,
79 PRIM_TRIS,
80 PRIM_CULLED
81};
82
83typedef void (*mergefunc)( struct vertex_buffer *cvaVB,
84 struct vertex_buffer *VB,
85 const struct gl_prim_state *state,
86 GLuint start,
87 GLuint count );
88
89static void fxCvaRenderNoop( struct vertex_buffer *cvaVB,
90 struct vertex_buffer *VB,
91 const struct gl_prim_state *state,
92 GLuint start,
93 GLuint count )
94{
95}
96
97static INLINE void fxRenderClippedTriangle2( struct vertex_buffer *VB,
98 GLuint v1, GLuint v2, GLuint v3 )
99{
100 fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
101 GLubyte *clipmask = VB->ClipMask;
102 GLubyte mask = clipmask[v1] | clipmask[v2] | clipmask[v3];
103
104 if (!mask) {
105 FX_grDrawTriangle((GrVertex *)gWin[v1].f,
106 (GrVertex *)gWin[v2].f,
107 (GrVertex *)gWin[v3].f);
108 } else if (!(clipmask[v1]&clipmask[v2]&clipmask[v3]&CLIP_ALL_BITS)) {
109 GLuint n;
110 GLuint vlist[VB_MAX_CLIPPED_VERTS];
111 ASSIGN_3V(vlist, v1, v2, v3);
112
113 n = (VB->ctx->poly_clip_tab[VB->ClipPtr->size])( VB, 3, vlist, mask );
114 if (n >= 3) {
115 GLuint i, j0 = vlist[0];
116 for (i=2;i<n;i++) {
117 FX_grDrawTriangle((GrVertex *)gWin[j0].f,
118 (GrVertex *)gWin[vlist[i-1]].f,
119 (GrVertex *)gWin[vlist[i]].f);
120 }
121 }
122 }
123}
124
125
126static mergefunc merge_and_render_tab[2][MAX_MERGABLE][PRIM_CULLED+1];
127
128
129/*
130#define CVA_VARS_RGBA \
131 GLubyte (*color)[4] = VB->ColorPtr->data; \
132 GLubyte (*cva_color)[4] = (cvaVB->ColorPtr = cvaVB->LitColor[0])->data;
133*/
134
135#define CVA_VARS_RGBA \
136 GLubyte (*color)[4] = VB->ColorPtr->data; \
137 GLubyte (*cva_color)[4] = cvaVB->ColorPtr->data;
138
139
140
141#undef DO_SETUP_RGBA
142#if FX_USE_PARGB
143#define DO_SETUP_RGBA \
144{ \
145 GLubyte *col = color[i]; \
146 GET_PARGB(v)= ((col[3] << 24) | \
147 (col[0] << 16) | \
148 (col[1] << 8) | \
149 (col[2])); \
150}
151#else
152#define DO_SETUP_RGBA \
153{ \
154 GLubyte *col = color[i]; \
155 v[GR_VERTEX_R_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \
156 v[GR_VERTEX_G_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \
157 v[GR_VERTEX_B_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \
158 v[GR_VERTEX_A_OFFSET]=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \
159}
160#endif /* FX_USE_PARGB */
161
162
163#define CVA_VARS_TMU0 \
164 VARS_TMU0 \
165 GLfloat (*cva_tex0)[4] = (cvaVB->TexCoordPtr[tmu0_source] = cvaVB->store.TexCoord[tmu0_source])->data;
166
167#define CVA_VARS_TMU1 \
168 VARS_TMU1 \
169 GLfloat (*cva_tex1)[4] = (cvaVB->TexCoordPtr[tmu1_source] = cvaVB->store.TexCoord[tmu1_source])->data;
170
171
172#define INIT_RGBA (void) cva_color;
173#define INIT_TMU0 (void) cva_tex0; (void) tmu0_stride; (void) tmu0_sz;
174#define INIT_TMU1 (void) cva_tex1; (void) tmu1_stride; (void) tmu1_sz;
175
176
177#define DRAW_POINT FX_grDrawPoint( (GrVertex *)v )
178#define DRAW_LINE FX_grDrawLine( (GrVertex *)v, (GrVertex *)prev_v )
179#define DRAW_TRI FX_grDrawTriangle( (GrVertex *)gWin[l[0]].f, (GrVertex *)gWin[l[1]].f, (GrVertex *)v )
180#define DRAW_TRI2 FX_grDrawTriangle( vl[0], vl[1], vl[2] )
181#define CLIP_LINE fxRenderClippedLine( cvaVB, e, prev )
182#define CLIP_OR_DRAW_TRI fxRenderClippedTriangle2( cvaVB, l[0], l[1], e )
183#define DIRECT 1
184
185#define TAG(x) x
186#define IDX 0
187#define VARS
188#define INIT
189#define INCR
190#define MERGE_RAST
191#define MERGE_VB
192#include "fxcvatmp.h"
193
194#define TAG(x) x##RGBA
195#define IDX SETUP_RGBA
196#define VARS CVA_VARS_RGBA
197#define INIT INIT_RGBA
198#define INCR
199#define MERGE_RAST DO_SETUP_RGBA
200#define MERGE_VB COPY_4UBV(cva_color[e], color[i])
201#include "fxcvatmp.h"
202
203#define TAG(x) x##T0
204#define IDX SETUP_TMU0
205#define VARS CVA_VARS_TMU0
206#define INIT INIT_TMU0
207#define INCR , tmu0_data+=4
208#define MERGE_RAST DO_SETUP_TMU0
209#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data)
210#include "fxcvatmp.h"
211
212#define TAG(x) x##T1
213#define IDX SETUP_TMU1
214#define VARS CVA_VARS_TMU1
215#define INIT INIT_TMU1
216#define INCR , tmu1_data+=4
217#define MERGE_RAST DO_SETUP_TMU1
218#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data)
219#include "fxcvatmp.h"
220
221#define TAG(x) x##T0T1
222#define IDX SETUP_TMU0|SETUP_TMU1
223#define VARS CVA_VARS_TMU0 CVA_VARS_TMU1
224#define INIT INIT_TMU0 INIT_TMU1
225#define INCR , tmu0_data+=4 , tmu1_data+=4
226#define MERGE_RAST DO_SETUP_TMU0 DO_SETUP_TMU1
227#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \
228 COPY_2FV(cva_tex1[e], tmu1_data);
229#include "fxcvatmp.h"
230
231#define TAG(x) x##RGBAT0
232#define IDX SETUP_RGBA|SETUP_TMU0
233#define VARS CVA_VARS_RGBA CVA_VARS_TMU0
234#define INIT INIT_RGBA INIT_TMU0
235#define INCR , tmu0_data+=4
236#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU0
237#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \
238 COPY_4UBV(cva_color[e], color[i]);
239#include "fxcvatmp.h"
240
241#define TAG(x) x##RGBAT1
242#define IDX SETUP_RGBA|SETUP_TMU1
243#define VARS CVA_VARS_RGBA CVA_VARS_TMU1
244#define INIT INIT_RGBA INIT_TMU1
245#define INCR , tmu1_data+=4
246#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU1
247#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data); \
248 COPY_4UBV(cva_color[e], color[i]);
249#include "fxcvatmp.h"
250
251#define TAG(x) x##RGBAT0T1
252#define IDX SETUP_RGBA|SETUP_TMU0|SETUP_TMU1
253#define VARS CVA_VARS_RGBA CVA_VARS_TMU0 CVA_VARS_TMU1
254#define INIT INIT_RGBA INIT_TMU0 INIT_TMU1
255#define INCR , tmu0_data+=4 , tmu1_data+=4
256#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU0 DO_SETUP_TMU1
257#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \
258 COPY_2FV(cva_tex1[e], tmu1_data); \
259 COPY_4UBV(cva_color[e], color[i]);
260#include "fxcvatmp.h"
261
262
263
264#undef DRAW_POINT
265#undef DRAW_LINE
266#undef DRAW_TRI
267#undef CLIP_LINE
268#undef CLIP_OR_DRAW_TRI
269#undef DIRECT
270
271#define DRAW_POINT ctx->Driver.PointsFunc( ctx, e, e )
272#define DRAW_LINE ctx->Driver.LineFunc( ctx, e, prev, e )
273#define DRAW_TRI ctx->TriangleFunc( ctx, l[0], l[1], e, e )
274#define CLIP_LINE gl_render_clipped_line( ctx, e, prev )
275#define CLIP_OR_DRAW_TRI \
276do { \
277 if (clip[l[0]] | clip[l[1]] | clip[e]) { \
278 if (!(clip[l[0]] & clip[l[1]] & clip[e] & CLIP_ALL_BITS)) { \
279 COPY_3V(vlist, l); \
280 gl_render_clipped_triangle( ctx, 3, vlist, e ); \
281 } \
282 } \
283 else ctx->TriangleFunc( ctx, l[0], l[1], e, e ); \
284} while (0)
285
286
287#define DIRECT 0
288
289#define TAG(x) x##_indirect
290#define IDX 0
291#define VARS
292#define INIT
293#define INCR
294#define MERGE_RAST
295#define MERGE_VB
296#include "fxcvatmp.h"
297
298#define TAG(x) x##RGBA_indirect
299#define IDX SETUP_RGBA
300#define VARS CVA_VARS_RGBA
301#define INIT INIT_RGBA
302#define INCR
303#define MERGE_RAST DO_SETUP_RGBA
304#define MERGE_VB COPY_4UBV(cva_color[e], color[i])
305#include "fxcvatmp.h"
306
307#define TAG(x) x##T0_indirect
308#define IDX SETUP_TMU0
309#define VARS CVA_VARS_TMU0
310#define INIT INIT_TMU0
311#define INCR , tmu0_data+=4
312#define MERGE_RAST DO_SETUP_TMU0
313#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data)
314#include "fxcvatmp.h"
315
316#define TAG(x) x##T1_indirect
317#define IDX SETUP_TMU1
318#define VARS CVA_VARS_TMU1
319#define INIT INIT_TMU1
320#define INCR , tmu1_data+=4
321#define MERGE_RAST DO_SETUP_TMU1
322#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data)
323#include "fxcvatmp.h"
324
325#define TAG(x) x##T0T1_indirect
326#define IDX SETUP_TMU0|SETUP_TMU1
327#define VARS CVA_VARS_TMU0 CVA_VARS_TMU1
328#define INIT INIT_TMU0 INIT_TMU1
329#define INCR , tmu0_data+=4 , tmu1_data+=4
330#define MERGE_RAST DO_SETUP_TMU0 DO_SETUP_TMU1
331#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \
332 COPY_2FV(cva_tex1[e], tmu1_data);
333#include "fxcvatmp.h"
334
335#define TAG(x) x##RGBAT0_indirect
336#define IDX SETUP_RGBA|SETUP_TMU0
337#define VARS CVA_VARS_RGBA CVA_VARS_TMU0
338#define INIT INIT_RGBA INIT_TMU0
339#define INCR , tmu0_data+=4
340#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU0
341#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \
342 COPY_4UBV(cva_color[e], color[i]);
343#include "fxcvatmp.h"
344
345#define TAG(x) x##RGBAT1_indirect
346#define IDX SETUP_RGBA|SETUP_TMU1
347#define VARS CVA_VARS_RGBA CVA_VARS_TMU1
348#define INIT INIT_RGBA INIT_TMU1
349#define INCR , tmu1_data+=4
350#define MERGE_RAST DO_SETUP_RGBA; DO_SETUP_TMU1
351#define MERGE_VB COPY_2FV(cva_tex1[e], tmu1_data); \
352 COPY_4UBV(cva_color[e], color[i]);
353#include "fxcvatmp.h"
354
355#define TAG(x) x##RGBAT0T1_indirect
356#define IDX SETUP_RGBA|SETUP_TMU0|SETUP_TMU1
357#define VARS CVA_VARS_RGBA CVA_VARS_TMU0 CVA_VARS_TMU1
358#define INIT INIT_RGBA INIT_TMU0 INIT_TMU1
359#define INCR , tmu0_data+=4 , tmu1_data+=4
360#define MERGE_RAST DO_SETUP_RGBA DO_SETUP_TMU0 DO_SETUP_TMU1
361#define MERGE_VB COPY_2FV(cva_tex0[e], tmu0_data); \
362 COPY_2FV(cva_tex1[e], tmu1_data); \
363 COPY_4UBV(cva_color[e], color[i]);
364#include "fxcvatmp.h"
365
366
367
368
369void fxDDCvaInit()
370{
371 /* Call grDrawTriangle et al */
372 init_cva();
373 init_cvaT0();
374 init_cvaT1();
375 init_cvaT0T1();
376 init_cvaRGBA();
377 init_cvaRGBAT0();
378 init_cvaRGBAT1();
379 init_cvaRGBAT0T1();
380
381 /* Call ctx->TriangleFunc and friends */
382 init_cva_indirect();
383 init_cvaT0_indirect();
384 init_cvaT1_indirect();
385 init_cvaT0T1_indirect();
386 init_cvaRGBA_indirect();
387 init_cvaRGBAT0_indirect();
388 init_cvaRGBAT1_indirect();
389 init_cvaRGBAT0T1_indirect();
390}
391
392
393void fxDDCheckMergeAndRender( GLcontext *ctx, struct gl_pipeline_stage *d )
394{
395 GLuint inputs = ctx->RenderFlags & ~ctx->CVA.pre.outputs;
396
397 if (!(ctx->TriangleCaps & DD_TRI_UNFILLED) &&
398 (ctx->Array.Summary & VERT_OBJ_ANY))
399 {
400 d->inputs = (VERT_SETUP_PART | VERT_ELT | inputs);
401 d->outputs = 0;
402 d->type = PIPE_IMMEDIATE;
403 }
404
405/* gl_print_vert_flags("merge&render inputs", d->inputs); */
406}
407
408
409extern void fxPointSmooth(GLcontext *ctx, GLuint first, GLuint last);
410extern void fxLineSmooth(GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv);
411extern void fxTriangleSmooth(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3,
412 GLuint pv);
413extern const char *gl_prim_name[];
414
415
416/* static GLboolean edge_flag[GL_POLYGON+2] = { 0,0,0,0,1,0,0,1,0,1,0 }; */
417
418void fxDDMergeAndRender( struct vertex_buffer *VB )
419{
420 GLcontext *ctx = VB->ctx;
421 struct vertex_buffer *cvaVB = ctx->CVA.VB;
422 fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
423 GLuint i, next, prim;
424 GLuint parity = VB->Parity;
425 GLuint count = VB->Count;
426 const struct gl_prim_state *state;
427 mergefunc func;
428 struct vertex_buffer *saved_vb = ctx->VB;
429 GLuint inputs = ctx->RenderFlags & ~ctx->CVA.pre.outputs;
430 GLuint flags = 0;
431 GLuint direct = (fxMesa->render_index == 0);
432 mergefunc (*tab)[PRIM_CULLED+1] = merge_and_render_tab[direct];
433 GLuint p = 0;
434
435 if (fxMesa->new_state)
436 fxSetupFXUnits(ctx);
437
438
439 /* May actually contain elements not present in fxMesa->setupindex,
440 * eg RGBA when flat shading. These need to be copied into the cva
441 * VB so that funcs like fxTriangleFlat will be able to reach them.
442 *
443 * This leads to some duplication of effort in the merge funcs.
444 */
445 if (inputs & VERT_RGBA) {
446 cvaVB->ColorPtr = cvaVB->Color[0] = cvaVB->LitColor[0];
447 cvaVB->Color[1] = cvaVB->LitColor[1];
448 flags |= SETUP_RGBA;
449 }
450
451 if (inputs & VERT_TEX0_ANY) {
452 cvaVB->TexCoordPtr[0] = cvaVB->store.TexCoord[0];
453 flags |= fxMesa->tex_dest[0];
454 }
455
456 if (inputs & VERT_TEX1_ANY) {
457 cvaVB->TexCoordPtr[1] = cvaVB->store.TexCoord[1];
458 flags |= fxMesa->tex_dest[1];
459 }
460#if 0
461 fxPrintSetupFlags("FX cva merge & render", flags);
462#endif
463
464 if (cvaVB->ClipOrMask)
465 gl_import_client_data( cvaVB, ctx->RenderFlags,
466 VEC_WRITABLE|VEC_GOOD_STRIDE );
467
468 ctx->VB = cvaVB;
469
470 do {
471 for ( i= VB->CopyStart ; i < count ; parity = 0, i = next )
472 {
473 prim = VB->Primitive[i];
474 next = VB->NextPrimitive[i];
475
476 state = gl_prim_state_machine[prim][parity];
477 func = tab[flags][reduce_prim[prim]];
478 func( cvaVB, VB, state, i, next );
479
480 if ( ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE )
481 {
482 cvaVB->Specular = cvaVB->Spec[0];
483 cvaVB->ColorPtr = cvaVB->Color[0];
484 cvaVB->IndexPtr = cvaVB->Index[0];
485 }
486 }
487 } while (ctx->Driver.MultipassFunc &&
488 ctx->Driver.MultipassFunc( VB, ++p ));
489
490
491
492 if (ctx->PB->count > 0)
493 gl_flush_pb(ctx);
494
495 ctx->VB = saved_vb;
496}
497
498
499
500#else
501
502
503/*
504 * Need this to provide at least one external definition.
505 */
506
507int gl_fx_dummy_function_cva(void)
508{
509 return 0;
510}
511
512
513#endif /* FX */
Note: See TracBrowser for help on using the repository browser.