~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/GL/mesa/src/drv/mga/mgatris.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2000-2001 VA Linux Systems, Inc.
 
3
 * All Rights Reserved.
 
4
 *
 
5
 * Permission is hereby granted, free of charge, to any person obtaining a
 
6
 * copy of this software and associated documentation files (the "Software"),
 
7
 * to deal in the Software without restriction, including without limitation
 
8
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 
9
 * license, and/or sell copies of the Software, and to permit persons to whom
 
10
 * the Software is furnished to do so, subject to the following conditions:
 
11
 *
 
12
 * The above copyright notice and this permission notice (including the next
 
13
 * paragraph) shall be included in all copies or substantial portions of the
 
14
 * Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
 
19
 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
22
 * OTHER DEALINGS IN THE SOFTWARE.
 
23
 *
 
24
 * Authors:
 
25
 *    Keith Whitwell <keith@tungstengraphics.com>
 
26
 */
 
27
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.10 2002/10/30 12:51:36 alanh Exp $ */
 
28
 
 
29
#include <stdio.h>
 
30
#include <math.h>
 
31
 
 
32
#include "mtypes.h"
 
33
#include "macros.h"
 
34
#include "colormac.h"
 
35
#include "swrast/swrast.h"
 
36
#include "swrast_setup/swrast_setup.h"
 
37
#include "tnl/t_context.h"
 
38
#include "tnl/t_pipeline.h"
 
39
 
 
40
#include "mm.h"
 
41
#include "mgacontext.h"
 
42
#include "mgaioctl.h"
 
43
#include "mgatris.h"
 
44
#include "mgavb.h"
 
45
#include "mgastate.h"
 
46
 
 
47
 
 
48
static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim );
 
49
 
 
50
/***********************************************************************
 
51
 *                 Functions to draw basic primitives                  *
 
52
 ***********************************************************************/
 
53
 
 
54
 
 
55
#if defined (USE_X86_ASM)
 
56
#define EMIT_VERT( j, vb, vertex_size, v )              \
 
57
do {    int __tmp;                                      \
 
58
        __asm__ __volatile__( "rep ; movsl"             \
 
59
                         : "=%c" (j), "=D" (vb), "=S" (__tmp)           \
 
60
                         : "0" (vertex_size),           \
 
61
                           "D" ((long)vb),              \
 
62
                           "S" ((long)v));              \
 
63
} while (0)
 
64
#else
 
65
#define EMIT_VERT( j, vb, vertex_size, v )      \
 
66
do {                                            \
 
67
   for ( j = 0 ; j < vertex_size ; j++ )        \
 
68
      vb[j] = (v)->ui[j];                       \
 
69
   vb += vertex_size;                           \
 
70
} while (0)
 
71
#endif
 
72
 
 
73
static void __inline__ mga_draw_triangle( mgaContextPtr mmesa,
 
74
                                           mgaVertexPtr v0,
 
75
                                           mgaVertexPtr v1,
 
76
                                           mgaVertexPtr v2 )
 
77
{
 
78
   GLuint vertex_size = mmesa->vertex_size;
 
79
   GLuint *vb = mgaAllocDmaLow( mmesa, 3 * 4 * vertex_size );
 
80
   int j;
 
81
 
 
82
   EMIT_VERT( j, vb, vertex_size, v0 );
 
83
   EMIT_VERT( j, vb, vertex_size, v1 );
 
84
   EMIT_VERT( j, vb, vertex_size, v2 );
 
85
}
 
86
 
 
87
 
 
88
static void __inline__ mga_draw_quad( mgaContextPtr mmesa,
 
89
                                       mgaVertexPtr v0,
 
90
                                       mgaVertexPtr v1,
 
91
                                       mgaVertexPtr v2,
 
92
                                       mgaVertexPtr v3 )
 
93
{
 
94
   GLuint vertex_size = mmesa->vertex_size;
 
95
   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
 
96
   int j;
 
97
 
 
98
   EMIT_VERT( j, vb, vertex_size, v0 );
 
99
   EMIT_VERT( j, vb, vertex_size, v1 );
 
100
   EMIT_VERT( j, vb, vertex_size, v3 );
 
101
   EMIT_VERT( j, vb, vertex_size, v1 );
 
102
   EMIT_VERT( j, vb, vertex_size, v2 );
 
103
   EMIT_VERT( j, vb, vertex_size, v3 );
 
104
}
 
105
 
 
106
 
 
107
static __inline__ void mga_draw_point( mgaContextPtr mmesa,
 
108
                                        mgaVertexPtr tmp )
 
