~gma500/+junk/gma500-natty

« back to all changes in this revision

Viewing changes to xpsb-glx/mesa/src/mesa/drivers/dri/r128/r128_tris.c

  • Committer: Luca Forina
  • Date: 2011-02-14 10:01:54 UTC
  • Revision ID: luca.forina@gmail.com-20110214100154-ai9gynuqb1dna2ea
new commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- c-basic-offset: 3 -*- */
 
2
/**************************************************************************
 
3
 
 
4
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
 
5
                     VA Linux Systems Inc., Fremont, California.
 
6
 
 
7
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
on the rights to use, copy, modify, merge, publish, distribute, sub
 
13
license, and/or sell copies of the Software, and to permit persons to whom
 
14
the Software is furnished to do so, subject to the following conditions:
 
15
 
 
16
The above copyright notice and this permission notice (including the next
 
17
paragraph) shall be included in all copies or substantial portions of the
 
18
Software.
 
19
 
 
20
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
21
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
22
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 
23
ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 
24
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
25
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 
26
USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
 
 
28
**************************************************************************/
 
29
 
 
30
/*
 
31
 * Authors:
 
32
 *   Keith Whitwell <keith@tungstengraphics.com>
 
33
 *
 
34
 */
 
35
 
 
36
#include "main/glheader.h"
 
37
#include "main/mtypes.h"
 
38
#include "main/colormac.h"
 
39
#include "main/macros.h"
 
40
 
 
41
#include "swrast/swrast.h"
 
42
#include "swrast_setup/swrast_setup.h"
 
43
#include "tnl/tnl.h"
 
44
#include "tnl/t_context.h"
 
45
#include "tnl/t_pipeline.h"
 
46
 
 
47
#include "r128_tris.h"
 
48
#include "r128_state.h"
 
49
#include "r128_tex.h"
 
50
#include "r128_ioctl.h"
 
51
 
 
52
static const GLuint hw_prim[GL_POLYGON+1] = {
 
53
   R128_CCE_VC_CNTL_PRIM_TYPE_POINT,
 
54
   R128_CCE_VC_CNTL_PRIM_TYPE_LINE,
 
55
   R128_CCE_VC_CNTL_PRIM_TYPE_LINE,
 
56
   R128_CCE_VC_CNTL_PRIM_TYPE_LINE,
 
57
   R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
 
58
   R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
 
59
   R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
 
60
   R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
 
61
   R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
 
62
   R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
 
63
};
 
64
 
 
65
static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim );
 
66
static void r128RenderPrimitive( GLcontext *ctx, GLenum prim );
 
67
 
 
68
 
 
69
/***********************************************************************
 
70
 *                    Emit primitives as inline vertices               *
 
71
 ***********************************************************************/
 
72
        
 
73
#define HAVE_QUADS 0
 
74
#define HAVE_LINES 1
 
75
#define HAVE_POINTS 1
 
76
#define HAVE_LE32_VERTS 1
 
77
#define CTX_ARG r128ContextPtr rmesa
 
78
#define GET_VERTEX_DWORDS() rmesa->vertex_size
 
79
#define ALLOC_VERTS( n, size ) r128AllocDmaLow( rmesa, (n), (size) * 4 )
 
80
#undef LOCAL_VARS
 
81
#define LOCAL_VARS                                              \
 
82
   r128ContextPtr rmesa = R128_CONTEXT(ctx);                    \
 
83
   const char *vertptr = rmesa->verts;
 
84
#define VERT(x) (r128Vertex *)(vertptr + ((x) * vertsize * 4))
 
85
#define VERTEX r128Vertex
 
86
#undef TAG
 
87
#define TAG(x) r128_##x
 
88
#include "tnl_dd/t_dd_triemit.h"
 
89
#undef TAG
 
90
#undef LOCAL_VARS
 
91
 
 
92
 
 
93
/***********************************************************************
 
94
 *          Macros for t_dd_tritmp.h to draw basic primitives          *
 
95
 ***********************************************************************/
 
96
 
 
97
#define TRI( a, b, c )                          \
 
98
do {                                            \
 
99
   if (DO_FALLBACK)                             \
 
100
      rmesa->draw_tri( rmesa, a, b, c );        \
 
101
   else                                         \
 
102
      r128_triangle( rmesa, a, b, c );          \
 
103
} while (0)
 
