~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/tdfx/tdfx_tris.c

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c; c-basic-offset: 3 -*-
2
 
 *
3
 
 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
4
 
 *
5
 
 * All Rights Reserved.
6
 
 *
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 
 * copy of this software and associated documentation files (the "Software"),
9
 
 * to deal in the Software without restriction, including without limitation
10
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 
 * and/or sell copies of the Software, and to permit persons to whom the
12
 
 * Software is furnished to do so, subject to the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice (including the next
15
 
 * paragraph) shall be included in all copies or substantial portions of the
16
 
 * Software.
17
 
 *
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
 
 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23
 
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
 
 * SOFTWARE.
25
 
 */
26
 
 
27
 
/* New fixes:
28
 
 *      Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
29
 
 *
30
 
 * Authors:
31
 
 *    Keith Whitwell <keith@tungstengraphics.com>
32
 
 */
33
 
 
34
 
#include "main/glheader.h"
35
 
#include "main/mtypes.h"
36
 
#include "main/macros.h"
37
 
#include "main/colormac.h"
38
 
 
39
 
#include "swrast/swrast.h"
40
 
#include "swrast_setup/swrast_setup.h"
41
 
#include "swrast_setup/ss_context.h"
42
 
#include "tnl/t_context.h"
43
 
#include "tnl/t_pipeline.h"
44
 
 
45
 
#include "tdfx_tris.h"
46
 
#include "tdfx_state.h"
47
 
#include "tdfx_vb.h"
48
 
#include "tdfx_lock.h"
49
 
#include "tdfx_render.h"
50
 
 
51
 
 
52
 
static void tdfxRasterPrimitive( struct gl_context *ctx, GLenum prim );
53
 
static void tdfxRenderPrimitive( struct gl_context *ctx, GLenum prim );
54
 
 
55
 
static GLenum reduced_prim[GL_POLYGON+1] = {
56
 
   GL_POINTS,
57
 
   GL_LINES,
58
 
   GL_LINES,
59
 
   GL_LINES,
60
 
   GL_TRIANGLES,
61
 
   GL_TRIANGLES,
62
 
   GL_TRIANGLES,
63
 
   GL_TRIANGLES,
64
 
   GL_TRIANGLES,
65
 
   GL_TRIANGLES
66
 
};
67
 
 
68
 
/***********************************************************************
69
 
 *          Macros for t_dd_tritmp.h to draw basic primitives          *
70
 
 ***********************************************************************/
71
 
 
72
 
#define TRI( a, b, c )                          \
73
 
do {                                            \
74
 
   if (DO_FALLBACK)                             \
75
 
      fxMesa->draw_triangle( fxMesa, a, b, c ); \
76
 
   else                                         \
77
 
      fxMesa->Glide.grDrawTriangle( a, b, c );  \
78
 
} while (0)                                     \
79
 
 
80
 
#define QUAD( a, b, c, d )                      \
81
 
do {                                            \
82
 
   if (DO_FALLBACK) {                           \
83
 
      fxMesa->draw_triangle( fxMesa, a, b, d ); \
84
 
      fxMesa->draw_triangle( fxMesa, b, c, d ); \
85
 
   } else {                                     \
86
 
      tdfxVertex *_v_[4];                       \
87
 
      _v_[0] = d;                               \
88
 
      _v_[1] = a;                               \
89
 
      _v_[2] = b;                               \
90
 
      _v_[3] = c;                               \
91
 
      fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\
92
 
      /*fxMesa->Glide.grDrawTriangle( a, b, d );*/\
93
 
      /*fxMesa->Glide.grDrawTriangle( b, c, d );*/\
94
 
   }                                            \
95
 
} while (0)
96
 
 
97
 
#define LINE( v0, v1 )                          \
98
 
do {                                            \
99
 
   if (DO_FALLBACK)                             \
100
 
      fxMesa->draw_line( fxMesa, v0, v1 );      \
101
 
   else {                                       \
102
 
      v0->x += LINE_X_OFFSET - TRI_X_OFFSET;    \
103
 
      v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET;    \
104
 
      v1->x += LINE_X_OFFSET - TRI_X_OFFSET;    \
105
 
      v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET;    \
106
 
      fxMesa->Glide.grDrawLine( v0, v1 );       \
107
 
      v0->x -= LINE_X_OFFSET - TRI_X_OFFSET;    \
108
 
      v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET;    \
109
 
      v1->x -= LINE_X_OFFSET - TRI_X_OFFSET;    \
110
 
      v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET;    \
111
 
   }                                            \
112
 
} while (0)
113
 
 
114
 
#define POINT( v0 )                             \
115
 
do {                                            \
116
 
   if (DO_FALLBACK)                             \
117
 
      fxMesa->draw_point( fxMesa, v0 );         \
118
 
   else {                                       \
119
 
      v0->x += PNT_X_OFFSET - TRI_X_OFFSET;     \
120
 
      v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET;     \
121
 
      fxMesa->Glide.grDrawPoint( v0 );          \
122
 
      v0->x -= PNT_X_OFFSET - TRI_X_OFFSET;     \
123
 
      v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET;     \
124
 
   }                                            \
125
 
} while (0)
126
 
 
127
 
 
128
 
/***********************************************************************
129
 
 *              Fallback to swrast for basic primitives                *
130
 
 ***********************************************************************/
131
 
 
132
 
/* Build an SWvertex from a hardware vertex. 
133
 
 *
134
 
 * This code is hit only when a mix of accelerated and unaccelerated
135
 
 * primitives are being drawn, and only for the unaccelerated
136
 
 * primitives.  
137
 
 */
138
 
static void 
139
 
tdfx_translate_vertex( struct gl_context *ctx, const tdfxVertex *src, SWvertex *dst)
140
 
{
141
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
142
 
 
143
 
   if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) {
144
 
      dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset;
145
 
      dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
146
 
      dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z;
147
 
      dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0;
148
 
 
149
 
      dst->color[0] = src->color[2];
150
 
      dst->color[1] = src->color[1];
151
 
      dst->color[2] = src->color[0];
152
 
      dst->color[3] = src->color[3];
153
 
   } 
154
 
   else {
155
 
      GLfloat w = 1.0 / src->rhw;
156
 
 
157
 
      dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset;
158
 
      dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset);
159
 
      dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z;
160
 
      dst->attrib[FRAG_ATTRIB_WPOS][3] = src->rhw;
161
 
 
162
 
      dst->color[0] = src->color[2];
163
 
      dst->color[1] = src->color[1];
164
 
      dst->color[2] = src->color[0];
165
 
      dst->color[3] = src->color[3];