109
{
 
110
   GLfloat sz = mmesa->glCtx->Point._Size * .5;
 
111
   int vertex_size = mmesa->vertex_size;
 
112
   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
 
113
   int j;
 
114
   
 
115
#if 0
 
116
   v0->v.x += PNT_X_OFFSET - TRI_X_OFFSET;
 
117
   v0->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET;
 
118
#endif
 
119
 
 
120
   /* Draw a point as two triangles.
 
121
    */
 
122
   *(float *)&vb[0] = tmp->v.x - sz;
 
123
   *(float *)&vb[1] = tmp->v.y - sz;
 
124
   for (j = 2 ; j < vertex_size ; j++) 
 
125
      vb[j] = tmp->ui[j];
 
126
   vb += vertex_size;
 
127
 
 
128
   *(float *)&vb[0] = tmp->v.x + sz;
 
129
   *(float *)&vb[1] = tmp->v.y - sz;
 
130
   for (j = 2 ; j < vertex_size ; j++) 
 
131
      vb[j] = tmp->ui[j];
 
132
   vb += vertex_size;
 
133
 
 
134
   *(float *)&vb[0] = tmp->v.x + sz;
 
135
   *(float *)&vb[1] = tmp->v.y + sz;
 
136
   for (j = 2 ; j < vertex_size ; j++) 
 
137
      vb[j] = tmp->ui[j];
 
138
   vb += vertex_size;
 
139
 
 
140
   *(float *)&vb[0] = tmp->v.x + sz;
 
141
   *(float *)&vb[1] = tmp->v.y + sz;
 
142
   for (j = 2 ; j < vertex_size ; j++) 
 
143
      vb[j] = tmp->ui[j];
 
144
   vb += vertex_size;
 
145
 
 
146
   *(float *)&vb[0] = tmp->v.x - sz;
 
147
   *(float *)&vb[1] = tmp->v.y + sz;
 
148
   for (j = 2 ; j < vertex_size ; j++) 
 
149
      vb[j] = tmp->ui[j];
 
150
   vb += vertex_size;
 
151
 
 
152
   *(float *)&vb[0] = tmp->v.x - sz;
 
153
   *(float *)&vb[1] = tmp->v.y - sz;
 
154
   for (j = 2 ; j < vertex_size ; j++) 
 
155
      vb[j] = tmp->ui[j];
 
156
 
 
157
#if 0
 
158
   v0->v.x -= PNT_X_OFFSET - TRI_X_OFFSET;
 
159
   v0->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET;
 
160
#endif
 
161
}
 
162
 
 
163
 
 
164
static __inline__ void mga_draw_line( mgaContextPtr mmesa,
 
165
                                      mgaVertexPtr v0,
 
166
                                      mgaVertexPtr v1 )
 
167
{
 
168
   GLuint vertex_size = mmesa->vertex_size;
 
169
   GLuint *vb = mgaAllocDmaLow( mmesa, 6 * 4 * vertex_size );
 
170
   GLfloat dx, dy, ix, iy;
 
171
   GLfloat width = mmesa->glCtx->Line._Width;
 
172
   GLint j;
 
173
 
 
174
#if 0
 
175
   v0->v.x += LINE_X_OFFSET - TRI_X_OFFSET;
 
176
   v0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET;
 
177
   v1->v.x += LINE_X_OFFSET - TRI_X_OFFSET;
 
178
   v1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET;
 
179
#endif
 
180
 
 
181
   dx = v0->v.x - v1->v.x;
 
182
   dy = v0->v.y - v1->v.y;
 
183
   
 
184
   ix = width * .5; iy = 0;
 
185
   if (dx * dx > dy * dy) {
 
186
      iy = ix; ix = 0;
 
187
   }
 
188
 
 
189
   *(float *)&vb[0] = v0->v.x - ix;
 
190
   *(float *)&vb[1] = v0->v.y - iy;
 
191
   for (j = 2 ; j < vertex_size ; j++) 
 
192
      vb[j] = v0->ui[j];
 
193
   vb += vertex_size;
 
194
 
 
195
   *(float *)&vb[0] = v1->v.x + ix;
 
196
   *(float *)&vb[1] = v1->v.y + iy;
 
197
   for (j = 2 ; j < vertex_size ; j++) 
 
198
      vb[j] = v1->ui[j];
 
199
   vb += vertex_size;
 
200
 
 
201
   *(float *)&vb[0] = v0->v.x + ix;
 
202
   *(float *)&vb[1] = v0->v.y + iy;
 
203
   for (j = 2 ; j < vertex_size ; j++) 
 
204
      vb[j] = v0->ui[j];
 
205
   vb += vertex_size;
 
206
         
 
207
   *(float *)&vb[0] = v0->v.x - ix;
 
208
   *(float *)&vb[1] = v0->v.y - iy;
 
209
   for (j = 2 ; j < vertex_size ; j++) 
 
210
      vb[j] = v0->ui[j];
 
211
   vb += vertex_size;
 
212
 
 
213
   *(float *)&vb[0] = v1->v.x - ix;
 
214
   *(float *)&vb[1] = v1->v.y - iy;
 
215
   for (j = 2 ; j < vertex_size ; j++) 
 
216
      vb[j] = v1->ui[j];
 
217
   vb += vertex_size;
 
218
 
 
219
   *(float *)&vb[0] = v1->v.x + ix;
 
220
   *(float *)&vb[1] = v1->v.y + iy;
 
221
   for (j = 2 ; j < vertex_size ; j++) 
 
222
      vb[j] = v1->ui[j];
 
223
   vb += vertex_size;
 
224
 
 
225
#if 0
 
226
   v0->v.x -= LINE_X_OFFSET - TRI_X_OFFSET;
 
227
   v0->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
 
228
   v1->v.x -= LINE_X_OFFSET - TRI_X_OFFSET;
 
229
   v1->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET;
 
230
#endif
 
231
}
 