104
 
 
105
#define QUAD( a, b, c, d )                      \
 
106
do {                                            \
 
107
   if (DO_FALLBACK) {                           \
 
108
      rmesa->draw_tri( rmesa, a, b, d );        \
 
109
      rmesa->draw_tri( rmesa, b, c, d );        \
 
110
   } else                                       \
 
111
      r128_quad( rmesa, a, b, c, d );           \
 
112
} while (0)
 
113
 
 
114
#define LINE( v0, v1 )                          \
 
115
do {                                            \
 
116
   if (DO_FALLBACK)                             \
 
117
      rmesa->draw_line( rmesa, v0, v1 );        \
 
118
   else                                         \
 
119
      r128_line( rmesa, v0, v1 );               \
 
120
} while (0)
 
121
 
 
122
#define POINT( v0 )                             \
 
123
do {                                            \
 
124
   if (DO_FALLBACK)                             \
 
125
      rmesa->draw_point( rmesa, v0 );           \
 
126
   else                                         \
 
127
      r128_point( rmesa, v0 );                  \
 
128
} while (0)
 
129
 
 
130
 
 
131
/***********************************************************************
 
132
 *              Build render functions from dd templates               *
 
133
 ***********************************************************************/
 
134
 
 
135
#define R128_OFFSET_BIT 0x01
 
136
#define R128_TWOSIDE_BIT        0x02
 
137
#define R128_UNFILLED_BIT       0x04
 
138
#define R128_FALLBACK_BIT       0x08
 
139
#define R128_MAX_TRIFUNC        0x10
 
140
 
 
141
 
 
142
static struct {
 
143
   tnl_points_func              points;
 
144
   tnl_line_func                line;
 
145
   tnl_triangle_func    triangle;
 
146
   tnl_quad_func                quad;
 
147
} rast_tab[R128_MAX_TRIFUNC];
 
148
 
 
149
 
 
150
#define DO_FALLBACK (IND & R128_FALLBACK_BIT)
 
151
#define DO_OFFSET   (IND & R128_OFFSET_BIT)
 
152
#define DO_UNFILLED (IND & R128_UNFILLED_BIT)
 
153
#define DO_TWOSIDE  (IND & R128_TWOSIDE_BIT)
 
154
#define DO_FLAT      0
 
155
#define DO_TRI       1
 
156
#define DO_QUAD      1
 
157
#define DO_LINE      1
 
158
#define DO_POINTS    1
 
159
#define DO_FULL_QUAD 1
 
160
 
 
161
#define HAVE_RGBA   1
 
162
#define HAVE_SPEC   1
 
163
#define HAVE_BACK_COLORS  0
 
164
#define HAVE_HW_FLATSHADE 1
 
165
#define VERTEX r128Vertex
 
166
#define TAB rast_tab
 
167
 
 
168
#define DEPTH_SCALE rmesa->depth_scale
 
169
#define UNFILLED_TRI unfilled_tri
 
170
#define UNFILLED_QUAD unfilled_quad
 
171
#define VERT_X(_v) _v->v.x
 
172
#define VERT_Y(_v) _v->v.y
 
173
#define VERT_Z(_v) _v->v.z
 
174
#define AREA_IS_CCW( a ) (a > 0)
 
175
#define GET_VERTEX(e) (rmesa->verts + (e * rmesa->vertex_size * sizeof(int)))
 
176
 
 
177
#define VERT_SET_RGBA( v, c )                                   \
 
178
do {                                                            \
 
179
   r128_color_t *color = (r128_color_t *)&((v)->ui[coloroffset]);       \
 
180
   UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);                \
 
181
   UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);              \
 
182
   UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);               \
 
183
   UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]);              \
 
184
} while (0)
 
185
 
 
186
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
 
187
 
 
188
#define VERT_SET_SPEC( v0, c )                                  \
 
189
do {                                                            \
 
190
   if (havespec) {                                              \
 
191
      r128_color_t *spec = (r128_color_t *)&((v0)->ui[specoffset]); \
 
192
      UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]);              \
 
193
      UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]);            \
 
194
      UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]);             \
 
195
   }                                                            \
 
196
} while (0)
 
197
#define VERT_COPY_SPEC( v0, v1 )                        \
 