166
 
 
167
 
      dst->attrib[FRAG_ATTRIB_TEX0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0;
168
 
      dst->attrib[FRAG_ATTRIB_TEX0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0;
169
 
      if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ1 || fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) {
170
 
         dst->attrib[FRAG_ATTRIB_TEX0][3] = w * src->tq0;
171
 
      } else {
172
 
         dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0;
173
 
      }
174
 
 
175
 
      if (fxMesa->SetupIndex & TDFX_TEX1_BIT) {
176
 
         dst->attrib[FRAG_ATTRIB_TEX1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1;
177
 
         dst->attrib[FRAG_ATTRIB_TEX1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1;
178
 
         if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) {
179
 
            dst->attrib[FRAG_ATTRIB_TEX1][3] = w * src->tq1;
180
 
         } else {
181
 
            dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0;
182
 
         }
183
 
      }
184
 
   }
185
 
 
186
 
   dst->pointSize = ctx->Point.Size;
187
 
}
188
 
 
189
 
 
190
 
static void 
191
 
tdfx_fallback_tri( tdfxContextPtr fxMesa, 
192
 
                   tdfxVertex *v0, 
193
 
                   tdfxVertex *v1, 
194
 
                   tdfxVertex *v2 )
195
 
{
196
 
   struct gl_context *ctx = fxMesa->glCtx;
197
 
   SWvertex v[3];
198
 
   tdfx_translate_vertex( ctx, v0, &v[0] );
199
 
   tdfx_translate_vertex( ctx, v1, &v[1] );
200
 
   tdfx_translate_vertex( ctx, v2, &v[2] );
201
 
   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
202
 
}
203
 
 
204
 
 
205
 
static void 
206
 
tdfx_fallback_line( tdfxContextPtr fxMesa,
207
 
                    tdfxVertex *v0,
208
 
                    tdfxVertex *v1 )
209
 
{
210
 
   struct gl_context *ctx = fxMesa->glCtx;
211
 
   SWvertex v[2];
212
 
   tdfx_translate_vertex( ctx, v0, &v[0] );
213
 
   tdfx_translate_vertex( ctx, v1, &v[1] );
214
 
   _swrast_Line( ctx, &v[0], &v[1] );
215
 
}
216
 
 
217
 
 
218
 
static void 
219
 
tdfx_fallback_point( tdfxContextPtr fxMesa, 
220
 
                     tdfxVertex *v0 )
221
 
{
222
 
   struct gl_context *ctx = fxMesa->glCtx;
223
 
   SWvertex v[1];
224
 
   tdfx_translate_vertex( ctx, v0, &v[0] );
225
 
   _swrast_Point( ctx, &v[0] );
226
 
}
227
 
 
228
 
/***********************************************************************
229
 
 *                 Functions to draw basic primitives                  *
230
 
 ***********************************************************************/
231
 
 
232
 
static void tdfx_print_vertex( struct gl_context *ctx, const tdfxVertex *v )
233
 
{
234
 
   tdfxContextPtr tmesa = TDFX_CONTEXT( ctx );
235
 
 
236
 
   fprintf(stderr, "vertex at %p\n", (void *)v);
237
 
 
238
 
   if (tmesa->vertexFormat == TDFX_LAYOUT_TINY) {
239
 
      fprintf(stderr, "x %f y %f z %f\n", v->x, v->y, v->z);
240
 
   } 
241
 
   else {
242
 
      fprintf(stderr, "x %f y %f z %f oow %f\n", 
243
 
              v->x, v->y, v->z, v->rhw);
244
 
   }
245
 
   fprintf(stderr, "r %d g %d b %d a %d\n", 
246
 
              v->color[0],
247
 
              v->color[1],
248
 
              v->color[2],
249
 
              v->color[3]);
250
 
   
251
 
   fprintf(stderr, "\n");
252
 
}
253
 
 
254
 
#define DO_FALLBACK 0
255
 
 
256
 
/* Need to do clip loop at each triangle when mixing swrast and hw
257
 
 * rendering.  These functions are only used when mixed-mode rendering
258
 
 * is occurring.
259
 
 */
260
 
static void tdfx_draw_triangle( tdfxContextPtr fxMesa,
261
 
                                tdfxVertexPtr v0,
262
 
                                tdfxVertexPtr v1,
263
 
                                tdfxVertexPtr v2 )
264
 
{
265
 
/*     fprintf(stderr, "%s\n", __FUNCTION__); */
266
 
/*     tdfx_print_vertex( fxMesa->glCtx, v0 ); */
267
 
/*     tdfx_print_vertex( fxMesa->glCtx, v1 ); */
268
 
/*     tdfx_print_vertex( fxMesa->glCtx, v2 ); */
269
 
   BEGIN_CLIP_LOOP_LOCKED(fxMesa) {
270
 
      TRI( v0, v1, v2 );
271
 
   } END_CLIP_LOOP_LOCKED(fxMesa);
272
 
}
273
 
 
274
 
static void tdfx_draw_line( tdfxContextPtr fxMesa,
275
 
                            tdfxVertexPtr v0,
276
 
                            tdfxVertexPtr v1 )
277
 
{
278
 
   /* No support for wide lines (avoid wide/aa line fallback).
279
 
    */
280
 
   BEGIN_CLIP_LOOP_LOCKED(fxMesa) {
281
 
      LINE(v0, v1);
282
 
   } END_CLIP_LOOP_LOCKED(fxMesa);
283
 
}
284
 
 
285
 
static void tdfx_draw_point( tdfxContextPtr fxMesa,
286
 
                             tdfxVertexPtr v0 )
287
 
{
288
 
   /* No support for wide points.
289
 
    */
290
 
   BEGIN_CLIP_LOOP_LOCKED(fxMesa) {
291
 
      POINT( v0 );
292
 
   } END_CLIP_LOOP_LOCKED(fxMesa);
293
 
}
294
 
 
295
 
#undef DO_FALLBACK
296
 
 
297
 
 
298
 
#define TDFX_UNFILLED_BIT    0x1
299
 
#define TDFX_OFFSET_BIT      0x2
300
 
#define TDFX_TWOSIDE_BIT     0x4
301
 
#define TDFX_FLAT_BIT        0x8
302
 
#define TDFX_FALLBACK_BIT    0x10
303
 
#define TDFX_MAX_TRIFUNC     0x20
304
 
 
305
 
static struct {
306
 
   tnl_points_func              points;
307
 
   tnl_line_func                line;
308
 
   tnl_triangle_func    triangle;
309
 
   tnl_quad_func                quad;
310
 
} rast_tab[TDFX_MAX_TRIFUNC];
311
 
 
312
 
#define DO_FALLBACK (IND & TDFX_FALLBACK_BIT)
313
 
#define DO_OFFSET   (IND & TDFX_OFFSET_BIT)
314
 
#define DO_UNFILLED (IND & TDFX_UNFILLED_BIT)
315
 
#define DO_TWOSIDE  (IND & TDFX_TWOSIDE_BIT)
316
 
#define DO_FLAT     (IND & TDFX_FLAT_BIT)
317
 
#define DO_TRI       1
318
 
#define DO_QUAD      1
319
 
#define DO_LINE      1
320
 