232
 
 
233
/***********************************************************************
 
234
 *          Macros for t_dd_tritmp.h to draw basic primitives          *
 
235
 ***********************************************************************/
 
236
 
 
237
#define TRI( a, b, c )                          \
 
238
do {                                            \
 
239
   if (DO_FALLBACK)                             \
 
240
      mmesa->draw_tri( mmesa, a, b, c );        \
 
241
   else                                         \
 
242
      mga_draw_triangle( mmesa, a, b, c );      \
 
243
} while (0)
 
244
 
 
245
#define QUAD( a, b, c, d )                      \
 
246
do {                                            \
 
247
   if (DO_FALLBACK) {                           \
 
248
      mmesa->draw_tri( mmesa, a, b, d );        \
 
249
      mmesa->draw_tri( mmesa, b, c, d );        \
 
250
   } else {                                     \
 
251
      mga_draw_quad( mmesa, a, b, c, d );       \
 
252
   }                                            \
 
253
} while (0)
 
254
 
 
255
#define LINE( v0, v1 )                          \
 
256
do {                                            \
 
257
   if (DO_FALLBACK)                             \
 
258
      mmesa->draw_line( mmesa, v0, v1 );        \
 
259
   else {                                       \
 
260
      mga_draw_line( mmesa, v0, v1 );           \
 
261
   }                                            \
 
262
} while (0)
 
263
 
 
264
#define POINT( v0 )                             \
 
265
do {                                            \
 
266
   if (DO_FALLBACK)                             \
 
267
      mmesa->draw_point( mmesa, v0 );           \
 
268
   else {                                       \
 
269
      mga_draw_point( mmesa, v0 );              \
 
270
   }                                            \
 
271
} while (0)
 
272
 
 
273
 
 
274
/***********************************************************************
 
275
 *              Fallback to swrast for basic primitives                *
 
276
 ***********************************************************************/
 
277
 
 
278
/* This code is hit only when a mix of accelerated and unaccelerated
 
279
 * primitives are being drawn, and only for the unaccelerated
 
280
 * primitives.  
 
281
 */
 
282
 
 
283
static void 
 
284
mga_fallback_tri( mgaContextPtr mmesa, 
 
285
                   mgaVertex *v0, 
 
286
                   mgaVertex *v1, 
 
287
                   mgaVertex *v2 )
 
288
{
 
289
   GLcontext *ctx = mmesa->glCtx;
 
290
   SWvertex v[3];
 
291
   mga_translate_vertex( ctx, v0, &v[0] );
 
292
   mga_translate_vertex( ctx, v1, &v[1] );
 
293
   mga_translate_vertex( ctx, v2, &v[2] );
 
294
   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
 
295
}
 
296
 
 
297
 
 
298
static void 
 
299
mga_fallback_line( mgaContextPtr mmesa,
 
300
                    mgaVertex *v0,
 
301
                    mgaVertex *v1 )
 
302
{
 
303
   GLcontext *ctx = mmesa->glCtx;
 
304
   SWvertex v[2];
 
305
   mga_translate_vertex( ctx, v0, &v[0] );
 
306
   mga_translate_vertex( ctx, v1, &v[1] );
 
307
   _swrast_Line( ctx, &v[0], &v[1] );
 
308
}
 
309
 
 
310
 
 
311
static void 
 
312
mga_fallback_point( mgaContextPtr mmesa, 
 
313
                     mgaVertex *v0 )
 
314
{
 
315
   GLcontext *ctx = mmesa->glCtx;
 
316
   SWvertex v[1];
 
317
   mga_translate_vertex( ctx, v0, &v[0] );
 
318
   _swrast_Point( ctx, &v[0] );
 
319
}
 
320
 
 
321
/***********************************************************************
 
322
 *              Build render functions from dd templates               *
 
323
 ***********************************************************************/
 
324
 
 
325
 
 
326
#define MGA_UNFILLED_BIT    0x1
 
327
#define MGA_OFFSET_BIT      0x2
 
328
#define MGA_TWOSIDE_BIT     0x4
 
329
#define MGA_FLAT_BIT        0x8 /* mga can't flatshade? */
 
330
#define MGA_FALLBACK_BIT    0x10
 
331
#define MGA_MAX_TRIFUNC     0x20
 
332
 
 
333
static struct {
 
334
   points_func          points;
 
335
   line_func            line;
 
336
   triangle_func        triangle;
 
337
   quad_func            quad;
 
338
} rast_tab[MGA_MAX_TRIFUNC];
 
339
 
 
340
#define DO_FALLBACK (IND & MGA_FALLBACK_BIT)
 
341
#define DO_OFFSET   (IND & MGA_OFFSET_BIT)
 