198
do {                                                    \
 
199
   if (havespec) {                                      \
 
200
      r128_color_t *spec0 = (r128_color_t *)&((v0)->ui[specoffset]); \
 
201
      r128_color_t *spec1 = (r128_color_t *)&((v1)->ui[specoffset]); \
 
202
      spec0->red   = spec1->red;                        \
 
203
      spec0->green = spec1->green;                      \
 
204
      spec0->blue  = spec1->blue;                       \
 
205
   }                                                    \
 
206
} while (0)
 
207
 
 
208
/* These don't need LE32_TO_CPU() as they are used to save and restore
 
209
 * colors which are already in the correct format.
 
210
 */
 
211
#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
 
212
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
 
213
#define VERT_SAVE_SPEC( idx )    if (havespec) spec[idx] = v[idx]->ui[specoffset]
 
214
#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[specoffset] = spec[idx]
 
215
 
 
216
 
 
217
#define LOCAL_VARS(n)                                           \
 
218
   r128ContextPtr rmesa = R128_CONTEXT(ctx);                    \
 
219
   GLuint color[n], spec[n];                                    \
 
220
   GLuint coloroffset = rmesa->coloroffset;                     \
 
221
   GLuint specoffset = rmesa->specoffset;                       \
 
222
   GLboolean havespec = (rmesa->specoffset != 0);               \
 
223
   (void) color; (void) spec; (void) specoffset;                \
 
224
   (void) coloroffset; (void) havespec;
 
225
 
 
226
/***********************************************************************
 
227
 *                Helpers for rendering unfilled primitives            *
 
228
 ***********************************************************************/
 
229
 
 
230
#define RASTERIZE(x) if (rmesa->hw_primitive != hw_prim[x]) \
 
231
                        r128RasterPrimitive( ctx, hw_prim[x] )
 
232
#define RENDER_PRIMITIVE rmesa->render_primitive
 
233
#define IND R128_FALLBACK_BIT
 
234
#define TAG(x) x
 
235
#include "tnl_dd/t_dd_unfilled.h"
 
236
#undef IND
 
237
 
 
238
 
 
239
/***********************************************************************
 
240
 *                      Generate GL render functions                   *
 
241
 ***********************************************************************/
 
242
 
 
243
 
 
244
#define IND (0)
 
245
#define TAG(x) x
 
246
#include "tnl_dd/t_dd_tritmp.h"
 
247
 
 
248
#define IND (R128_OFFSET_BIT)
 
249
#define TAG(x) x##_offset
 
250
#include "tnl_dd/t_dd_tritmp.h"
 
251
 
 
252
#define IND (R128_TWOSIDE_BIT)
 
253
#define TAG(x) x##_twoside
 
254
#include "tnl_dd/t_dd_tritmp.h"
 
255
 
 
256
#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT)
 
257
#define TAG(x) x##_twoside_offset
 
258
#include "tnl_dd/t_dd_tritmp.h"
 
259
 
 
260
#define IND (R128_UNFILLED_BIT)
 
261
#define TAG(x) x##_unfilled
 
262
#include "tnl_dd/t_dd_tritmp.h"
 
263
 
 
264
#define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT)
 
265
#define TAG(x) x##_offset_unfilled
 
266
#include "tnl_dd/t_dd_tritmp.h"
 
267
 
 
268
#define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT)
 
269
#define TAG(x) x##_twoside_unfilled
 
270
#include "tnl_dd/t_dd_tritmp.h"
 
271
 
 
272
#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT)
 
273
#define TAG(x) x##_twoside_offset_unfilled
 
274
#include "tnl_dd/t_dd_tritmp.h"
 
275
 
 
276
#define IND (R128_FALLBACK_BIT)
 
277
#define TAG(x) x##_fallback
 
278
#include "tnl_dd/t_dd_tritmp.h"
 
279
 
 
280
#define IND (R128_OFFSET_BIT|R128_FALLBACK_BIT)
 
281
#define TAG(x) x##_offset_fallback
 
282
#include "tnl_dd/t_dd_tritmp.h"
 
283
 
 
284
#define IND (R128_TWOSIDE_BIT|R128_FALLBACK_BIT)
 
285
#define TAG(x) x##_twoside_fallback
 