#define DO_POINTS    1
321
 
#define DO_FULL_QUAD 1
322
 
 
323
 
#define HAVE_SPEC   0
324
 
#define HAVE_HW_FLATSHADE 0
325
 
#define HAVE_BACK_COLORS  0
326
 
#define VERTEX tdfxVertex
327
 
#define TAB rast_tab
328
 
 
329
 
#define DEPTH_SCALE 1.0
330
 
#define UNFILLED_TRI unfilled_tri
331
 
#define UNFILLED_QUAD unfilled_quad
332
 
#define VERT_X(_v) _v->x
333
 
#define VERT_Y(_v) _v->y
334
 
#define VERT_Z(_v) _v->z
335
 
#define AREA_IS_CCW( a ) (a < 0)
336
 
#define GET_VERTEX(e) (fxMesa->verts + (e))
337
 
 
338
 
#define VERT_SET_RGBA( dst, f )                 \
339
 
do {                                            \
340
 
   UNCLAMPED_FLOAT_TO_UBYTE(dst->color[2], f[0]);\
341
 
   UNCLAMPED_FLOAT_TO_UBYTE(dst->color[1], f[1]);\
342
 
   UNCLAMPED_FLOAT_TO_UBYTE(dst->color[0], f[2]);\
343
 
   UNCLAMPED_FLOAT_TO_UBYTE(dst->color[3], f[3]);\
344
 
} while (0)
345
 
 
346
 
#define VERT_COPY_RGBA( v0, v1 )                \
347
 
   *(GLuint *)&v0->color = *(GLuint *)&v1->color
348
 
 
349
 
#define VERT_SAVE_RGBA( idx )                   \
350
 
   *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->color
351
 
 
352
 
#define VERT_RESTORE_RGBA( idx )                \
353
 
   *(GLuint *)&v[idx]->color = *(GLuint *)&color[idx]
354
 
 
355
 
#define LOCAL_VARS(n)                                   \
356
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);           \
357
 
   GLubyte color[n][4];                                 \
358
 
   (void) color;
359
 
 
360
 
 
361
 
 
362
 
/***********************************************************************
363
 
 *            Functions to draw basic unfilled primitives              *
364
 
 ***********************************************************************/
365
 
 
366
 
#define RASTERIZE(x) if (fxMesa->raster_primitive != reduced_prim[x]) \
367
 
                        tdfxRasterPrimitive( ctx, reduced_prim[x] )
368
 
#define RENDER_PRIMITIVE fxMesa->render_primitive
369
 
#define IND TDFX_FALLBACK_BIT
370
 
#define TAG(x) x
371
 
#include "tnl_dd/t_dd_unfilled.h"
372
 
#undef IND
373
 
 
374
 
/***********************************************************************
375
 
 *                 Functions to draw GL primitives                     *
376
 
 ***********************************************************************/
377
 
 
378
 
#define IND (0)
379
 
#define TAG(x) x
380
 
#include "tnl_dd/t_dd_tritmp.h"
381
 
 
382
 
#define IND (TDFX_OFFSET_BIT)
383
 
#define TAG(x) x##_offset
384
 
#include "tnl_dd/t_dd_tritmp.h"
385
 
 
386
 
#define IND (TDFX_TWOSIDE_BIT)
387
 
#define TAG(x) x##_twoside
388
 
#include "tnl_dd/t_dd_tritmp.h"
389
 
 
390
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT)
391
 
#define TAG(x) x##_twoside_offset
392
 
#include "tnl_dd/t_dd_tritmp.h"
393
 
 
394
 
#define IND (TDFX_UNFILLED_BIT)
395
 
#define TAG(x) x##_unfilled
396
 
#include "tnl_dd/t_dd_tritmp.h"
397
 
 
398
 
#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT)
399
 
#define TAG(x) x##_offset_unfilled
400
 
#include "tnl_dd/t_dd_tritmp.h"
401
 
 
402
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT)
403
 
#define TAG(x) x##_twoside_unfilled
404
 
#include "tnl_dd/t_dd_tritmp.h"
405
 
 
406
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT)
407
 
#define TAG(x) x##_twoside_offset_unfilled
408
 
#include "tnl_dd/t_dd_tritmp.h"
409
 
 
410
 
#define IND (TDFX_FALLBACK_BIT)
411
 
#define TAG(x) x##_fallback
412
 
#include "tnl_dd/t_dd_tritmp.h"
413
 
 
414
 
#define IND (TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT)
415
 
#define TAG(x) x##_offset_fallback
416
 
#include "tnl_dd/t_dd_tritmp.h"
417
 
 
418
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_FALLBACK_BIT)
419
 
#define TAG(x) x##_twoside_fallback
420
 
#include "tnl_dd/t_dd_tritmp.h"
421
 
 
422
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT)
423
 
#define TAG(x) x##_twoside_offset_fallback
424
 
#include "tnl_dd/t_dd_tritmp.h"
425
 
 
426
 
#define IND (TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT)
427
 
#define TAG(x) x##_unfilled_fallback
428
 
#include "tnl_dd/t_dd_tritmp.h"
429
 
 
430
 
#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT)
431
 
#define TAG(x) x##_offset_unfilled_fallback
432
 
#include "tnl_dd/t_dd_tritmp.h"
433
 
 
434
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT)
435
 
#define TAG(x) x##_twoside_unfilled_fallback
436
 
#include "tnl_dd/t_dd_tritmp.h"
437
 
 
438
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT| \
439
 
             TDFX_FALLBACK_BIT)
440
 
#define TAG(x) x##_twoside_offset_unfilled_fallback
441
 
#include "tnl_dd/t_dd_tritmp.h"
442
 
 
443
 
 
444
 
/* Tdfx doesn't support provoking-vertex flat-shading?
445
 
 */
446
 
#define IND (TDFX_FLAT_BIT)
447
 
#define TAG(x) x##_flat
448
 
#include "tnl_dd/t_dd_tritmp.h"
449
 
 
450
 
#define IND (TDFX_OFFSET_BIT|TDFX_FLAT_BIT)
451
 
#define TAG(x) x##_offset_flat
452
 
#include "tnl_dd/t_dd_tritmp.h"
453
 
 
454
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_FLAT_BIT)
455
 
#define TAG(x) x##_twoside_flat
456
 
#include "tnl_dd/t_dd_tritmp.h"
457
 
 
458
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FLAT_BIT)
459
 
#define TAG(x) x##_twoside_offset_flat
460
 
#include "tnl_dd/t_dd_tritmp.h"
461
 
 
462
 
#define IND (TDFX_UNFILLED_BIT|TDFX_FLAT_BIT)
463
 
#define TAG(x) x##_unfilled_flat
464
 
#include "tnl_dd/t_dd_tritmp.h"
465
 
 
466
 
#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FLAT_BIT)
467
 
#define TAG(x) x##_offset_unfilled_flat
468
 