342
#define DO_UNFILLED (IND & MGA_UNFILLED_BIT)
 
343
#define DO_TWOSIDE  (IND & MGA_TWOSIDE_BIT)
 
344
#define DO_FLAT     (IND & MGA_FLAT_BIT)
 
345
#define DO_TRI       1
 
346
#define DO_QUAD      1
 
347
#define DO_LINE      1
 
348
#define DO_POINTS    1
 
349
#define DO_FULL_QUAD 1
 
350
 
 
351
#define HAVE_RGBA         1
 
352
#define HAVE_BACK_COLORS  0
 
353
#define HAVE_SPEC         1
 
354
#define HAVE_HW_FLATSHADE 0
 
355
#define VERTEX mgaVertex
 
356
#define TAB rast_tab
 
357
 
 
358
#define MGA_COLOR( dst, src )                   \
 
359
do {                                            \
 
360
   dst[0] = src[2];                             \
 
361
   dst[1] = src[1];                             \
 
362
   dst[2] = src[0];                             \
 
363
   dst[3] = src[3];                             \
 
364
} while (0)
 
365
 
 
366
#define MGA_SPEC( dst, src )                    \
 
367
do {                                            \
 
368
   dst[0] = src[2];                             \
 
369
   dst[1] = src[1];                             \
 
370
   dst[2] = src[0];                             \
 
371
} while (0)
 
372
 
 
373
#define DEPTH_SCALE mmesa->depth_scale
 
374
#define UNFILLED_TRI unfilled_tri
 
375
#define UNFILLED_QUAD unfilled_quad
 
376
#define VERT_X(_v) _v->v.x
 
377
#define VERT_Y(_v) _v->v.y
 
378
#define VERT_Z(_v) _v->v.z
 
379
#define AREA_IS_CCW( a ) (a > 0)
 
380
#define GET_VERTEX(e) (mmesa->verts + (e<<mmesa->vertex_stride_shift))
 
381
 
 
382
#define VERT_SET_RGBA( v, c )  MGA_COLOR( v->ub4[4], c )
 
383
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
 
384
#define VERT_SAVE_RGBA( idx )  color[idx] = v[idx]->ui[4]
 
385
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]   
 
386
 
 
387
#define VERT_SET_SPEC( v, c )  MGA_SPEC( v->ub4[5], c )
 
388
#define VERT_COPY_SPEC( v0, v1 ) COPY_3V(v0->ub4[5], v1->ub4[5])
 
389
#define VERT_SAVE_SPEC( idx )  spec[idx] = v[idx]->ui[5]
 
390
#define VERT_RESTORE_SPEC( idx ) v[idx]->ui[5] = spec[idx]   
 
391
 
 
392
#define LOCAL_VARS(n)                                   \
 
393
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);              \
 
394
   GLuint color[n], spec[n];                            \
 
395
   (void) color; (void) spec;
 
396
 
 
397
 
 
398
 
 
399
/***********************************************************************
 
400
 *            Functions to draw basic unfilled primitives              *
 
401
 ***********************************************************************/
 
402
 
 
403
#define RASTERIZE(x) if (mmesa->raster_primitive != x) \
 
404
                        mgaRasterPrimitive( ctx, x, MGA_WA_TRIANGLES )
 
405
#define RENDER_PRIMITIVE mmesa->render_primitive
 
406
#define IND MGA_FALLBACK_BIT
 
407
#define TAG(x) x
 
408
#include "tnl_dd/t_dd_unfilled.h"
 
409
#undef IND
 
410
 
 
411
/***********************************************************************
 
412
 *                 Functions to draw GL primitives                     *
 
413
 ***********************************************************************/
 
414
 
 
415
#define IND (0)
 
416
#define TAG(x) x
 
417
#include "tnl_dd/t_dd_tritmp.h"
 
418
 
 
419
#define IND (MGA_OFFSET_BIT)
 
420
#define TAG(x) x##_offset
 
421
#include "tnl_dd/t_dd_tritmp.h"
 
422
 
 
423
#define IND (MGA_TWOSIDE_BIT)
 
424
#define TAG(x) x##_twoside
 
425
#include "tnl_dd/t_dd_tritmp.h"
 
426
 
 
427
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT)
 
428
#define TAG(x) x##_twoside_offset
 
429
#include "tnl_dd/t_dd_tritmp.h"
 
430
 
 
431
#define IND (MGA_UNFILLED_BIT)
 
432
#define TAG(x) x##_unfilled
 
433
#include "tnl_dd/t_dd_tritmp.h"
 
434
 
 
435
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT)
 
436
#define TAG(x) x##_offset_unfilled
 
437
#include "tnl_dd/t_dd_tritmp.h"
 
438
 
 
439
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT)
 
440
#define TAG(x) x##_twoside_unfilled
 
441
#include "tnl_dd/t_dd_tritmp.h"
 
442
 
 
443
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT)
 
444
#define TAG(x) x##_twoside_offset_unfilled
 
445
#include "tnl_dd/t_dd_tritmp.h"
 