286
#include "tnl_dd/t_dd_tritmp.h"
 
287
 
 
288
#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_FALLBACK_BIT)
 
289
#define TAG(x) x##_twoside_offset_fallback
 
290
#include "tnl_dd/t_dd_tritmp.h"
 
291
 
 
292
#define IND (R128_UNFILLED_BIT|R128_FALLBACK_BIT)
 
293
#define TAG(x) x##_unfilled_fallback
 
294
#include "tnl_dd/t_dd_tritmp.h"
 
295
 
 
296
#define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
 
297
#define TAG(x) x##_offset_unfilled_fallback
 
298
#include "tnl_dd/t_dd_tritmp.h"
 
299
 
 
300
#define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
 
301
#define TAG(x) x##_twoside_unfilled_fallback
 
302
#include "tnl_dd/t_dd_tritmp.h"
 
303
 
 
304
#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT| \
 
305
             R128_FALLBACK_BIT)
 
306
#define TAG(x) x##_twoside_offset_unfilled_fallback
 
307
#include "tnl_dd/t_dd_tritmp.h"
 
308
 
 
309
 
 
310
static void init_rast_tab( void )
 
311
{
 
312
   init();
 
313
   init_offset();
 
314
   init_twoside();
 
315
   init_twoside_offset();
 
316
   init_unfilled();
 
317
   init_offset_unfilled();
 
318
   init_twoside_unfilled();
 
319
   init_twoside_offset_unfilled();
 
320
   init_fallback();
 
321
   init_offset_fallback();
 
322
   init_twoside_fallback();
 
323
   init_twoside_offset_fallback();
 
324
   init_unfilled_fallback();
 
325
   init_offset_unfilled_fallback();
 
326
   init_twoside_unfilled_fallback();
 
327
   init_twoside_offset_unfilled_fallback();
 
328
}
 
329
 
 
330
 
 
331
 
 
332
/***********************************************************************
 
333
 *                    Rasterization fallback helpers                   *
 
334
 ***********************************************************************/
 
335
 
 
336
 
 
337
/* This code is hit only when a mix of accelerated and unaccelerated
 
338
 * primitives are being drawn, and only for the unaccelerated
 
339
 * primitives.
 
340
 */
 
341
static void
 
342
r128_fallback_tri( r128ContextPtr rmesa,
 
343
                     r128Vertex *v0,
 
344
                     r128Vertex *v1,
 
345
                     r128Vertex *v2 )
 
346
{
 
347
   GLcontext *ctx = rmesa->glCtx;
 
348
   SWvertex v[3];
 
349
   _swsetup_Translate( ctx, v0, &v[0] );
 
350
   _swsetup_Translate( ctx, v1, &v[1] );
 
351
   _swsetup_Translate( ctx, v2, &v[2] );
 
352
   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
 
353
}
 
354
 
 
355
 
 
356
static void
 
357
r128_fallback_line( r128ContextPtr rmesa,
 
358
                    r128Vertex *v0,
 
359
                    r128Vertex *v1 )
 
360
{
 
361
   GLcontext *ctx = rmesa->glCtx;
 
362
   SWvertex v[2];
 
363
   _swsetup_Translate( ctx, v0, &v[0] );
 
364
   _swsetup_Translate( ctx, v1, &v[1] );
 
365
   _swrast_Line( ctx, &v[0], &v[1] );
 
366
}
 
367
 
 
368
 
 
369
static void
 
370
r128_fallback_point( r128ContextPtr rmesa,
 
371
                     r128Vertex *v0 )
 
372
{
 
373
   GLcontext *ctx = rmesa->glCtx;
 
374
   SWvertex v[1];
 
375
   _swsetup_Translate( ctx, v0, &v[0] );
 
376
   _swrast_Point( ctx, &v[0] );
 
377
}
 
378
 
 
379
 
 
380
 
 
381
/**********************************************************************/
 
382
/*               Render unclipped begin/end objects                   */
 
383
/**********************************************************************/
 
384
 
 
385
#define RENDER_POINTS( start, count )           \
 
386
   for ( ; start < count ; start++)             \
 
387
      r128_point( rmesa, VERT(start) )
 
388
#define RENDER_LINE( v0, v1 ) \
 
389
   r128_line( rmesa, VERT(v0), VERT(v1) )
 