#include "tnl_dd/t_dd_tritmp.h"
469
 
 
470
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT|TDFX_FLAT_BIT)
471
 
#define TAG(x) x##_twoside_unfilled_flat
472
 
#include "tnl_dd/t_dd_tritmp.h"
473
 
 
474
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FLAT_BIT)
475
 
#define TAG(x) x##_twoside_offset_unfilled_flat
476
 
#include "tnl_dd/t_dd_tritmp.h"
477
 
 
478
 
#define IND (TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
479
 
#define TAG(x) x##_fallback_flat
480
 
#include "tnl_dd/t_dd_tritmp.h"
481
 
 
482
 
#define IND (TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
483
 
#define TAG(x) x##_offset_fallback_flat
484
 
#include "tnl_dd/t_dd_tritmp.h"
485
 
 
486
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
487
 
#define TAG(x) x##_twoside_fallback_flat
488
 
#include "tnl_dd/t_dd_tritmp.h"
489
 
 
490
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
491
 
#define TAG(x) x##_twoside_offset_fallback_flat
492
 
#include "tnl_dd/t_dd_tritmp.h"
493
 
 
494
 
#define IND (TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
495
 
#define TAG(x) x##_unfilled_fallback_flat
496
 
#include "tnl_dd/t_dd_tritmp.h"
497
 
 
498
 
#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
499
 
#define TAG(x) x##_offset_unfilled_fallback_flat
500
 
#include "tnl_dd/t_dd_tritmp.h"
501
 
 
502
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
503
 
#define TAG(x) x##_twoside_unfilled_fallback_flat
504
 
#include "tnl_dd/t_dd_tritmp.h"
505
 
 
506
 
#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT| \
507
 
             TDFX_FALLBACK_BIT|TDFX_FLAT_BIT)
508
 
#define TAG(x) x##_twoside_offset_unfilled_fallback_flat
509
 
#include "tnl_dd/t_dd_tritmp.h"
510
 
 
511
 
 
512
 
static void init_rast_tab( void )
513
 
{
514
 
   init();
515
 
   init_offset();
516
 
   init_twoside();
517
 
   init_twoside_offset();
518
 
   init_unfilled();
519
 
   init_offset_unfilled();
520
 
   init_twoside_unfilled();
521
 
   init_twoside_offset_unfilled();
522
 
   init_fallback();
523
 
   init_offset_fallback();
524
 
   init_twoside_fallback();
525
 
   init_twoside_offset_fallback();
526
 
   init_unfilled_fallback();
527
 
   init_offset_unfilled_fallback();
528
 
   init_twoside_unfilled_fallback();
529
 
   init_twoside_offset_unfilled_fallback();
530
 
 
531
 
   init_flat();
532
 
   init_offset_flat();
533
 
   init_twoside_flat();
534
 
   init_twoside_offset_flat();
535
 
   init_unfilled_flat();
536
 
   init_offset_unfilled_flat();
537
 
   init_twoside_unfilled_flat();
538
 
   init_twoside_offset_unfilled_flat();
539
 
   init_fallback_flat();
540
 
   init_offset_fallback_flat();
541
 
   init_twoside_fallback_flat();
542
 
   init_twoside_offset_fallback_flat();
543
 
   init_unfilled_fallback_flat();
544
 
   init_offset_unfilled_fallback_flat();
545
 
   init_twoside_unfilled_fallback_flat();
546
 
   init_twoside_offset_unfilled_fallback_flat();
547
 
}
548
 
 
549
 
 
550
 
/**********************************************************************/
551
 
/*                 Render whole begin/end objects                     */
552
 
/**********************************************************************/
553
 
 
554
 
 
555
 
/* Accelerate vertex buffer rendering when renderindex == 0 and
556
 
 * there is no clipping.
557
 
 */
558
 
#define INIT(x) tdfxRenderPrimitive( ctx, x )
559
 
 
560
 
static void tdfx_render_vb_points( struct gl_context *ctx,
561
 
                                      GLuint start,
562
 
                                      GLuint count,
563
 
                                      GLuint flags )
564
 
{
565
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
566
 
   tdfxVertex *fxVB = fxMesa->verts;
567
 
   GLint i;
568
 
   (void) flags;
569
 
 
570
 
   INIT(GL_POINTS);
571
 
 
572
 
   /* Adjust point coords */
573
 
   for (i = start; i < count; i++) {
574
 
      fxVB[i].x += PNT_X_OFFSET - TRI_X_OFFSET;
575
 
      fxVB[i].y += PNT_Y_OFFSET - TRI_Y_OFFSET;
576
 
   }
577
 
 
578
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_POINTS, count-start,
579
 
                                              fxVB + start, sizeof(tdfxVertex));
580
 
   /* restore point coords */
581
 
   for (i = start; i < count; i++) {
582
 
      fxVB[i].x -= PNT_X_OFFSET - TRI_X_OFFSET;
583
 
      fxVB[i].y -= PNT_Y_OFFSET - TRI_Y_OFFSET;
584
 
   }
585
 
}
586
 
 
587
 
static void tdfx_render_vb_line_strip( struct gl_context *ctx,
588
 
                                      GLuint start,
589
 
                                      GLuint count,
590
 
                                      GLuint flags )
591
 
{
592
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
593
 
   tdfxVertex *fxVB = fxMesa->verts;
594
 
   GLint i;
595
 
   (void) flags;
596
 
 
597
 
   INIT(GL_LINE_STRIP);
598
 
 
599
 
   /* adjust line coords */
600
 
   for (i = start; i < count; i++) {
601
 
      fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET;
602
 
      fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET;
603
 
   }
604
 
 
605
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINE_STRIP, count-start,
606
 
                                              fxVB + start, sizeof(tdfxVertex) );
607
 
 
608
 
   /* restore line coords */
609
 
   for (i = start; i < count; i++) {
610
 
      fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET;
611
 
      fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
612
 
   }
613
 
}
614
 
 
615
 
static void tdfx_render_vb_line_loop( struct gl_context *ctx,
616
 
                                      GLuint start,
617
 
                                      GLuint count,
618
 
                                      GLuint flags )
619
 
{
620
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
621
 
   tdfxVertex *fxVB = fxMesa->verts;
622
 
   GLint i;
623
 
   GLint j = start;
624
 
   (void) flags;
625
 
 
626
 
   INIT(GL_LINE_LOOP);
627
 
 
628
 
   if (!(flags & PRIM_BEGIN)) {
629
 
      j++;
630
 
   }
631
 
 
632
 
   /* adjust line coords */
633
 
   for (i = start; i < count; i++) {
634
 
      fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET;
635
 
      fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET;
636
 
   }
637
 
 
638
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINE_STRIP, count-j,
639
 
                                              fxVB + j, sizeof(tdfxVertex));
640
 
 
641
 
   if (flags & PRIM_END) 