446
 
 
447
#define IND (MGA_FALLBACK_BIT)
 
448
#define TAG(x) x##_fallback
 
449
#include "tnl_dd/t_dd_tritmp.h"
 
450
 
 
451
#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT)
 
452
#define TAG(x) x##_offset_fallback
 
453
#include "tnl_dd/t_dd_tritmp.h"
 
454
 
 
455
#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT)
 
456
#define TAG(x) x##_twoside_fallback
 
457
#include "tnl_dd/t_dd_tritmp.h"
 
458
 
 
459
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT)
 
460
#define TAG(x) x##_twoside_offset_fallback
 
461
#include "tnl_dd/t_dd_tritmp.h"
 
462
 
 
463
#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
 
464
#define TAG(x) x##_unfilled_fallback
 
465
#include "tnl_dd/t_dd_tritmp.h"
 
466
 
 
467
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
 
468
#define TAG(x) x##_offset_unfilled_fallback
 
469
#include "tnl_dd/t_dd_tritmp.h"
 
470
 
 
471
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT)
 
472
#define TAG(x) x##_twoside_unfilled_fallback
 
473
#include "tnl_dd/t_dd_tritmp.h"
 
474
 
 
475
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \
 
476
             MGA_FALLBACK_BIT)
 
477
#define TAG(x) x##_twoside_offset_unfilled_fallback
 
478
#include "tnl_dd/t_dd_tritmp.h"
 
479
 
 
480
 
 
481
/* Mga doesn't support provoking-vertex flat-shading?
 
482
 */
 
483
#define IND (MGA_FLAT_BIT)
 
484
#define TAG(x) x##_flat
 
485
#include "tnl_dd/t_dd_tritmp.h"
 
486
 
 
487
#define IND (MGA_OFFSET_BIT|MGA_FLAT_BIT)
 
488
#define TAG(x) x##_offset_flat
 
489
#include "tnl_dd/t_dd_tritmp.h"
 
490
 
 
491
#define IND (MGA_TWOSIDE_BIT|MGA_FLAT_BIT)
 
492
#define TAG(x) x##_twoside_flat
 
493
#include "tnl_dd/t_dd_tritmp.h"
 
494
 
 
495
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FLAT_BIT)
 
496
#define TAG(x) x##_twoside_offset_flat
 
497
#include "tnl_dd/t_dd_tritmp.h"
 
498
 
 
499
#define IND (MGA_UNFILLED_BIT|MGA_FLAT_BIT)
 
500
#define TAG(x) x##_unfilled_flat
 
501
#include "tnl_dd/t_dd_tritmp.h"
 
502
 
 
503
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
 
504
#define TAG(x) x##_offset_unfilled_flat
 
505
#include "tnl_dd/t_dd_tritmp.h"
 
506
 
 
507
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
 
508
#define TAG(x) x##_twoside_unfilled_flat
 
509
#include "tnl_dd/t_dd_tritmp.h"
 
510
 
 
511
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FLAT_BIT)
 
512
#define TAG(x) x##_twoside_offset_unfilled_flat
 
513
#include "tnl_dd/t_dd_tritmp.h"
 
514
 
 
515
#define IND (MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
516
#define TAG(x) x##_fallback_flat
 
517
#include "tnl_dd/t_dd_tritmp.h"
 
518
 
 
519
#define IND (MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
520
#define TAG(x) x##_offset_fallback_flat
 
521
#include "tnl_dd/t_dd_tritmp.h"
 
522
 
 
523
#define IND (MGA_TWOSIDE_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
524
#define TAG(x) x##_twoside_fallback_flat
 
525
#include "tnl_dd/t_dd_tritmp.h"
 
526
 
 
527
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
528
#define TAG(x) x##_twoside_offset_fallback_flat
 
529
#include "tnl_dd/t_dd_tritmp.h"
 
530
 
 
531
#define IND (MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
532
#define TAG(x) x##_unfilled_fallback_flat
 
533
#include "tnl_dd/t_dd_tritmp.h"
 
534
 
 
535
#define IND (MGA_OFFSET_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
536
#define TAG(x) x##_offset_unfilled_fallback_flat
 
537
#include "tnl_dd/t_dd_tritmp.h"
 
538
 
 
539
#define IND (MGA_TWOSIDE_BIT|MGA_UNFILLED_BIT|MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
540
#define TAG(x) x##_twoside_unfilled_fallback_flat
 
541
#include "tnl_dd/t_dd_tritmp.h"
 
542
 
 
543
#define IND (MGA_TWOSIDE_BIT|MGA_OFFSET_BIT|MGA_UNFILLED_BIT| \
 
544
             MGA_FALLBACK_BIT|MGA_FLAT_BIT)
 
545
#define TAG(x) x##_twoside_offset_unfilled_fallback_flat
 
546
#include "tnl_dd/t_dd_tritmp.h"
 
547
 
 
548
 
 
549
static void init_rast_tab( void )
 