390
#define RENDER_TRI( v0, v1, v2 )  \
 
391
   r128_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
 
392
#define RENDER_QUAD( v0, v1, v2, v3 ) \
 
393
   r128_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
 
394
#define INIT(x) do {                                    \
 
395
   if (0) fprintf(stderr, "%s\n", __FUNCTION__);        \
 
396
   r128RenderPrimitive( ctx, x );                       \
 
397
} while (0)
 
398
#undef LOCAL_VARS
 
399
#define LOCAL_VARS                                              \
 
400
    r128ContextPtr rmesa = R128_CONTEXT(ctx);           \
 
401
    const GLuint vertsize = rmesa->vertex_size;         \
 
402
    const char *vertptr = (char *)rmesa->verts;         \
 
403
    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
 
404
    (void) elt;
 
405
#define RESET_STIPPLE
 
406
#define RESET_OCCLUSION
 
407
#define PRESERVE_VB_DEFS
 
408
#define ELT(x) (x)
 
409
#define TAG(x) r128_##x##_verts
 
410
#include "tnl/t_vb_rendertmp.h"
 
411
#undef ELT
 
412
#undef TAG
 
413
#define TAG(x) r128_##x##_elts
 
414
#define ELT(x) elt[x]
 
415
#include "tnl/t_vb_rendertmp.h"
 
416
 
 
417
 
 
418
/**********************************************************************/
 
419
/*                    Choose render functions                         */
 
420
/**********************************************************************/
 
421
 
 
422
#define POINT_FALLBACK (DD_POINT_SMOOTH)
 
423
#define LINE_FALLBACK (DD_LINE_STIPPLE)
 
424
#define TRI_FALLBACK (DD_TRI_SMOOTH)
 
425
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
 
426
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
 
427
#define _R128_NEW_RENDER_STATE (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)
 
428
 
 
429
static void r128ChooseRenderState(GLcontext *ctx)
 
430
{
 
431
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
432
   GLuint flags = ctx->_TriangleCaps;
 
433
   GLuint index = 0;
 
434
 
 
435
   if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
 
436
      rmesa->draw_point = r128_point;
 
437
      rmesa->draw_line = r128_line;
 
438
      rmesa->draw_tri = r128_triangle;
 
439
 
 
440
      if (flags & ANY_RASTER_FLAGS) {
 
441
         if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT;
 
442
         if (flags & DD_TRI_OFFSET)        index |= R128_OFFSET_BIT;
 
443
         if (flags & DD_TRI_UNFILLED)      index |= R128_UNFILLED_BIT;
 
444
      }
 
445
 
 
446
      /* Hook in fallbacks for specific primitives.
 
447
       */
 
448
      if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) {
 
449
         if (flags & POINT_FALLBACK) rmesa->draw_point = r128_fallback_point;
 
450
         if (flags & LINE_FALLBACK)  rmesa->draw_line = r128_fallback_line;
 
451
         if (flags & TRI_FALLBACK)   rmesa->draw_tri = r128_fallback_tri;
 
452
         index |= R128_FALLBACK_BIT;
 
453
      }
 
454
   }
 
455
 
 
456
   if (index != rmesa->RenderIndex) {
 
457
      TNLcontext *tnl = TNL_CONTEXT(ctx);
 
458
      tnl->Driver.Render.Points = rast_tab[index].points;
 
459
      tnl->Driver.Render.Line = rast_tab[index].line;
 
460
      tnl->Driver.Render.ClippedLine = rast_tab[index].line;
 
461
      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
 
462
      tnl->Driver.Render.Quad = rast_tab[index].quad;
 
463
 
 
464
      if (index == 0) {
 
465
         tnl->Driver.Render.PrimTabVerts = r128_render_tab_verts;
 
466
         tnl->Driver.Render.PrimTabElts = r128_render_tab_elts;
 
467
         tnl->Driver.Render.ClippedPolygon = r128_fast_clipped_poly;
 
468
      } else {
 
469
         tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
 
470
         tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
 
471
         tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
 
472
      }
 
473
 
 
474
      rmesa->RenderIndex = index;
 
475
   }
 
476
}
 
477
 
 
478
/**********************************************************************/
 
479
/*                 Validate state at pipeline start                   */
 
480
/**********************************************************************/
 