642
 
      fxMesa->Glide.grDrawLine( fxVB + (count - 1), 
643
 
                                fxVB + start );
644
 
 
645
 
   /* restore line coords */
646
 
   for (i = start; i < count; i++) {
647
 
      fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET;
648
 
      fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
649
 
   }
650
 
}
651
 
 
652
 
static void tdfx_render_vb_lines( struct gl_context *ctx,
653
 
                                      GLuint start,
654
 
                                      GLuint count,
655
 
                                      GLuint flags )
656
 
{
657
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
658
 
   tdfxVertex *fxVB = fxMesa->verts;
659
 
   GLint i;
660
 
   (void) flags;
661
 
 
662
 
   INIT(GL_LINES);
663
 
 
664
 
   /* adjust line coords */
665
 
   for (i = start; i < count; i++) {
666
 
      fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET;
667
 
      fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET;
668
 
   }
669
 
 
670
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINES, count-start,
671
 
                                              fxVB + start, sizeof(tdfxVertex));
672
 
 
673
 
   /* restore line coords */
674
 
   for (i = start; i < count; i++) {
675
 
      fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET;
676
 
      fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
677
 
   }
678
 
}
679
 
 
680
 
static void tdfx_render_vb_triangles( struct gl_context *ctx,
681
 
                                      GLuint start,
682
 
                                      GLuint count,
683
 
                                      GLuint flags )
684
 
{
685
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
686
 
   tdfxVertex *fxVB = fxMesa->verts;
687
 
   (void) flags;
688
 
 
689
 
   INIT(GL_TRIANGLES);
690
 
 
691
 
#if 0
692
 
   /* [dBorca]
693
 
    * apparently, this causes troubles with some programs (GLExcess);
694
 
    * might be a bug in Glide... However, "grDrawVertexArrayContiguous"
695
 
    * eventually calls "grDrawTriangle" for GR_TRIANGLES, so we're better
696
 
    * off doing it by hand...
697
 
    */
698
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLES, count-start,
699
 
                                              fxVB + start, sizeof(tdfxVertex));
700
 
#else
701
 
   {
702
 
    GLuint j;
703
 
    for (j=start+2; j<count; j+=3) {
704
 
        fxMesa->Glide.grDrawTriangle(fxVB + (j-2), fxVB + (j-1), fxVB + j);
705
 
    }
706
 
   }
707
 
#endif
708
 
}
709
 
 
710
 
 
711
 
static void tdfx_render_vb_tri_strip( struct gl_context *ctx,
712
 
                                      GLuint start,
713
 
                                      GLuint count,
714
 
                                      GLuint flags )
715
 
{
716
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
717
 
   tdfxVertex *fxVB = fxMesa->verts;
718
 
   int mode;
719
 
   (void) flags;
720
 
 
721
 
   INIT(GL_TRIANGLE_STRIP);
722
 
 
723
 
/*     fprintf(stderr, "%s/%d\n", __FUNCTION__, 1<<shift); */
724
 
/*     if(!prevLockLine) abort(); */
725
 
 
726
 
   mode = GR_TRIANGLE_STRIP;
727
 
 
728
 
   fxMesa->Glide.grDrawVertexArrayContiguous( mode, count-start,
729
 
                                              fxVB + start, sizeof(tdfxVertex));
730
 
}
731
 
 
732
 
 
733
 
static void tdfx_render_vb_tri_fan( struct gl_context *ctx,
734
 
                                    GLuint start,
735
 
                                    GLuint count,
736
 
                                    GLuint flags )
737
 
{
738
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
739
 
   tdfxVertex *fxVB = fxMesa->verts;
740
 
   (void) flags;
741
 
 
742
 
   INIT(GL_TRIANGLE_FAN);
743
 
 
744
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start,
745
 
                                              fxVB + start, sizeof(tdfxVertex) );
746
 
}
747
 
 
748
 
static void tdfx_render_vb_quads( struct gl_context *ctx,
749
 
                                       GLuint start,
750
 
                                       GLuint count,
751
 
                                       GLuint flags )
752
 
{
753
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
754
 
   tdfxVertex *fxVB = fxMesa->verts;
755
 
   GLuint i;
756
 
   (void) flags;
757
 
 
758
 
   INIT(GL_QUADS);
759
 
   
760
 
   for (i = start + 3 ; i < count ; i += 4 ) {
761
 
#define VERT(x) (fxVB + (x))
762
 
      tdfxVertex *_v_[4];
763
 
      _v_[0] = VERT(i);
764
 
      _v_[1] = VERT(i-3);
765
 
      _v_[2] = VERT(i-2);
766
 
      _v_[3] = VERT(i-1);
767
 
      fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);
768
 
      /*fxMesa->Glide.grDrawTriangle( VERT(i-3), VERT(i-2), VERT(i) );*/
769
 
      /*fxMesa->Glide.grDrawTriangle( VERT(i-2), VERT(i-1), VERT(i) );*/
770
 
#undef VERT
771
 
   }
772
 
}
773
 
 
774
 
static void tdfx_render_vb_quad_strip( struct gl_context *ctx,
775
 
                                       GLuint start,
776
 
                                       GLuint count,
777
 
                                       GLuint flags )
778
 
{
779
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
780
 
   tdfxVertex *fxVB = fxMesa->verts;
781
 
   (void) flags;
782
 
 
783
 
   INIT(GL_QUAD_STRIP);
784
 
 
785
 
   count -= (count-start)&1;
786
 
 
787
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP,
788
 
                                              count-start, fxVB + start, sizeof(tdfxVertex));
789
 
}
790
 
 
791
 
static void tdfx_render_vb_poly( struct gl_context *ctx,
792
 
                                 GLuint start,
793
 
                                 GLuint count,
794
 
                                 GLuint flags )
795
 
{
796
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
797
 
   tdfxVertex *fxVB = fxMesa->verts;
798
 
   (void) flags;
799
 
 
800
 
   INIT(GL_POLYGON);
801
 
   
802
 
   fxMesa->Glide.grDrawVertexArrayContiguous( GR_POLYGON, count-start,
803
 
                                              fxVB + start, sizeof(tdfxVertex));
804
 
}
805
 
 
806
 
static void tdfx_render_vb_noop( struct gl_context *ctx,
807
 
                                 GLuint start,
808
 
                                 GLuint count,
809
 
                                 GLuint flags )
810
 
{
811
 
   (void) (ctx && start && count && flags);
812
 
}
813
 
 
814
 
static void (*tdfx_render_tab_verts[GL_POLYGON+2])(struct gl_context *,
815
 
                                                   GLuint,
816
 
                                                   GLuint,
817
 
                                                   GLuint) = 
818
 