550
{
 
551
   init();
 
552
   init_offset();
 
553
   init_twoside();
 
554
   init_twoside_offset();
 
555
   init_unfilled();
 
556
   init_offset_unfilled();
 
557
   init_twoside_unfilled();
 
558
   init_twoside_offset_unfilled();
 
559
   init_fallback();
 
560
   init_offset_fallback();
 
561
   init_twoside_fallback();
 
562
   init_twoside_offset_fallback();
 
563
   init_unfilled_fallback();
 
564
   init_offset_unfilled_fallback();
 
565
   init_twoside_unfilled_fallback();
 
566
   init_twoside_offset_unfilled_fallback();
 
567
 
 
568
   init_flat();
 
569
   init_offset_flat();
 
570
   init_twoside_flat();
 
571
   init_twoside_offset_flat();
 
572
   init_unfilled_flat();
 
573
   init_offset_unfilled_flat();
 
574
   init_twoside_unfilled_flat();
 
575
   init_twoside_offset_unfilled_flat();
 
576
   init_fallback_flat();
 
577
   init_offset_fallback_flat();
 
578
   init_twoside_fallback_flat();
 
579
   init_twoside_offset_fallback_flat();
 
580
   init_unfilled_fallback_flat();
 
581
   init_offset_unfilled_fallback_flat();
 
582
   init_twoside_unfilled_fallback_flat();
 
583
   init_twoside_offset_unfilled_fallback_flat();
 
584
}
 
585
 
 
586
/**********************************************************************/
 
587
/*                 Render whole begin/end objects                     */
 
588
/**********************************************************************/
 
589
 
 
590
 
 
591
#define VERT(x) (mgaVertex *)(vertptr + ((x)<<vertshift))
 
592
#define RENDER_POINTS( start, count )           \
 
593
   for ( ; start < count ; start++)             \
 
594
      mga_draw_point( mmesa, VERT(ELT(start)) );
 
595
#define RENDER_LINE( v0, v1 ) \
 
596
   mga_draw_line( mmesa, VERT(v0), VERT(v1) )
 
597
#define RENDER_TRI( v0, v1, v2 )  \
 
598
   mga_draw_triangle( mmesa, VERT(v0), VERT(v1), VERT(v2) )
 
599
#define RENDER_QUAD( v0, v1, v2, v3 ) \
 
600
   mga_draw_quad( mmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
 
601
#define INIT(x) mgaRenderPrimitive( ctx, x )
 
602
#undef LOCAL_VARS
 
603
#define LOCAL_VARS                                              \
 
604
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);                     \
 
605
    GLubyte *vertptr = (GLubyte *)mmesa->verts;                 \
 
606
    const GLuint vertshift = mmesa->vertex_stride_shift;        \
 
607
    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
 
608
    (void) elt;
 
609
#define RESET_STIPPLE 
 
610
#define RESET_OCCLUSION 
 
611
#define PRESERVE_VB_DEFS
 
612
#define ELT(x) x
 
613
#define TAG(x) mga_##x##_verts
 
614
#include "tnl/t_vb_rendertmp.h"
 
615
#undef ELT
 
616
#undef TAG
 
617
#define TAG(x) mga_##x##_elts
 
618
#define ELT(x) elt[x]
 
619
#include "tnl/t_vb_rendertmp.h"
 
620
 
 
621
 
 
622
/**********************************************************************/
 
623
/*                   Render clipped primitives                        */
 
624
/**********************************************************************/
 
625
 
 
626
 
 
627
 
 
628
static void mgaRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n )
 
629
{
 
630
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
631
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
632
   struct vertex_buffer *VB = &tnl->vb;
 
633
   GLuint prim = mmesa->render_primitive;
 
634
 
 
635
   /* Render the new vertices as an unclipped polygon. 
 
636
    */
 
637
   {
 
638
      GLuint *tmp = VB->Elts;
 
639
      VB->Elts = (GLuint *)elts;
 
640
      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
 
641
      VB->Elts = tmp;
 
642
   }
 
643
 
 
644
   /* Restore the render primitive
 
645
    */
 
646
   if (prim != GL_POLYGON)
 
647
      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
 
648
}
 
649
 
 
650
static void mgaRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
 
651
{
 
652
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
653
   tnl->Driver.Render.Line( ctx, ii, jj );
 
654
}
 
655
 
 
656
static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, 
 
657
                                       GLuint n )
 
658
{
 
659
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
 
660
   GLuint vertex_size = mmesa->vertex_size;
 
661
   GLuint *vb = mgaAllocDmaLow( mmesa, (n-2) * 3 * 4 * vertex_size );
 
662
   GLubyte *vertptr = (GLubyte *)mmesa->verts;                  
 
663
   const GLuint vertshift = mmesa->vertex_stride_shift;         
 
664
   const GLuint *start = (const GLuint *)VERT(elts[0]);
 
665
   int i,j;
 
666
 
 
667
   for (i = 2 ; i < n ; i++) {
 
668
      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i-1]) );
 
669
      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) VERT(elts[i]) );
 
670
      EMIT_VERT( j, vb, vertex_size, (mgaVertexPtr) start );
 
671
   }
 
672
}
 
673
 
 
674
/**********************************************************************/
 