481
 
 
482
static void r128RunPipeline( GLcontext *ctx )
 
483
{
 
484
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
485
 
 
486
   if (rmesa->new_state || rmesa->NewGLState & _NEW_TEXTURE)
 
487
      r128DDUpdateHWState( ctx );
 
488
 
 
489
   if (!rmesa->Fallback && rmesa->NewGLState) {
 
490
      if (rmesa->NewGLState & _R128_NEW_RENDER_STATE)
 
491
         r128ChooseRenderState( ctx );
 
492
 
 
493
      rmesa->NewGLState = 0;
 
494
   }
 
495
 
 
496
   _tnl_run_pipeline( ctx );
 
497
}
 
498
 
 
499
/**********************************************************************/
 
500
/*                 High level hooks for t_vb_render.c                 */
 
501
/**********************************************************************/
 
502
 
 
503
/* This is called when Mesa switches between rendering triangle
 
504
 * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
 
505
 * and lines, points and bitmaps.
 
506
 *
 
507
 * As the r128 uses triangles to render lines and points, it is
 
508
 * necessary to turn off hardware culling when rendering these
 
509
 * primitives.
 
510
 */
 
511
 
 
512
static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim )
 
513
{
 
514
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
515
 
 
516
   rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
 
517
 
 
518
   if ( ctx->Polygon.StippleFlag && hwprim == GL_TRIANGLES ) {
 
519
      rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA;
 
520
   }
 
521
   else {
 
522
      rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR;
 
523
   }
 
524
 
 
525
   rmesa->new_state |= R128_NEW_CONTEXT;
 
526
   rmesa->dirty |= R128_UPLOAD_CONTEXT;
 
527
 
 
528
   if (rmesa->hw_primitive != hwprim) {
 
529
      FLUSH_BATCH( rmesa );
 
530
      rmesa->hw_primitive = hwprim;
 
531
   }
 
532
}
 
533
 
 
534
static void r128SetupAntialias( GLcontext *ctx, GLenum prim )
 
535
{
 
536
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
537
 
 
538
   GLuint currAA, wantAA;
 
539
   
 
540
   currAA = (rmesa->setup.pm4_vc_fpu_setup & R128_EDGE_ANTIALIAS) != 0;
 
541
   if( prim >= GL_TRIANGLES )
 
542
      wantAA = ctx->Polygon.SmoothFlag;
 
543
   else if( prim >= GL_LINES )
 
544
      wantAA = ctx->Line.SmoothFlag;
 
545
   else
 
546
      wantAA = 0;
 
547
      
 
548
   if( wantAA != currAA )
 
549
   {
 
550
     FLUSH_BATCH( rmesa );
 
551
     rmesa->setup.pm4_vc_fpu_setup ^= R128_EDGE_ANTIALIAS;
 
552
     rmesa->dirty |= R128_UPLOAD_SETUP;
 
553
   }
 
554
}
 
555
 
 
556
static void r128RenderPrimitive( GLcontext *ctx, GLenum prim )
 
557
{
 
558
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
559
   GLuint hw = hw_prim[prim];
 
560
   rmesa->render_primitive = prim;
 
561
 
 
562
   r128SetupAntialias( ctx, prim );
 
563
   
 
564
   if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
 
565
      return;
 
566
   r128RasterPrimitive( ctx, hw );
 
567
}
 
568
 
 
569
#define EMIT_ATTR( ATTR, STYLE, VF, SIZE )                              \
 
570
do {                                                                    \
 
571
   rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = (ATTR);       \
 
572
   rmesa->vertex_attrs[rmesa->vertex_attr_count].format = (STYLE);      \
 
573
   rmesa->vertex_attr_count++;                                          \
 
574
   vc_frmt |= (VF);                                                     \
 
575
   offset += (SIZE);                                                    \
 
576
} while (0)
 
577
 
 
578
#define EMIT_PAD( SIZE )                                                \
 
579
do {                                                                    \
 
580
   rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = 0;            \
 
581
   rmesa->vertex_attrs[rmesa->vertex_attr_count].format = EMIT_PAD;     \
 
582
   rmesa->vertex_attrs[rmesa->vertex_attr_count].offset = (SIZE);       \
 
583
   rmesa->vertex_attr_count++;                                          \
 
584
   offset += (SIZE);                                                    \
 
585
} while (0)
 