{
819
 
   tdfx_render_vb_points,
820
 
   tdfx_render_vb_lines,
821
 
   tdfx_render_vb_line_loop,
822
 
   tdfx_render_vb_line_strip,
823
 
   tdfx_render_vb_triangles,
824
 
   tdfx_render_vb_tri_strip,
825
 
   tdfx_render_vb_tri_fan,
826
 
   tdfx_render_vb_quads,
827
 
   tdfx_render_vb_quad_strip,
828
 
   tdfx_render_vb_poly,
829
 
   tdfx_render_vb_noop,
830
 
};
831
 
#undef INIT
832
 
 
833
 
 
834
 
/**********************************************************************/
835
 
/*            Render whole (indexed) begin/end objects                */
836
 
/**********************************************************************/
837
 
 
838
 
 
839
 
#define VERT(x) (tdfxVertex *)(vertptr + (x))
840
 
 
841
 
#define RENDER_POINTS( start, count )           \
842
 
   for ( ; start < count ; start++)             \
843
 
      fxMesa->Glide.grDrawPoint( VERT(ELT(start)) );
844
 
 
845
 
#define RENDER_LINE( v0, v1 ) \
846
 
   fxMesa->Glide.grDrawLine( VERT(v0), VERT(v1) )
847
 
 
848
 
#define RENDER_TRI( v0, v1, v2 )  \
849
 
   fxMesa->Glide.grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) )
850
 
 
851
 
#define RENDER_QUAD( v0, v1, v2, v3 ) \
852
 
   do {                                 \
853
 
      tdfxVertex *_v_[4];               \
854
 
      _v_[0] = VERT(v3);                \
855
 
      _v_[1] = VERT(v0);                \
856
 
      _v_[2] = VERT(v1);                \
857
 
      _v_[3] = VERT(v2);                \
858
 
      fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\
859
 
      /*fxMesa->Glide.grDrawTriangle( VERT(v0), VERT(v1), VERT(v3) );*/\
860
 
      /*fxMesa->Glide.grDrawTriangle( VERT(v1), VERT(v2), VERT(v3) );*/\
861
 
   } while (0)
862
 
 
863
 
#define INIT(x) tdfxRenderPrimitive( ctx, x )
864
 
 
865
 
#undef LOCAL_VARS
866
 
#define LOCAL_VARS                                              \
867
 
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);                  \
868
 
    tdfxVertex *vertptr = fxMesa->verts;                        \
869
 
    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
870
 
    (void) elt;
871
 
 
872
 
#define RESET_STIPPLE 
873
 
#define RESET_OCCLUSION 
874
 
#define PRESERVE_VB_DEFS
875
 
 
876
 
/* Elts, no clipping.
877
 
 */
878
 
#undef ELT
879
 
#undef TAG
880
 
#define TAG(x) tdfx_##x##_elts
881
 
#define ELT(x) elt[x]
882
 
#include "tnl_dd/t_dd_rendertmp.h"
883
 
 
884
 
/* Verts, no clipping.
885
 
 */
886
 
#undef ELT
887
 
#undef TAG
888
 
#define TAG(x) tdfx_##x##_verts
889
 
#define ELT(x) x
890
 
/*#include "tnl_dd/t_dd_rendertmp.h"*/
891
 
 
892
 
 
893
 
 
894
 
/**********************************************************************/
895
 
/*                   Render clipped primitives                        */
896
 
/**********************************************************************/
897
 
 
898
 
 
899
 
 
900
 
static void tdfxRenderClippedPoly( struct gl_context *ctx, const GLuint *elts, 
901
 
                                   GLuint n )
902
 
{
903
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
904
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
905
 
   struct vertex_buffer *VB = &tnl->vb;
906
 
   GLuint prim = fxMesa->render_primitive;
907
 
 
908
 
   /* Render the new vertices as an unclipped polygon. 
909
 
    */
910
 
   {
911
 
      GLuint *tmp = VB->Elts;
912
 
      VB->Elts = (GLuint *)elts;
913
 
      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
914
 
      VB->Elts = tmp;
915
 
   }
916
 
 
917
 
   /* Restore the render primitive
918
 
    */
919
 
   if (prim != GL_POLYGON)
920
 
      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
921
 
}
922
 
 
923
 
static void tdfxRenderClippedLine( struct gl_context *ctx, GLuint ii, GLuint jj )
924
 
{
925
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
926
 
   tnl->Driver.Render.Line( ctx, ii, jj );
927
 
}
928
 
 
929
 
static void tdfxFastRenderClippedPoly( struct gl_context *ctx, const GLuint *elts, 
930
 
                                       GLuint n )
931
 
{
932
 
   int i;
933
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
934
 
   tdfxVertex *vertptr = fxMesa->verts;
935
 
   if (n == 3) {
936
 
      fxMesa->Glide.grDrawTriangle( VERT(elts[0]), VERT(elts[1]), VERT(elts[2]) );
937
 
   } else if (n <= 32) {
938
 
      tdfxVertex *newvptr[32];
939
 
      for (i = 0 ; i < n ; i++) {
940
 
         newvptr[i] = VERT(elts[i]);
941
 
      }
942
 
      fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, n, newvptr);
943
 
   } else {
944
 
      const tdfxVertex *start = VERT(elts[0]);
945
 
      for (i = 2 ; i < n ; i++) {
946
 
         fxMesa->Glide.grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) );
947
 
      }
948
 
   }
949
 
}
950
 
 
951
 
/**********************************************************************/
952
 
/*                    Choose render functions                         */
953
 
/**********************************************************************/
954
 
 
955
 
 
956
 
#define POINT_FALLBACK (DD_POINT_SMOOTH)
957
 
#define LINE_FALLBACK (DD_LINE_STIPPLE)
958
 
#define TRI_FALLBACK (DD_TRI_SMOOTH)
959
 
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE)
960
 
#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \
961
 
                          DD_TRI_UNFILLED)
962
 
 
963
 
 
964
 
/* All state referenced below:
965
 
 */
966
 
#define _TDFX_NEW_RENDERSTATE (_DD_NEW_POINT_SMOOTH |           \
967
 
                               _DD_NEW_LINE_STIPPLE |           \
968
 
                               _DD_NEW_TRI_SMOOTH |             \
969
 
                               _DD_NEW_FLATSHADE |              \
970
 
                               _DD_NEW_TRI_UNFILLED |           \
971
 
                               _DD_NEW_TRI_LIGHT_TWOSIDE |      \
972
 
                               _DD_NEW_TRI_OFFSET |             \
973
 
                               _DD_NEW_TRI_STIPPLE |            \
974
 
                               _NEW_POLYGONSTIPPLE)
975
 
 
976
 
 
977
 
static void tdfxChooseRenderState(struct gl_context *ctx)
978
 