675
/*                    Choose render functions                         */
 
676
/**********************************************************************/
 
677
 
 
678
 
 
679
 
 
680
#define _MGA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE |            \
 
681
                               _DD_NEW_TRI_UNFILLED |           \
 
682
                               _DD_NEW_TRI_LIGHT_TWOSIDE |      \
 
683
                               _DD_NEW_TRI_OFFSET |             \
 
684
                               _DD_NEW_TRI_STIPPLE |            \
 
685
                               _NEW_POLYGONSTIPPLE)
 
686
 
 
687
 
 
688
#define POINT_FALLBACK (DD_POINT_SMOOTH)
 
689
#define LINE_FALLBACK (DD_LINE_SMOOTH | DD_LINE_STIPPLE)
 
690
#define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_UNFILLED)
 
691
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK| \
 
692
                            DD_TRI_STIPPLE)
 
693
#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \
 
694
                          DD_TRI_UNFILLED)
 
695
 
 
696
static void mgaChooseRenderState(GLcontext *ctx)
 
697
{
 
698
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
699
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
700
   GLuint flags = ctx->_TriangleCaps;
 
701
   GLuint index = 0;
 
702
 
 
703
   if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
 
704
      if (flags & ANY_RASTER_FLAGS) {
 
705
         if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= MGA_TWOSIDE_BIT;
 
706
         if (flags & DD_TRI_OFFSET)           index |= MGA_OFFSET_BIT;
 
707
         if (flags & DD_TRI_UNFILLED)         index |= MGA_UNFILLED_BIT;
 
708
         if (flags & DD_FLATSHADE)            index |= MGA_FLAT_BIT;
 
709
      }
 
710
 
 
711
      mmesa->draw_point = mga_draw_point;
 
712
      mmesa->draw_line = mga_draw_line;
 
713
      mmesa->draw_tri = mga_draw_triangle;
 
714
 
 
715
      /* Hook in fallbacks for specific primitives.
 
716
       */
 
717
      if (flags & ANY_FALLBACK_FLAGS)
 
718
      {
 
719
         if (flags & POINT_FALLBACK) 
 
720
            mmesa->draw_point = mga_fallback_point;
 
721
         
 
722
         if (flags & LINE_FALLBACK) 
 
723
            mmesa->draw_line = mga_fallback_line;
 
724
         
 
725
         if (flags & TRI_FALLBACK) 
 
726
            mmesa->draw_tri = mga_fallback_tri;
 
727
         
 
728
         if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple)
 
729
            mmesa->draw_tri = mga_fallback_tri;
 
730
      
 
731
         index |= MGA_FALLBACK_BIT;
 
732
      }
 
733
   }
 
734
 
 
735
   if (mmesa->RenderIndex != index) {
 
736
      mmesa->RenderIndex = index;
 
737
 
 
738
      tnl->Driver.Render.Points = rast_tab[index].points;
 
739
      tnl->Driver.Render.Line = rast_tab[index].line;
 
740
      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
 
741
      tnl->Driver.Render.Quad = rast_tab[index].quad;
 
742
         
 
743
      if (index == 0) {
 
744
         tnl->Driver.Render.PrimTabVerts = mga_render_tab_verts;
 
745
         tnl->Driver.Render.PrimTabElts = mga_render_tab_elts;
 
746
         tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
 
747
         tnl->Driver.Render.ClippedPolygon = mgaFastRenderClippedPoly;
 
748
      } else {
 
749
         tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
 
750
         tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
 
751
         tnl->Driver.Render.ClippedLine = mgaRenderClippedLine;
 
752
         tnl->Driver.Render.ClippedPolygon = mgaRenderClippedPoly;
 
753
      }
 
754
   }
 
755
}
 
756
 
 
757
/**********************************************************************/
 
758
/*                Runtime render state and callbacks                  */
 
759
/**********************************************************************/
 
760
 
 
761
 
 
762
static void mgaRunPipeline( GLcontext *ctx )
 
763
{
 
764
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
765
 
 
766
   if (mmesa->new_state) {
 
767
      mgaDDUpdateHwState( ctx );
 
768
   }
 
769
 
 
770
   if (!mmesa->Fallback && mmesa->new_gl_state) {
 
771
      if (mmesa->new_gl_state & _MGA_NEW_RASTERSETUP)
 
772
         mgaChooseVertexState( ctx );
 
773
      
 
774
      if (mmesa->new_gl_state & _MGA_NEW_RENDERSTATE)
 
775
         mgaChooseRenderState( ctx );
 
776
      
 
777
      mmesa->new_gl_state = 0;
 
778
 
 
779
      /* Circularity: mgaDDUpdateHwState can affect mmesa->Fallback,
 
780
       * but mgaChooseVertexState can affect mmesa->new_state.  Hence
 
781
       * the second check.  (Fix this...)
 
782
       */
 
783
      if (mmesa->new_state) {
 
784
         mgaDDUpdateHwState( ctx );
 
785
      }
 
786
   }
 
787
 
 
788
   _tnl_run_pipeline( ctx );
 
789
}
 