586
 
 
587
static void r128RenderStart( GLcontext *ctx )
 
588
{
 
589
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
590
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
591
   struct vertex_buffer *VB = &tnl->vb;
 
592
   DECLARE_RENDERINPUTS(index_bitset);
 
593
   GLuint vc_frmt = 0;
 
594
   GLboolean fallback_projtex = GL_FALSE;
 
595
   GLuint offset = 0;
 
596
 
 
597
   RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
598
 
 
599
   /* Important: */
 
600
   VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
 
601
   rmesa->vertex_attr_count = 0;
 
602
   rmesa->specoffset = 0;
 
603
 
 
604
   /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
 
605
    * build up a hardware vertex.
 
606
    */
 
607
   if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ))
 
608
      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, R128_CCE_VC_FRMT_RHW, 4 );
 
609
   else
 
610
      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 3 );
 
611
 
 
612
   rmesa->coloroffset = offset;
 
613
#if MESA_LITTLE_ENDIAN 
 
614
   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA,
 
615
      R128_CCE_VC_FRMT_DIFFUSE_ARGB, 4 );
 
616
#else
 
617
   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ARGB,
 
618
      R128_CCE_VC_FRMT_DIFFUSE_ARGB, 4 );
 
619
#endif
 
620
 
 
621
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
 
622
       RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
 
623
#if MESA_LITTLE_ENDIAN
 
624
      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
 
625
         rmesa->specoffset = offset;
 
626
         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR,
 
627
            R128_CCE_VC_FRMT_SPEC_FRGB, 3 );
 
628
      } else 
 
629
         EMIT_PAD( 3 );
 
630
 
 
631
      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
 
632
         EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
 
633
                    1 );
 
634
      else
 
635
         EMIT_PAD( 1 );
 
636
#else
 
637
      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
 
638
         EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
 
639
                    1 );
 
640
      else
 
641
         EMIT_PAD( 1 );
 
642
 
 
643
      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
 
644
         rmesa->specoffset = offset;
 
645
         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB,
 
646
            R128_CCE_VC_FRMT_SPEC_FRGB, 3 );
 
647
      } else 
 
648
         EMIT_PAD( 3 );
 
649
#endif
 
650
   }
 
651
 
 
652
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[0]) )) {
 
653
      if ( VB->TexCoordPtr[rmesa->tmu_source[0]]->size > 2 )
 
654
         fallback_projtex = GL_TRUE;
 
655
      EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, R128_CCE_VC_FRMT_S_T, 8 );
 
656
   }
 
657
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[1]) )) {
 
658
      if ( VB->TexCoordPtr[rmesa->tmu_source[1]]->size > 2 )
 
659
         fallback_projtex = GL_TRUE;
 
660
      EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, R128_CCE_VC_FRMT_S2_T2, 8 );
 
661
   }
 
662
 
 
663
   /* projective textures are not supported by the hardware */
 
664
   FALLBACK( rmesa, R128_FALLBACK_PROJTEX, fallback_projtex );
 
665
 
 
666
   /* Only need to change the vertex emit code if there has been a
 
667
    * statechange to a TNL index.
 
668
    */
 
669
   if (!RENDERINPUTS_EQUAL( index_bitset, rmesa->tnl_state_bitset )) {
 
670
      FLUSH_BATCH( rmesa );
 
671
      rmesa->dirty |= R128_UPLOAD_CONTEXT;
 
672
 
 
673
      rmesa->vertex_size = 
 
674
         _tnl_install_attrs( ctx, 
 
675
                             rmesa->vertex_attrs, 
 
676
                             rmesa->vertex_attr_count,
 
677
                             rmesa->hw_viewport, 0 );
 
678
      rmesa->vertex_size >>= 2;
 
679
 
 
680
      rmesa->vertex_format = vc_frmt;
 
681
   }
 
682
}
 
683
 
 
684
static void r128RenderFinish( GLcontext *ctx )
 
685
{
 
686
   if (R128_CONTEXT(ctx)->RenderIndex & R128_FALLBACK_BIT)
 
687
      _swrast_flush( ctx );
 
688
}
 
689
 
 
690
 
 
691
/**********************************************************************/
 
692
/*           Transition to/from hardware rasterization.               */
 