{
979
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
980
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
981
 
   GLuint flags = ctx->_TriangleCaps;
982
 
   GLuint index = 0;
983
 
 
984
 
   if (0) {
985
 
      fxMesa->draw_point = tdfx_draw_point;
986
 
      fxMesa->draw_line = tdfx_draw_line;
987
 
      fxMesa->draw_triangle = tdfx_draw_triangle;
988
 
      index |= TDFX_FALLBACK_BIT;
989
 
   }
990
 
 
991
 
   if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
992
 
      if (flags & ANY_RASTER_FLAGS) {
993
 
         if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= TDFX_TWOSIDE_BIT;
994
 
         if (flags & DD_TRI_OFFSET)           index |= TDFX_OFFSET_BIT;
995
 
         if (flags & DD_TRI_UNFILLED)         index |= TDFX_UNFILLED_BIT;
996
 
         if (flags & DD_FLATSHADE)            index |= TDFX_FLAT_BIT;
997
 
      }
998
 
 
999
 
      fxMesa->draw_point = tdfx_draw_point;
1000
 
      fxMesa->draw_line = tdfx_draw_line;
1001
 
      fxMesa->draw_triangle = tdfx_draw_triangle;
1002
 
 
1003
 
      /* Hook in fallbacks for specific primitives.
1004
 
       *
1005
 
       * DD_TRI_UNFILLED is here because the unfilled_tri functions use
1006
 
       * fxMesa->draw_tri *always*, and thus can't use the multipass
1007
 
       * approach to cliprects.
1008
 
       *
1009
 
       */
1010
 
      if (flags & (POINT_FALLBACK|
1011
 
                   LINE_FALLBACK|
1012
 
                   TRI_FALLBACK|
1013
 
                   DD_TRI_STIPPLE|
1014
 
                   DD_TRI_UNFILLED))
1015
 
      {
1016
 
         if (flags & POINT_FALLBACK)
1017
 
            fxMesa->draw_point = tdfx_fallback_point;
1018
 
 
1019
 
         if (flags & LINE_FALLBACK)
1020
 
            fxMesa->draw_line = tdfx_fallback_line;
1021
 
 
1022
 
         if (flags & TRI_FALLBACK)
1023
 
            fxMesa->draw_triangle = tdfx_fallback_tri;
1024
 
 
1025
 
         if ((flags & DD_TRI_STIPPLE) && !fxMesa->haveHwStipple)
1026
 
            fxMesa->draw_triangle = tdfx_fallback_tri;
1027
 
 
1028
 
         index |= TDFX_FALLBACK_BIT;
1029
 
      }
1030
 
   }
1031
 
 
1032
 
   if (fxMesa->RenderIndex != index) {
1033
 
      fxMesa->RenderIndex = index;
1034
 
 
1035
 
      tnl->Driver.Render.Points = rast_tab[index].points;
1036
 
      tnl->Driver.Render.Line = rast_tab[index].line;
1037
 
      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
1038
 
      tnl->Driver.Render.Quad = rast_tab[index].quad;
1039
 
 
1040
 
      if (index == 0) {
1041
 
         tnl->Driver.Render.PrimTabVerts = tdfx_render_tab_verts;
1042
 
         tnl->Driver.Render.PrimTabElts = tdfx_render_tab_elts;
1043
 
         tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
1044
 
         tnl->Driver.Render.ClippedPolygon = tdfxFastRenderClippedPoly;
1045
 
      } else {
1046
 
         tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
1047
 
         tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
1048
 
         tnl->Driver.Render.ClippedLine = tdfxRenderClippedLine;
1049
 
         tnl->Driver.Render.ClippedPolygon = tdfxRenderClippedPoly;
1050
 
      }
1051
 
   }
1052
 
}
1053
 
 
1054
 
/**********************************************************************/
1055
 
/*                Use multipass rendering for cliprects               */
1056
 
/**********************************************************************/
1057
 
 
1058
 
 
1059
 
 
1060
 
/* TODO: Benchmark this.
1061
 
 * TODO: Use single back-buffer cliprect where possible.  
1062
 
 * NOTE: <pass> starts at 1, not zero!
1063
 
 */
1064
 
static GLboolean multipass_cliprect( struct gl_context *ctx, GLuint pass )
1065
 
{
1066
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1067
 
   if (pass >= fxMesa->numClipRects)
1068
 
      return GL_FALSE;
1069
 
   else {   
1070
 
      fxMesa->Glide.grClipWindow(fxMesa->pClipRects[pass].x1,
1071
 
                   fxMesa->screen_height - fxMesa->pClipRects[pass].y2,
1072
 
                   fxMesa->pClipRects[pass].x2,
1073
 
                   fxMesa->screen_height - fxMesa->pClipRects[pass].y1);
1074
 
      
1075
 
      return GL_TRUE;
1076
 
   }
1077
 
}
1078
 
 
1079
 
 
1080
 
/**********************************************************************/
1081
 
/*                Runtime render state and callbacks                  */
1082
 
/**********************************************************************/
1083
 
 
1084
 
static void tdfxRunPipeline( struct gl_context *ctx )
1085
 
{
1086
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1087
 
 
1088
 
   if (fxMesa->new_state) {
1089
 
      tdfxDDUpdateHwState( ctx );
1090
 
   }
1091
 
 
1092
 
   if (!fxMesa->Fallback && fxMesa->new_gl_state) {
1093
 
      if (fxMesa->new_gl_state & _TDFX_NEW_RASTERSETUP)
1094
 
         tdfxChooseVertexState( ctx );
1095
 
      
1096
 
      if (fxMesa->new_gl_state & _TDFX_NEW_RENDERSTATE)
1097
 
         tdfxChooseRenderState( ctx );
1098
 
      
1099
 
      fxMesa->new_gl_state = 0;
1100
 
   }
1101
 
 
1102
 
   _tnl_run_pipeline( ctx );
1103
 
}
1104
 
 
1105
 
 
1106
 
static void tdfxRenderStart( struct gl_context *ctx )
1107
 
{
1108
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
1109
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1110
 
 
1111
 
   tdfxCheckTexSizes( ctx );
1112
 
 
1113
 
   LOCK_HARDWARE(fxMesa);
1114
 
 
1115
 
   /* Make sure vertex format changes get uploaded before we start
1116
 
    * sending triangles.  
1117
 
    */
1118
 
   if (fxMesa->dirty) {
1119
 
      tdfxEmitHwStateLocked( fxMesa );
1120
 
   }
1121
 
 
1122
 
   if (fxMesa->numClipRects && !(fxMesa->RenderIndex & TDFX_FALLBACK_BIT)) {
1123
 
      fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1,
1124
 
                   fxMesa->screen_height - fxMesa->pClipRects[0].y2,
1125
 
                   fxMesa->pClipRects[0].x2,
1126
 
                   fxMesa->screen_height - fxMesa->pClipRects[0].y1);
1127
 
      if (fxMesa->numClipRects > 1)
1128
 
         tnl->Driver.Render.Multipass = multipass_cliprect;
1129
 
      else
1130
 
         tnl->Driver.Render.Multipass = NULL;
1131
 
   }
1132
 
   else
1133
 
      tnl->Driver.Render.Multipass = NULL;
1134
 
}
1135
 
 
1136
 
 
1137
 
 
1138
 