790
 
 
791
 
 
792
static GLenum reduced_prim[GL_POLYGON+1] = {
 
793
   GL_POINTS,
 
794
   GL_LINES,
 
795
   GL_LINES,
 
796
   GL_LINES,
 
797
   GL_TRIANGLES,
 
798
   GL_TRIANGLES,
 
799
   GL_TRIANGLES,
 
800
   GL_TRIANGLES,
 
801
   GL_TRIANGLES,
 
802
   GL_TRIANGLES
 
803
};
 
804
 
 
805
 
 
806
 
 
807
/* Always called between RenderStart and RenderFinish --> We already
 
808
 * hold the lock.
 
809
 */
 
810
void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim )
 
811
{
 
812
   mgaContextPtr mmesa = MGA_CONTEXT( ctx );
 
813
 
 
814
   FLUSH_BATCH( mmesa );
 
815
   mmesa->raster_primitive = prim;
 
816
/*     mmesa->hw_primitive = hwprim; */
 
817
   mmesa->hw_primitive = MGA_WA_TRIANGLES; /* disable mgarender.c for now */
 
818
   mgaUpdateCull(ctx);   
 
819
 
 
820
   if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple)
 
821
   {
 
822
      mmesa->dirty |= MGA_UPLOAD_CONTEXT;
 
823
      if (mmesa->raster_primitive == GL_TRIANGLES)
 
824
         mmesa->setup.dwgctl |= mmesa->poly_stipple;
 
825
      else
 
826
         mmesa->setup.dwgctl &= ~(0xf<<20);
 
827
   }
 
828
}
 
829
 
 
830
 
 
831
 
 
832
/* Determine the rasterized primitive when not drawing unfilled 
 
833
 * polygons.
 
834
 *
 
835
 * Used only for the default render stage which always decomposes
 
836
 * primitives to trianges/lines/points.  For the accelerated stage,
 
837
 * which renders strips as strips, the equivalent calculations are
 
838
 * performed in mgarender.c.
 
839
 */
 
840
static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim )
 
841
{
 
842
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
843
   GLuint rprim = reduced_prim[prim];
 
844
 
 
845
   mmesa->render_primitive = prim;
 
846
 
 
847
   if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
 
848
      return;
 
849
       
 
850
   if (mmesa->raster_primitive != rprim) {
 
851
      mgaRasterPrimitive( ctx, rprim, MGA_WA_TRIANGLES );
 
852
   }
 
853
}
 
854
 
 
855
static void mgaRenderFinish( GLcontext *ctx )
 
856
{
 
857
   if (MGA_CONTEXT(ctx)->RenderIndex & MGA_FALLBACK_BIT)
 
858
      _swrast_flush( ctx );
 
859
}
 
860
 
 
861
 
 
862
 
 
863
/**********************************************************************/
 
864
/*               Manage total rasterization fallbacks                 */
 
865
/**********************************************************************/
 
866
 
 
867
void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
 
868
{
 
869
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
870
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
871
   GLuint oldfallback = mmesa->Fallback;
 
872
 
 
873
   if (mode) {
 
874
      mmesa->Fallback |= bit;
 
875
      if (oldfallback == 0) {
 
876
         FLUSH_BATCH(mmesa);
 
877
         _swsetup_Wakeup( ctx );
 
878
         mmesa->RenderIndex = ~0;
 
879
      }
 
880
   }
 
881
   else {
 
882
      mmesa->Fallback &= ~bit;
 
883
      if (oldfallback == bit) {
 
884
         _swrast_flush( ctx );
 
885
         tnl->Driver.Render.Start = mgaCheckTexSizes;
 
886
         tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive;
 
887
         tnl->Driver.Render.Finish = mgaRenderFinish;
 
888
         tnl->Driver.Render.BuildVertices = mgaBuildVertices;
 
889
         mmesa->new_gl_state |= (_MGA_NEW_RENDERSTATE |
 
890
                                 _MGA_NEW_RASTERSETUP);
 
891
      }
 
892
   }
 
893
}
 
894
 
 
895
 
 
896
void mgaDDInitTriFuncs( GLcontext *ctx )
 
897
{
 
898
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
899
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
 
900
   static int firsttime = 1;
 
901
   if (firsttime) {
 
902
      init_rast_tab();
 
903
      firsttime = 0;
 
904
   }
 
905
 
 
906
   mmesa->RenderIndex = ~0;
 
907
        
 
908
   tnl->Driver.RunPipeline               = mgaRunPipeline;
 
909
   tnl->Driver.Render.Start              = mgaCheckTexSizes;
 
910
   tnl->Driver.Render.Finish             = mgaRenderFinish; 
 
911
   tnl->Driver.Render.PrimitiveNotify    = mgaRenderPrimitive;
 
912
   tnl->Driver.Render.ResetLineStipple   = _swrast_ResetLineStipple;
 
913
   tnl->Driver.Render.BuildVertices      = mgaBuildVertices;
 
914
   tnl->Driver.Render.Multipass          = NULL;
 
915
}