693
/**********************************************************************/
 
694
 
 
695
static const char * const fallbackStrings[] = {
 
696
   "Texture mode",
 
697
   "glDrawBuffer(GL_FRONT_AND_BACK)",
 
698
   "glReadBuffer",
 
699
   "glEnable(GL_STENCIL) without hw stencil buffer",
 
700
   "glRenderMode(selection or feedback)",
 
701
   "glLogicOp (mode != GL_COPY)",
 
702
   "GL_SEPARATE_SPECULAR_COLOR",
 
703
   "glBlendEquation(mode != ADD)",
 
704
   "glBlendFunc",
 
705
   "Projective texture",
 
706
   "Rasterization disable",
 
707
};
 
708
 
 
709
 
 
710
static const char *getFallbackString(GLuint bit)
 
711
{
 
712
   int i = 0;
 
713
   while (bit > 1) {
 
714
      i++;
 
715
      bit >>= 1;
 
716
   }
 
717
   return fallbackStrings[i];
 
718
}
 
719
 
 
720
void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
 
721
{
 
722
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
723
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
724
   GLuint oldfallback = rmesa->Fallback;
 
725
 
 
726
   if (mode) {
 
727
      rmesa->Fallback |= bit;
 
728
      if (oldfallback == 0) {
 
729
         FLUSH_BATCH( rmesa );
 
730
         _swsetup_Wakeup( ctx );
 
731
         rmesa->RenderIndex = ~0;
 
732
         if ( R128_DEBUG & DEBUG_VERBOSE_FALL ) {
 
733
             fprintf(stderr, "R128 begin rasterization fallback: 0x%x %s\n",
 
734
                     bit, getFallbackString(bit));
 
735
         }
 
736
      }
 
737
   }
 
738
   else {
 
739
      rmesa->Fallback &= ~bit;
 
740
      if (oldfallback == bit) {
 
741
         _swrast_flush( ctx );
 
742
         tnl->Driver.Render.Start = r128RenderStart;
 
743
         tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
 
744
         tnl->Driver.Render.Finish = r128RenderFinish;
 
745
 
 
746
         tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
 
747
         tnl->Driver.Render.CopyPV = _tnl_copy_pv;
 
748
         tnl->Driver.Render.Interp = _tnl_interp;
 
749
 
 
750
         _tnl_invalidate_vertex_state( ctx, ~0 );
 
751
         _tnl_invalidate_vertices( ctx, ~0 );
 
752
         _tnl_install_attrs( ctx, 
 
753
                             rmesa->vertex_attrs, 
 
754
                             rmesa->vertex_attr_count,
 
755
                             rmesa->hw_viewport, 0 ); 
 
756
 
 
757
         rmesa->NewGLState |= _R128_NEW_RENDER_STATE;
 
758
         if ( R128_DEBUG & DEBUG_VERBOSE_FALL ) {
 
759
             fprintf(stderr, "R128 end rasterization fallback: 0x%x %s\n",
 
760
                     bit, getFallbackString(bit));
 
761
         }
 
762
      }
 
763
   }
 
764
}
 
765
 
 
766
 
 
767
/**********************************************************************/
 
768
/*                            Initialization.                         */
 
769
/**********************************************************************/
 
770
 
 
771
void r128InitTriFuncs( GLcontext *ctx )
 
772
{
 
773
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
774
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
775
   static int firsttime = 1;
 
776
 
 
777
   if (firsttime) {
 
778
      init_rast_tab();
 
779
      firsttime = 0;
 
780
   }
 
781
 
 
782
   tnl->Driver.RunPipeline = r128RunPipeline;
 
783
   tnl->Driver.Render.Start = r128RenderStart;
 
784
   tnl->Driver.Render.Finish = r128RenderFinish;
 
785
   tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
 
786
   tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
 
787
   tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
 
788
   tnl->Driver.Render.CopyPV = _tnl_copy_pv;
 
789
   tnl->Driver.Render.Interp = _tnl_interp;
 
790
 
 
791
   _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 
 
792
                       (6 + 2 * ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
 
793
   rmesa->verts = (char *)tnl->clipspace.vertex_buf;
 
794
   RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
 
795
 
 
796
   rmesa->NewGLState |= _R128_NEW_RENDER_STATE;
 
797
}