/* Always called between RenderStart and RenderFinish --> We already
1139
 
 * hold the lock.
1140
 
 */
1141
 
static void tdfxRasterPrimitive( struct gl_context *ctx, GLenum prim )
1142
 
{
1143
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
1144
 
 
1145
 
   FLUSH_BATCH( fxMesa );
1146
 
 
1147
 
   fxMesa->raster_primitive = prim;
1148
 
 
1149
 
   tdfxUpdateCull(ctx);
1150
 
   if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) {
1151
 
      fxMesa->Glide.grCullMode( fxMesa->CullMode );
1152
 
      fxMesa->dirty &= ~TDFX_UPLOAD_CULL;
1153
 
   }
1154
 
 
1155
 
   tdfxUpdateStipple(ctx);
1156
 
   if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE ) {
1157
 
      fxMesa->Glide.grStipplePattern ( fxMesa->Stipple.Pattern );
1158
 
      fxMesa->Glide.grStippleMode ( fxMesa->Stipple.Mode );
1159
 
      fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE;
1160
 
   }
1161
 
}
1162
 
 
1163
 
 
1164
 
 
1165
 
/* Determine the rasterized primitive when not drawing unfilled 
1166
 
 * polygons.
1167
 
 *
1168
 
 * Used only for the default render stage which always decomposes
1169
 
 * primitives to trianges/lines/points.  For the accelerated stage,
1170
 
 * which renders strips as strips, the equivalent calculations are
1171
 
 * performed in tdfx_render.c.
1172
 
 */
1173
 
static void tdfxRenderPrimitive( struct gl_context *ctx, GLenum prim )
1174
 
{
1175
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1176
 
   GLuint rprim = reduced_prim[prim];
1177
 
 
1178
 
   fxMesa->render_primitive = prim;
1179
 
 
1180
 
   if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
1181
 
      return;
1182
 
       
1183
 
   if (fxMesa->raster_primitive != rprim) {
1184
 
      tdfxRasterPrimitive( ctx, rprim );
1185
 
   }
1186
 
}
1187
 
 
1188
 
static void tdfxRenderFinish( struct gl_context *ctx )
1189
 
{
1190
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1191
 
 
1192
 
   if (fxMesa->RenderIndex & TDFX_FALLBACK_BIT)
1193
 
      _swrast_flush( ctx );
1194
 
 
1195
 
   UNLOCK_HARDWARE(fxMesa);
1196
 
}
1197
 
 
1198
 
 
1199
 
/**********************************************************************/
1200
 
/*               Manage total rasterization fallbacks                 */
1201
 
/**********************************************************************/
1202
 
 
1203
 
static char *fallbackStrings[] = {
1204
 
   "3D/Rect/Cube Texture map",
1205
 
   "glDrawBuffer(GL_FRONT_AND_BACK)",
1206
 
   "Separate specular color",
1207
 
   "glEnable/Disable(GL_STENCIL_TEST)",
1208
 
   "glRenderMode(selection or feedback)",
1209
 
   "glLogicOp()",
1210
 
   "Texture env mode",
1211
 
   "Texture border",
1212
 
   "glColorMask",
1213
 
   "blend mode",
1214
 
   "line stipple",
1215
 
   "Rasterization disable"
1216
 
};
1217
 
 
1218
 
 
1219
 
static char *getFallbackString(GLuint bit)
1220
 
{
1221
 
   int i = 0;
1222
 
   while (bit > 1) {
1223
 
      i++;
1224
 
      bit >>= 1;
1225
 
   }
1226
 
   return fallbackStrings[i];
1227
 
}
1228
 
 
1229
 
 
1230
 
void tdfxFallback( struct gl_context *ctx, GLuint bit, GLboolean mode )
1231
 
{
1232
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
1233
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1234
 
   GLuint oldfallback = fxMesa->Fallback;
1235
 
 
1236
 
   if (mode) {
1237
 
      fxMesa->Fallback |= bit;
1238
 
      if (oldfallback == 0) {
1239
 
         /*printf("Go to software rendering, bit = 0x%x\n", bit);*/
1240
 
         FLUSH_BATCH(fxMesa);
1241
 
         _swsetup_Wakeup( ctx );
1242
 
         fxMesa->RenderIndex = ~0;
1243
 
         if (TDFX_DEBUG & DEBUG_VERBOSE_FALL) {
1244
 
            fprintf(stderr, "Tdfx begin software fallback: 0x%x %s\n",
1245
 
                    bit, getFallbackString(bit));
1246
 
         }
1247
 
      }
1248
 
   }
1249
 
   else {
1250
 
      fxMesa->Fallback &= ~bit;
1251
 
      if (oldfallback == bit) {
1252
 
         /*printf("Go to hardware rendering, bit = 0x%x\n", bit);*/
1253
 
         _swrast_flush( ctx );
1254
 
         tnl->Driver.Render.Start = tdfxRenderStart;
1255
 
         tnl->Driver.Render.PrimitiveNotify = tdfxRenderPrimitive;
1256
 
         tnl->Driver.Render.Finish = tdfxRenderFinish;
1257
 
         tnl->Driver.Render.BuildVertices = tdfxBuildVertices;
1258
 
         fxMesa->new_gl_state |= (_TDFX_NEW_RENDERSTATE|
1259
 
                                  _TDFX_NEW_RASTERSETUP);
1260
 
         if (TDFX_DEBUG & DEBUG_VERBOSE_FALL) {
1261
 
            fprintf(stderr, "Tdfx end software fallback: 0x%x %s\n",
1262
 
                    bit, getFallbackString(bit));
1263
 
         }
1264
 
      }
1265
 
   }
1266
 
}
1267
 
 
1268
 
 
1269
 
void tdfxDDInitTriFuncs( struct gl_context *ctx )
1270
 
{
1271
 
   TNLcontext *tnl = TNL_CONTEXT(ctx);
1272
 
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
1273
 
   static int firsttime = 1;
1274
 
 
1275
 
   if (firsttime) {
1276
 
      init_rast_tab();
1277
 
      firsttime = 0;
1278
 
   }
1279
 
 
1280
 
   fxMesa->RenderIndex = ~0;
1281
 
        
1282
 
   tnl->Driver.RunPipeline              = tdfxRunPipeline;
1283
 
   tnl->Driver.Render.Start             = tdfxRenderStart;
1284
 
   tnl->Driver.Render.Finish            = tdfxRenderFinish; 
1285
 
   tnl->Driver.Render.PrimitiveNotify   = tdfxRenderPrimitive;
1286
 
   tnl->Driver.Render.ResetLineStipple  = _swrast_ResetLineStipple;
1287
 
   tnl->Driver.Render.BuildVertices     = tdfxBuildVertices;
1288
 
   tnl->Driver.Render.Multipass         = NULL;
1289
 
 
1290
 
   (void) tdfx_print_vertex;
1291
 
}