~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/unichrome/via_tris.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
 
3
 * Copyright 2001-2003 S3 Graphics, Inc. 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
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 
9
 * and/or sell copies of the Software, and to permit persons to whom the
 
10
 * Software is furnished to do so, subject to the following conditions:
 
11
 *
 
12
 * The above copyright notice and this permission notice (including the
 
13
 * next paragraph) shall be included in all copies or substantial portions
 
14
 * of the 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
 * VIA, S3 GRAPHICS, 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 OTHER
 
22
 * DEALINGS IN THE SOFTWARE.
 
23
 */
 
24
 
 
25
#include <stdio.h>
 
26
#include <math.h>
 
27
 
 
28
#include "glheader.h"
 
29
#include "context.h"
 
30
#include "mtypes.h"
 
31
#include "macros.h"
 
32
#include "colormac.h"
 
33
#include "enums.h"
 
34
 
 
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 "via_context.h"
 
41
#include "via_tris.h"
 
42
#include "via_state.h"
 
43
#include "via_span.h"
 
44
#include "via_ioctl.h"
 
45
#include "via_3d_reg.h"
 
46
#include "via_tex.h"
 
47
 
 
48
/***********************************************************************
 
49
 *                    Emit primitives as inline vertices               *
 
50
 ***********************************************************************/
 
51
#define LINE_FALLBACK (0)
 
52
#define POINT_FALLBACK (0)
 
53
#define TRI_FALLBACK (0)
 
54
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
 
55
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
 
56
 
 
57
 
 
58
#if 0
 
59
#define COPY_DWORDS(vb, vertsize, v)            \
 
60
do {                                            \
 
61
   via_sse_memcpy(vb, v, vertsize * 4);         \
 
62
   vb += vertsize;                              \
 
63
} while (0)
 
64
#else
 
65
#if defined( USE_X86_ASM )
 
66
#define COPY_DWORDS(vb, vertsize, v)                                    \
 
67
    do {                                                                \
 
68
        int j;                                                          \
 
69
        int __tmp;                                                      \
 
70
        __asm__ __volatile__("rep ; movsl"                              \
 
71
                              : "=%c" (j), "=D" (vb), "=S" (__tmp)      \
 
72
                              : "0" (vertsize),                         \
 
73
                                "D" ((long)vb),                         \
 
74
                                "S" ((long)v));                         \
 
75
    } while (0)
 
76
#else
 
77
#define COPY_DWORDS(vb, vertsize, v)            \
 
78
    do {                                        \
 
79
        int j;                                  \
 
80
        for (j = 0; j < vertsize; j++)          \
 
81
            vb[j] = ((GLuint *)v)[j];           \
 
82
        vb += vertsize;                         \
 
83
    } while (0)
 
84
#endif
 
85
#endif
 
86
 
 
87
static void via_draw_triangle(struct via_context *vmesa,
 
88
                              viaVertexPtr v0,
 
89
                              viaVertexPtr v1,
 
90
                              viaVertexPtr v2)
 
91
{
 
92
   GLuint vertsize = vmesa->vertexSize;
 
93
   GLuint *vb = viaExtendPrimitive(vmesa, 3 * 4 * vertsize);
 
94
 
 
95
   COPY_DWORDS(vb, vertsize, v0);
 
96
   COPY_DWORDS(vb, vertsize, v1);
 
97
   COPY_DWORDS(vb, vertsize, v2);
 
98
}
 
99
 
 
100
 
 
101
static void via_draw_quad(struct via_context *vmesa,
 
102
                          viaVertexPtr v0,
 
103
                          viaVertexPtr v1,
 
104
                          viaVertexPtr v2,
 
105
                          viaVertexPtr v3)
 
106
{
 
107
   GLuint vertsize = vmesa->vertexSize;
 
108
   GLuint *vb = viaExtendPrimitive(vmesa, 6 * 4 * vertsize);
 
109
 
 
110
   COPY_DWORDS(vb, vertsize, v0);
 
111
   COPY_DWORDS(vb, vertsize, v1);
 
112
   COPY_DWORDS(vb, vertsize, v3);
 
113
   COPY_DWORDS(vb, vertsize, v1);
 
114
   COPY_DWORDS(vb, vertsize, v2);
 
115
   COPY_DWORDS(vb, vertsize, v3);
 
116
}
 
117
 
 
118
static void via_draw_line(struct via_context *vmesa,
 
119
                          viaVertexPtr v0,
 
120
                          viaVertexPtr v1)
 
121
{
 
122
   GLuint vertsize = vmesa->vertexSize;
 
123
   GLuint *vb = viaExtendPrimitive(vmesa, 2 * 4 * vertsize);
 
124
   COPY_DWORDS(vb, vertsize, v0);
 
125
   COPY_DWORDS(vb, vertsize, v1);
 
126
}
 
127
 
 
128
 
 
129
static void via_draw_point(struct via_context *vmesa,
 
130
                           viaVertexPtr v0)
 
131
{
 
132
   GLuint vertsize = vmesa->vertexSize;
 
133
   GLuint *vb = viaExtendPrimitive(vmesa, 4 * vertsize);
 
134
   COPY_DWORDS(vb, vertsize, v0);
 
135
}
 
136
 
 
137
 
 
138
/* Fallback drawing functions for the ptex hack.
 
139
 */
 
140
#define PTEX_VERTEX( tmp, vertex_size, v)       \
 
141
do {                                                    \
 
142
   GLuint j;                                            \
 
143
   GLfloat rhw = 1.0 / v->f[vertex_size];               \
 
144
   for ( j = 0 ; j < vertex_size ; j++ )                \
 
145
      tmp.f[j] = v->f[j];                               \
 
146
   tmp.f[3] *= v->f[vertex_size];                       \
 
147
   tmp.f[vertex_size-2] *= rhw;                         \
 
148
   tmp.f[vertex_size-1] *= rhw;                         \
 
149
} while (0)
 
150
 
 
151
static void via_ptex_tri (struct via_context *vmesa,
 
152
                          viaVertexPtr v0,
 
153
                          viaVertexPtr v1,
 
154
                          viaVertexPtr v2)
 
155
{
 
156
   GLuint vertsize = vmesa->hwVertexSize;
 
157
   GLuint *vb = viaExtendPrimitive(vmesa, 3*4*vertsize);
 
158
   viaVertex tmp;
 
159
 
 
160
   PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp);
 
161
   PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp);
 
162
   PTEX_VERTEX(tmp, vertsize, v2); COPY_DWORDS(vb, vertsize, &tmp);
 
163
}
 
164
 
 
165
static void via_ptex_line (struct via_context *vmesa,
 
166
                           viaVertexPtr v0,
 
167
                           viaVertexPtr v1)
 
168
{
 
169
   GLuint vertsize = vmesa->hwVertexSize;
 
170
   GLuint *vb = viaExtendPrimitive(vmesa, 2*4*vertsize);
 
171
   viaVertex tmp;
 
172
 
 
173
   PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp);
 
174
   PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp);
 
175
}
 
176
 
 
177
static void via_ptex_point (struct via_context *vmesa,
 
178
                            viaVertexPtr v0)
 
179
{
 
180
   GLuint vertsize = vmesa->hwVertexSize;
 
181
   GLuint *vb = viaExtendPrimitive(vmesa, 1*4*vertsize);
 
182
   viaVertex tmp;
 
183
 
 
184
   PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp);
 
185
}
 
186
 
 
187
 
 
188
 
 
189
 
 
190
 
 
191
/***********************************************************************
 
192
 *          Macros for via_dd_tritmp.h to draw basic primitives        *
 
193
 ***********************************************************************/
 
194
 
 
195
#define TRI(a, b, c)                                \
 
196
    do {                                            \
 
197
        if (DO_FALLBACK)                            \
 
198
            vmesa->drawTri(vmesa, a, b, c);         \
 
199
        else                                        \
 
200
            via_draw_triangle(vmesa, a, b, c);      \
 
201
    } while (0)
 
202
 
 
203
#define QUAD(a, b, c, d)                            \
 
204
    do {                                            \
 
205
        if (DO_FALLBACK) {                          \
 
206
            vmesa->drawTri(vmesa, a, b, d);         \
 
207
            vmesa->drawTri(vmesa, b, c, d);         \
 
208
        }                                           \
 
209
        else                                        \
 
210
            via_draw_quad(vmesa, a, b, c, d);       \
 
211
    } while (0)
 
212
 
 
213
#define LINE(v0, v1)                                \
 
214
    do {                                            \
 
215
        if (DO_FALLBACK)                            \
 
216
            vmesa->drawLine(vmesa, v0, v1);         \
 
217
        else                                        \
 
218
            via_draw_line(vmesa, v0, v1);           \
 
219
    } while (0)
 
220
 
 
221
#define POINT(v0)                                    \
 
222
    do {                                             \
 
223
        if (DO_FALLBACK)                             \
 
224
            vmesa->drawPoint(vmesa, v0);             \
 
225
        else                                         \
 
226
            via_draw_point(vmesa, v0);               \
 
227
    } while (0)
 
228
 
 
229
 
 
230
/***********************************************************************
 
231
 *              Build render functions from dd templates               *
 
232
 ***********************************************************************/
 
233
 
 
234
#define VIA_OFFSET_BIT         0x01
 
235
#define VIA_TWOSIDE_BIT        0x02
 
236
#define VIA_UNFILLED_BIT       0x04
 
237
#define VIA_FALLBACK_BIT       0x08
 
238
#define VIA_MAX_TRIFUNC        0x10
 
239
 
 
240
 
 
241
static struct {
 
242
    tnl_points_func          points;
 
243
    tnl_line_func            line;
 
244
    tnl_triangle_func        triangle;
 
245
    tnl_quad_func            quad;
 
246
} rast_tab[VIA_MAX_TRIFUNC + 1];
 
247
 
 
248
 
 
249
#define DO_FALLBACK (IND & VIA_FALLBACK_BIT)
 
250
#define DO_OFFSET   (IND & VIA_OFFSET_BIT)
 
251
#define DO_UNFILLED (IND & VIA_UNFILLED_BIT)
 
252
#define DO_TWOSIDE  (IND & VIA_TWOSIDE_BIT)
 
253
#define DO_FLAT      0
 
254
#define DO_TRI       1
 
255
#define DO_QUAD      1
 
256
#define DO_LINE      1
 
257
#define DO_POINTS    1
 
258
#define DO_FULL_QUAD 1
 
259
 
 
260
#define HAVE_RGBA         1
 
261
#define HAVE_SPEC         1
 
262
#define HAVE_BACK_COLORS  0
 
263
#define HAVE_HW_FLATSHADE 1
 
264
#define VERTEX            viaVertex
 
265
#define TAB               rast_tab
 
266
 
 
267
/* Only used to pull back colors into vertices (ie, we know color is
 
268
 * floating point).
 
269
 */
 
270
#define VIA_COLOR(dst, src)                     \
 
271
    do {                                        \
 
272
        dst[0] = src[2];                        \
 
273
        dst[1] = src[1];                        \
 
274
        dst[2] = src[0];                        \
 
275
        dst[3] = src[3];                        \
 
276
    } while (0)
 
277
 
 
278
#define VIA_SPEC(dst, src)                      \
 
279
    do {                                        \
 
280
        dst[0] = src[2];                        \
 
281
        dst[1] = src[1];                        \
 
282
        dst[2] = src[0];                        \
 
283
    } while (0)
 
284
 
 
285
 
 
286
#define DEPTH_SCALE vmesa->polygon_offset_scale
 
287
#define UNFILLED_TRI unfilled_tri
 
288
#define UNFILLED_QUAD unfilled_quad
 
289
#define VERT_X(_v) _v->v.x
 
290
#define VERT_Y(_v) _v->v.y
 
291
#define VERT_Z(_v) _v->v.z
 
292
#define AREA_IS_CCW(a) (a > 0)
 
293
#define GET_VERTEX(e) (vmesa->verts + (e * vmesa->vertexSize * sizeof(int)))
 
294
 
 
295
#define VERT_SET_RGBA( v, c )                                   \
 
296
do {                                                            \
 
297
   via_color_t *color = (via_color_t *)&((v)->ui[coloroffset]); \
 
298
   UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);                \
 
299
   UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);              \
 
300
   UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);               \
 
301
   UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]);              \
 
302
} while (0)
 
303
 
 
304
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
 
305
 
 
306
#define VERT_SET_SPEC( v, c )                                   \
 
307
do {                                                            \
 
308
   if (specoffset) {                                            \
 
309
     via_color_t *color = (via_color_t *)&((v)->ui[specoffset]);        \
 
310
     UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);              \
 
311
     UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);            \
 
312
     UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);             \
 
313
   }                                                            \
 
314
} while (0)
 
315
#define VERT_COPY_SPEC( v0, v1 )                        \
 
316
do {                                                    \
 
317
   if (specoffset) {                                    \
 
318
      v0->ub4[specoffset][0] = v1->ub4[specoffset][0];  \
 
319
      v0->ub4[specoffset][1] = v1->ub4[specoffset][1];  \
 
320
      v0->ub4[specoffset][2] = v1->ub4[specoffset][2];  \
 
321
   }                                                    \
 
322
} while (0)
 
323
 
 
324
 
 
325
#define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
 
326
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
 
327
#define VERT_SAVE_SPEC( idx )    if (specoffset) spec[idx] = v[idx]->ui[specoffset]
 
328
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
 
329
 
 
330
 
 
331
#define LOCAL_VARS(n)                                                   \
 
332
    struct via_context *vmesa = VIA_CONTEXT(ctx);                             \
 
333
    GLuint color[n], spec[n];                                           \
 
334
    GLuint coloroffset = vmesa->coloroffset;              \
 
335
    GLuint specoffset = vmesa->specoffset;                       \
 
336
    (void)color; (void)spec; (void)coloroffset; (void)specoffset;
 
337
 
 
338
 
 
339
/***********************************************************************
 
340
 *                Helpers for rendering unfilled primitives            *
 
341
 ***********************************************************************/
 
342
 
 
343
static const GLenum hwPrim[GL_POLYGON + 2] = {
 
344
    GL_POINTS,
 
345
    GL_LINES,
 
346
    GL_LINES,
 
347
    GL_LINES,
 
348
    GL_TRIANGLES,
 
349
    GL_TRIANGLES,
 
350
    GL_TRIANGLES,
 
351
    GL_TRIANGLES,
 
352
    GL_TRIANGLES,
 
353
    GL_TRIANGLES,
 
354
    GL_POLYGON+1
 
355
};
 
356
 
 
357
 
 
358
#define RASTERIZE(x) viaRasterPrimitive( ctx, x, hwPrim[x] )
 
359
#define RENDER_PRIMITIVE vmesa->renderPrimitive
 
360
#define TAG(x) x
 
361
#define IND VIA_FALLBACK_BIT
 
362
#include "tnl_dd/t_dd_unfilled.h"
 
363
#undef IND
 
364
#undef RASTERIZE
 
365
 
 
366
/***********************************************************************
 
367
 *                      Generate GL render functions                   *
 
368
 ***********************************************************************/
 
369
#define RASTERIZE(x)
 
370
 
 
371
#define IND (0)
 
372
#define TAG(x) x
 
373
#include "tnl_dd/t_dd_tritmp.h"
 
374
 
 
375
#define IND (VIA_OFFSET_BIT)
 
376
#define TAG(x) x##_offset
 
377
#include "tnl_dd/t_dd_tritmp.h"
 
378
 
 
379
#define IND (VIA_TWOSIDE_BIT)
 
380
#define TAG(x) x##_twoside
 
381
#include "tnl_dd/t_dd_tritmp.h"
 
382
 
 
383
#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT)
 
384
#define TAG(x) x##_twoside_offset
 
385
#include "tnl_dd/t_dd_tritmp.h"
 
386
 
 
387
#define IND (VIA_UNFILLED_BIT)
 
388
#define TAG(x) x##_unfilled
 
389
#include "tnl_dd/t_dd_tritmp.h"
 
390
 
 
391
#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
 
392
#define TAG(x) x##_offset_unfilled
 
393
#include "tnl_dd/t_dd_tritmp.h"
 
394
 
 
395
#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT)
 
396
#define TAG(x) x##_twoside_unfilled
 
397
#include "tnl_dd/t_dd_tritmp.h"
 
398
 
 
399
#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
 
400
#define TAG(x) x##_twoside_offset_unfilled
 
401
#include "tnl_dd/t_dd_tritmp.h"
 
402
 
 
403
#define IND (VIA_FALLBACK_BIT)
 
404
#define TAG(x) x##_fallback
 
405
#include "tnl_dd/t_dd_tritmp.h"
 
406
 
 
407
#define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
 
408
#define TAG(x) x##_offset_fallback
 
409
#include "tnl_dd/t_dd_tritmp.h"
 
410
 
 
411
#define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT)
 
412
#define TAG(x) x##_twoside_fallback
 
413
#include "tnl_dd/t_dd_tritmp.h"
 
414
 
 
415
#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
 
416
#define TAG(x) x##_twoside_offset_fallback
 
417
#include "tnl_dd/t_dd_tritmp.h"
 
418
 
 
419
#define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
 
420
#define TAG(x) x##_unfilled_fallback
 
421
#include "tnl_dd/t_dd_tritmp.h"
 
422
 
 
423
#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
 
424
#define TAG(x) x##_offset_unfilled_fallback
 
425
#include "tnl_dd/t_dd_tritmp.h"
 
426
 
 
427
#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
 
428
#define TAG(x) x##_twoside_unfilled_fallback
 
429
#include "tnl_dd/t_dd_tritmp.h"
 
430
 
 
431
#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT| \
 
432
             VIA_FALLBACK_BIT)
 
433
#define TAG(x) x##_twoside_offset_unfilled_fallback
 
434
#include "tnl_dd/t_dd_tritmp.h"
 
435
 
 
436
 
 
437
/* Catchall case for flat, separate specular triangles (via has flat
 
438
 * diffuse shading, but always does specular color with gouraud).
 
439
 */
 
440
#undef  DO_FALLBACK
 
441
#undef  DO_OFFSET
 
442
#undef  DO_UNFILLED
 
443
#undef  DO_TWOSIDE
 
444
#undef  DO_FLAT
 
445
#define DO_FALLBACK (0)
 
446
#define DO_OFFSET   (ctx->_TriangleCaps & DD_TRI_OFFSET)
 
447
#define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED)
 
448
#define DO_TWOSIDE  (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
 
449
#define DO_FLAT     1
 
450
#define TAG(x) x##_flat_specular
 
451
#define IND VIA_MAX_TRIFUNC
 
452
#include "tnl_dd/t_dd_tritmp.h"
 
453
 
 
454
 
 
455
static void init_rast_tab(void)
 
456
{
 
457
    init();
 
458
    init_offset();
 
459
    init_twoside();
 
460
    init_twoside_offset();
 
461
    init_unfilled();
 
462
    init_offset_unfilled();
 
463
    init_twoside_unfilled();
 
464
    init_twoside_offset_unfilled();
 
465
    init_fallback();
 
466
    init_offset_fallback();
 
467
    init_twoside_fallback();
 
468
    init_twoside_offset_fallback();
 
469
    init_unfilled_fallback();
 
470
    init_offset_unfilled_fallback();
 
471
    init_twoside_unfilled_fallback();
 
472
    init_twoside_offset_unfilled_fallback();
 
473
 
 
474
    init_flat_specular();       /* special! */
 
475
}
 
476
 
 
477
 
 
478
/***********************************************************************
 
479
 *                    Rasterization fallback helpers                   *
 
480
 ***********************************************************************/
 
481
 
 
482
 
 
483
/* This code is hit only when a mix of accelerated and unaccelerated
 
484
 * primitives are being drawn, and only for the unaccelerated
 
485
 * primitives.
 
486
 */
 
487
static void
 
488
via_fallback_tri(struct via_context *vmesa,
 
489
                 viaVertex *v0,
 
490
                 viaVertex *v1,
 
491
                 viaVertex *v2)
 
492
{    
 
493
    GLcontext *ctx = vmesa->glCtx;
 
494
    SWvertex v[3];
 
495
    _swsetup_Translate(ctx, v0, &v[0]);
 
496
    _swsetup_Translate(ctx, v1, &v[1]);
 
497
    _swsetup_Translate(ctx, v2, &v[2]);
 
498
    viaSpanRenderStart( ctx );
 
499
    _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
 
500
    viaSpanRenderFinish( ctx );
 
501
}
 
502
 
 
503
 
 
504
static void
 
505
via_fallback_line(struct via_context *vmesa,
 
506
                  viaVertex *v0,
 
507
                  viaVertex *v1)
 
508
{
 
509
    GLcontext *ctx = vmesa->glCtx;
 
510
    SWvertex v[2];
 
511
    _swsetup_Translate(ctx, v0, &v[0]);
 
512
    _swsetup_Translate(ctx, v1, &v[1]);
 
513
    viaSpanRenderStart( ctx );
 
514
    _swrast_Line(ctx, &v[0], &v[1]);
 
515
    viaSpanRenderFinish( ctx );
 
516
}
 
517
 
 
518
 
 
519
static void
 
520
via_fallback_point(struct via_context *vmesa,
 
521
                   viaVertex *v0)
 
522
{
 
523
    GLcontext *ctx = vmesa->glCtx;
 
524
    SWvertex v[1];
 
525
    _swsetup_Translate(ctx, v0, &v[0]);
 
526
    viaSpanRenderStart( ctx );
 
527
    _swrast_Point(ctx, &v[0]);
 
528
    viaSpanRenderFinish( ctx );
 
529
}
 
530
 
 
531
static void viaResetLineStipple( GLcontext *ctx )
 
532
{
 
533
   struct via_context *vmesa = VIA_CONTEXT(ctx);
 
534
   vmesa->regCmdB |= HC_HLPrst_MASK;
 
535
}
 
536
 
 
537
/**********************************************************************/
 
538
/*               Render unclipped begin/end objects                   */
 
539
/**********************************************************************/
 
540
#define IND 0
 
541
#define V(x) (viaVertex *)(vertptr + ((x) * vertsize * sizeof(int)))
 
542
#define RENDER_POINTS(start, count)   \
 
543
    for (; start < count; start++) POINT(V(ELT(start)));
 
544
#define RENDER_LINE(v0, v1)         LINE(V(v0), V(v1))
 
545
#define RENDER_TRI( v0, v1, v2)     TRI( V(v0), V(v1), V(v2))
 
546
#define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
 
547
#define INIT(x) viaRasterPrimitive(ctx, x, hwPrim[x])
 
548
#undef LOCAL_VARS
 
549
#define LOCAL_VARS                                              \
 
550
    struct via_context *vmesa = VIA_CONTEXT(ctx);                     \
 
551
    GLubyte *vertptr = (GLubyte *)vmesa->verts;                 \
 
552
    const GLuint vertsize = vmesa->vertexSize;          \
 
553
    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;       \
 
554
   const GLboolean stipple = ctx->Line.StippleFlag;             \
 
555
   (void) elt; (void) stipple;
 
556
#define RESET_STIPPLE   if ( stipple ) viaResetLineStipple( ctx );
 
557
#define RESET_OCCLUSION
 
558
#define PRESERVE_VB_DEFS
 
559
#define ELT(x) x
 
560
#define TAG(x) via_##x##_verts
 
561
#include "tnl/t_vb_rendertmp.h"
 
562
#undef ELT
 
563
#undef TAG
 
564
#define TAG(x) via_##x##_elts
 
565
#define ELT(x) elt[x]
 
566
#include "tnl/t_vb_rendertmp.h"
 
567
#undef ELT
 
568
#undef TAG
 
569
#undef NEED_EDGEFLAG_SETUP
 
570
#undef EDGEFLAG_GET
 
571
#undef EDGEFLAG_SET
 
572
#undef RESET_OCCLUSION
 
573
 
 
574
 
 
575
/**********************************************************************/
 
576
/*                   Render clipped primitives                        */
 
577
/**********************************************************************/
 
578
 
 
579
 
 
580
 
 
581
static void viaRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
 
582
                                 GLuint n)
 
583
{
 
584
    TNLcontext *tnl = TNL_CONTEXT(ctx);
 
585
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
586
    GLuint prim = VIA_CONTEXT(ctx)->renderPrimitive;
 
587
 
 
588
    /* Render the new vertices as an unclipped polygon.
 
589
     */
 
590
    {
 
591
        GLuint *tmp = VB->Elts;
 
592
        VB->Elts = (GLuint *)elts;
 
593
        tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n,
 
594
                                                   PRIM_BEGIN|PRIM_END);
 
595
        VB->Elts = tmp;
 
596
    }
 
597
 
 
598
    /* Restore the render primitive
 
599
     */
 
600
    if (prim != GL_POLYGON &&
 
601
        prim != GL_POLYGON + 1)
 
602
       tnl->Driver.Render.PrimitiveNotify( ctx, prim );
 
603
}
 
604
 
 
605
static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
 
606
{
 
607
    TNLcontext *tnl = TNL_CONTEXT(ctx);
 
608
    tnl->Driver.Render.Line(ctx, ii, jj);
 
609
}
 
610
 
 
611
static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
 
612
                                     GLuint n)
 
613
{
 
614
    struct via_context *vmesa = VIA_CONTEXT(ctx);
 
615
    GLuint vertsize = vmesa->vertexSize;
 
616
    GLuint *vb = viaExtendPrimitive(vmesa, (n - 2) * 3 * 4 * vertsize);
 
617
    GLubyte *vertptr = (GLubyte *)vmesa->verts;
 
618
    const GLuint *start = (const GLuint *)V(elts[0]);
 
619
    int i;
 
620
 
 
621
    for (i = 2; i < n; i++) {
 
622
        COPY_DWORDS(vb, vertsize, V(elts[i - 1]));
 
623
        COPY_DWORDS(vb, vertsize, V(elts[i]));
 
624
        COPY_DWORDS(vb, vertsize, start);       
 
625
    }
 
626
}
 
627
 
 
628
 
 
629
/**********************************************************************/
 
630
/*                    Choose render functions                         */
 
631
/**********************************************************************/
 
632
 
 
633
 
 
634
#define _VIA_NEW_VERTEX (_NEW_TEXTURE |                         \
 
635
                         _DD_NEW_SEPARATE_SPECULAR |            \
 
636
                         _DD_NEW_TRI_UNFILLED |                 \
 
637
                         _DD_NEW_TRI_LIGHT_TWOSIDE |            \
 
638
                         _NEW_FOG)
 
639
 
 
640
#define _VIA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE |            \
 
641
                              _DD_NEW_TRI_UNFILLED |            \
 
642
                              _DD_NEW_TRI_LIGHT_TWOSIDE |       \
 
643
                              _DD_NEW_TRI_OFFSET |              \
 
644
                              _DD_NEW_TRI_STIPPLE |             \
 
645
                              _NEW_POLYGONSTIPPLE)
 
646
 
 
647
 
 
648
static void viaChooseRenderState(GLcontext *ctx)
 
649
{
 
650
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
651
   struct via_context *vmesa = VIA_CONTEXT(ctx);
 
652
   GLuint flags = ctx->_TriangleCaps;
 
653
   GLuint index = 0;
 
654
 
 
655
   if (vmesa->ptexHack) {
 
656
      vmesa->drawPoint = via_ptex_point;
 
657
      vmesa->drawLine = via_ptex_line;
 
658
      vmesa->drawTri = via_ptex_tri;
 
659
      index |= VIA_FALLBACK_BIT;
 
660
   }
 
661
   else {
 
662
      vmesa->drawPoint = via_draw_point;
 
663
      vmesa->drawLine = via_draw_line;
 
664
      vmesa->drawTri = via_draw_triangle;
 
665
   }
 
666
 
 
667
   if (flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) {
 
668
      if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
 
669
         index |= VIA_TWOSIDE_BIT;
 
670
      if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL)
 
671
         index |= VIA_UNFILLED_BIT;
 
672
      if (flags & DD_TRI_OFFSET)
 
673
         index |= VIA_OFFSET_BIT;
 
674
      if (flags & ANY_FALLBACK_FLAGS)
 
675
         index |= VIA_FALLBACK_BIT;
 
676
 
 
677
      /* Hook in fallbacks for specific primitives. */
 
678
      if (flags & POINT_FALLBACK)
 
679
         vmesa->drawPoint = via_fallback_point;
 
680
      
 
681
      if (flags & LINE_FALLBACK)
 
682
         vmesa->drawLine = via_fallback_line;
 
683
 
 
684
      if (flags & TRI_FALLBACK)
 
685
         vmesa->drawTri = via_fallback_tri;
 
686
   }
 
687
 
 
688
   if ((flags & DD_SEPARATE_SPECULAR) && ctx->Light.ShadeModel == GL_FLAT)
 
689
      index = VIA_MAX_TRIFUNC;  /* flat specular */
 
690
 
 
691
   if (vmesa->renderIndex != index) {
 
692
      vmesa->renderIndex = index;
 
693
 
 
694
      tnl->Driver.Render.Points = rast_tab[index].points;
 
695
      tnl->Driver.Render.Line = rast_tab[index].line;
 
696
      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
 
697
      tnl->Driver.Render.Quad = rast_tab[index].quad;
 
698
 
 
699
      if (index == 0) {
 
700
         tnl->Driver.Render.PrimTabVerts = via_render_tab_verts;
 
701
         tnl->Driver.Render.PrimTabElts = via_render_tab_elts;
 
702
         tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
 
703
         tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly;
 
704
      }
 
705
      else {
 
706
         tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
 
707
         tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
 
708
         tnl->Driver.Render.ClippedLine = viaRenderClippedLine;
 
709
         tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly;
 
710
      }
 
711
   }
 
712
}
 
713
 
 
714
 
 
715
#define VIA_EMIT_TEX1   0x01
 
716
#define VIA_EMIT_TEX0   0x02
 
717
#define VIA_EMIT_PTEX0  0x04
 
718
#define VIA_EMIT_RGBA   0x08
 
719
#define VIA_EMIT_SPEC   0x10
 
720
#define VIA_EMIT_FOG    0x20
 
721
#define VIA_EMIT_W      0x40
 
722
 
 
723
#define EMIT_ATTR( ATTR, STYLE, INDEX, REGB )                           \
 
724
do {                                                                    \
 
725
   vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = (ATTR);       \
 
726
   vmesa->vertex_attrs[vmesa->vertex_attr_count].format = (STYLE);      \
 
727
   vmesa->vertex_attr_count++;                                          \
 
728
   setupIndex |= (INDEX);                                               \
 
729
   regCmdB |= (REGB);                                                   \
 
730
} while (0)
 
731
 
 
732
#define EMIT_PAD( N )                                                   \
 
733
do {                                                                    \
 
734
   vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = 0;            \
 
735
   vmesa->vertex_attrs[vmesa->vertex_attr_count].format = EMIT_PAD;     \
 
736
   vmesa->vertex_attrs[vmesa->vertex_attr_count].offset = (N);          \
 
737
   vmesa->vertex_attr_count++;                                          \
 
738
} while (0)
 
739
 
 
740
 
 
741
 
 
742
static void viaChooseVertexState( GLcontext *ctx )
 
743
{
 
744
   struct via_context *vmesa = VIA_CONTEXT(ctx);
 
745
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
746
   DECLARE_RENDERINPUTS(index_bitset);
 
747
   GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z;
 
748
   GLuint setupIndex = 0;
 
749
 
 
750
   RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
751
   vmesa->vertex_attr_count = 0;
 
752
 
 
753
   /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
 
754
    * build up a hardware vertex.
 
755
    */
 
756
   if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) ||
 
757
       RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
 
758
      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W );
 
759
      vmesa->coloroffset = 4;
 
760
   }
 
761
   else {
 
762
      EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
 
763
      vmesa->coloroffset = 3;
 
764
   }
 
765
 
 
766
   /* t_context.c always includes a diffuse color */
 
767
   EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA, 
 
768
              HC_HVPMSK_Cd );
 
769
      
 
770
   vmesa->specoffset = 0;
 
771
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
 
772
       RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
 
773
      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
 
774
         vmesa->specoffset = vmesa->coloroffset + 1;
 
775
         EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC, 
 
776
                    HC_HVPMSK_Cs );
 
777
      }
 
778
      else
 
779
         EMIT_PAD( 3 );
 
780
 
 
781
      if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
 
782
         EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs );
 
783
      else
 
784
         EMIT_PAD( 1 );
 
785
   }
 
786
 
 
787
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
 
788
      if (vmesa->ptexHack)
 
789
         EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0, 
 
790
                    (HC_HVPMSK_S | HC_HVPMSK_T) );
 
791
      else 
 
792
         EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0, 
 
793
                    (HC_HVPMSK_S | HC_HVPMSK_T) );
 
794
   }
 
795
 
 
796
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
 
797
      EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1, 
 
798
                 (HC_HVPMSK_S | HC_HVPMSK_T) );
 
799
   }
 
800
 
 
801
   if (setupIndex != vmesa->setupIndex) {
 
802
      vmesa->vertexSize = _tnl_install_attrs( ctx, 
 
803
                                               vmesa->vertex_attrs, 
 
804
                                               vmesa->vertex_attr_count,
 
805
                                               vmesa->ViewportMatrix.m, 0 );
 
806
      vmesa->vertexSize >>= 2;
 
807
      vmesa->setupIndex = setupIndex;
 
808
      vmesa->regCmdB &= ~HC_HVPMSK_MASK;
 
809
      vmesa->regCmdB |= regCmdB;
 
810
 
 
811
      if (vmesa->ptexHack) 
 
812
         vmesa->hwVertexSize = vmesa->vertexSize - 1;
 
813
      else
 
814
         vmesa->hwVertexSize = vmesa->vertexSize;
 
815
   }
 
816
}
 
817
 
 
818
 
 
819
 
 
820
 
 
821
/* Check if projective texture coordinates are used and if we can fake
 
822
 * them. Fallback to swrast if we can't. Returns GL_TRUE if projective
 
823
 * texture coordinates must be faked, GL_FALSE otherwise.
 
824
 */
 
825
static GLboolean viaCheckPTexHack( GLcontext *ctx )
 
826
{
 
827
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
828
   struct vertex_buffer *VB = &tnl->vb;
 
829
   DECLARE_RENDERINPUTS(index_bitset);
 
830
   GLboolean fallback = GL_FALSE;
 
831
   GLboolean ptexHack = GL_FALSE;
 
832
 
 
833
   RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
834
 
 
835
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
 
836
      if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
 
837
         ptexHack = GL_TRUE; 
 
838
      else
 
839
         fallback = GL_TRUE;
 
840
   }
 
841
   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
 
842
      fallback = GL_TRUE;
 
843
 
 
844
   FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback);
 
845
   return ptexHack;
 
846
}
 
847
 
 
848
 
 
849
 
 
850
 
 
851
/**********************************************************************/
 
852
/*                 High level hooks for t_vb_render.c                 */
 
853
/**********************************************************************/
 
854
 
 
855
 
 
856
static void viaRenderStart(GLcontext *ctx)
 
857
{
 
858
   struct via_context *vmesa = VIA_CONTEXT(ctx);
 
859
   TNLcontext *tnl = TNL_CONTEXT(ctx);
 
860
   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
861
 
 
862
   {
 
863
      GLboolean ptexHack = viaCheckPTexHack( ctx );
 
864
      if (ptexHack != vmesa->ptexHack) {
 
865
         vmesa->ptexHack = ptexHack;
 
866
         vmesa->newRenderState |= _VIA_NEW_RENDERSTATE;
 
867
      }
 
868
   }
 
869
 
 
870
   if (vmesa->newState) {
 
871
      vmesa->newRenderState |= vmesa->newState;
 
872
      viaValidateState( ctx );
 
873
   }
 
874
 
 
875
   if (vmesa->Fallback) {
 
876
      tnl->Driver.Render.Start(ctx);
 
877
      return;
 
878
   }
 
879
 
 
880
   if (vmesa->newRenderState) {
 
881
      viaChooseVertexState(ctx);
 
882
      viaChooseRenderState(ctx);
 
883
      vmesa->newRenderState = 0;
 
884
   }
 
885
 
 
886
   /* Important:
 
887
    */
 
888
   VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
 
889
}
 
890
 
 
891
static void viaRenderFinish(GLcontext *ctx)
 
892
{
 
893
   VIA_FINISH_PRIM(VIA_CONTEXT(ctx));
 
894
}
 
895
 
 
896
 
 
897
/* System to flush dma and emit state changes based on the rasterized
 
898
 * primitive.
 
899
 */
 
900
void viaRasterPrimitive(GLcontext *ctx,
 
901
                        GLenum glprim,
 
902
                        GLenum hwprim)
 
903
{
 
904
   struct via_context *vmesa = VIA_CONTEXT(ctx);
 
905
   GLuint regCmdB;
 
906
   RING_VARS;
 
907
 
 
908
   if (VIA_DEBUG & DEBUG_PRIMS) 
 
909
      fprintf(stderr, "%s: %s/%s/%s\n", 
 
910
              __FUNCTION__, _mesa_lookup_enum_by_nr(glprim),
 
911
              _mesa_lookup_enum_by_nr(hwprim),
 
912
              _mesa_lookup_enum_by_nr(ctx->Light.ShadeModel));
 
913
 
 
914
   assert (!vmesa->newState);
 
915
 
 
916
   vmesa->renderPrimitive = glprim;
 
917
 
 
918
   if (hwprim != vmesa->hwPrimitive ||
 
919
       ctx->Light.ShadeModel != vmesa->hwShadeModel) {
 
920
 
 
921
      VIA_FINISH_PRIM(vmesa);
 
922
 
 
923
      /* Ensure no wrapping inside this function  */    
 
924
      viaCheckDma( vmesa, 1024 );       
 
925
 
 
926
      if (vmesa->newEmitState) {
 
927
         viaEmitState(vmesa);
 
928
      }
 
929
       
 
930
      vmesa->regCmdA_End = HC_ACMD_HCmdA;
 
931
 
 
932
      if (ctx->Light.ShadeModel == GL_SMOOTH) {
 
933
         vmesa->regCmdA_End |= HC_HShading_Gouraud;
 
934
      }
 
935
      
 
936
      vmesa->hwShadeModel = ctx->Light.ShadeModel;
 
937
      regCmdB = vmesa->regCmdB;
 
938
 
 
939
      switch (hwprim) {
 
940
      case GL_POINTS:
 
941
         vmesa->regCmdA_End |= HC_HPMType_Point | HC_HVCycle_Full;
 
942
         vmesa->regCmdA_End |= HC_HShading_Gouraud; /* always Gouraud 
 
943
                                                       shade points?!? */
 
944
         break;
 
945
      case GL_LINES:
 
946
         vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_Full;
 
947
         regCmdB |= HC_HLPrst_MASK;
 
948
         if (ctx->Light.ShadeModel == GL_FLAT)
 
949
            vmesa->regCmdA_End |= HC_HShading_FlatB; 
 
950
         break;
 
951
      case GL_LINE_LOOP:
 
952
      case GL_LINE_STRIP:
 
953
         vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_AFP |
 
954
            HC_HVCycle_AB | HC_HVCycle_NewB;
 
955
         regCmdB |= HC_HVCycle_AB | HC_HVCycle_NewB | HC_HLPrst_MASK;
 
956
         if (ctx->Light.ShadeModel == GL_FLAT)
 
957
            vmesa->regCmdA_End |= HC_HShading_FlatB; 
 
958
         break;
 
959
      case GL_TRIANGLES:
 
960
         vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_Full;
 
961
         if (ctx->Light.ShadeModel == GL_FLAT)
 
962
            vmesa->regCmdA_End |= HC_HShading_FlatC; 
 
963
         break;
 
964
      case GL_TRIANGLE_STRIP:
 
965
         vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
 
966
            HC_HVCycle_AC | HC_HVCycle_BB | HC_HVCycle_NewC;
 
967
         regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
 
968
         if (ctx->Light.ShadeModel == GL_FLAT)
 
969
            vmesa->regCmdA_End |= HC_HShading_FlatC; 
 
970
         break;
 
971
      case GL_TRIANGLE_FAN:
 
972
         vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
 
973
            HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
 
974
         regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
 
975
         if (ctx->Light.ShadeModel == GL_FLAT)
 
976
            vmesa->regCmdA_End |= HC_HShading_FlatC; 
 
977
         break;
 
978
      case GL_QUADS:
 
979
         abort();
 
980
         return;
 
981
      case GL_QUAD_STRIP:
 
982
         abort();
 
983
         return;
 
984
      case GL_POLYGON:
 
985
         vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
 
986
            HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
 
987
         regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
 
988
         if (ctx->Light.ShadeModel == GL_FLAT)
 
989
            vmesa->regCmdA_End |= HC_HShading_FlatC; 
 
990
         break;                          
 
991
      default:
 
992
         abort();
 
993
         return;
 
994
      }
 
995
    
 
996
/*     assert((vmesa->dmaLow & 0x4) == 0); */
 
997
 
 
998
      if (vmesa->dmaCliprectAddr == ~0) {
 
999
         if (VIA_DEBUG & DEBUG_DMA) 
 
1000
            fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
 
1001
         vmesa->dmaCliprectAddr = vmesa->dmaLow;
 
1002
         BEGIN_RING(8);
 
1003
         OUT_RING( HC_HEADER2 );    
 
1004
         OUT_RING( (HC_ParaType_NotTex << 16) );
 
1005
         OUT_RING( 0xCCCCCCCC );
 
1006
         OUT_RING( 0xCCCCCCCC );
 
1007
         OUT_RING( 0xCCCCCCCC );
 
1008
         OUT_RING( 0xCCCCCCCC );
 
1009
         OUT_RING( 0xCCCCCCCC );
 
1010
         OUT_RING( 0xCCCCCCCC );
 
1011
         ADVANCE_RING();
 
1012
      }
 
1013
 
 
1014
      assert(vmesa->dmaLastPrim == 0);
 
1015
 
 
1016
      BEGIN_RING(8);
 
1017
      OUT_RING( HC_HEADER2 );    
 
1018
      OUT_RING( (HC_ParaType_NotTex << 16) );
 
1019
      OUT_RING( 0xCCCCCCCC );
 
1020
      OUT_RING( 0xDDDDDDDD );
 
1021
 
 
1022
      OUT_RING( HC_HEADER2 );    
 
1023
      OUT_RING( (HC_ParaType_CmdVdata << 16) );
 
1024
      OUT_RING( regCmdB );
 
1025
      OUT_RING( vmesa->regCmdA_End );
 
1026
      ADVANCE_RING();
 
1027
 
 
1028
      vmesa->hwPrimitive = hwprim;        
 
1029
      vmesa->dmaLastPrim = vmesa->dmaLow;
 
1030
   }
 
1031
   else {
 
1032
      assert(!vmesa->newEmitState);
 
1033
   }
 
1034
}
 
1035
 
 
1036
/* Callback for mesa:
 
1037
 */
 
1038
static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
 
1039
{
 
1040
   viaRasterPrimitive( ctx, prim, hwPrim[prim] );
 
1041
}
 
1042
 
 
1043
 
 
1044
void viaFinishPrimitive(struct via_context *vmesa)
 
1045
{
 
1046
   if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS)) 
 
1047
      fprintf(stderr, "%s\n", __FUNCTION__);
 
1048
 
 
1049
   if (!vmesa->dmaLastPrim || vmesa->dmaCliprectAddr == ~0) {
 
1050
      assert(0);
 
1051
   }
 
1052
   else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
 
1053
      GLuint cmdA = (vmesa->regCmdA_End | HC_HPLEND_MASK | 
 
1054
                     HC_HPMValidN_MASK | HC_HE3Fire_MASK); 
 
1055
      RING_VARS;
 
1056
 
 
1057
      vmesa->dmaLastPrim = 0;
 
1058
 
 
1059
      /* KW: modified 0x1 to 0x4 below:
 
1060
       */
 
1061
      if ((vmesa->dmaLow & 0x4) || !vmesa->useAgp) {
 
1062
         BEGIN_RING_NOCHECK( 1 );
 
1063
         OUT_RING( cmdA );
 
1064
         ADVANCE_RING();
 
1065
      }   
 
1066
      else {      
 
1067
         BEGIN_RING_NOCHECK( 2 );
 
1068
         OUT_RING( cmdA );
 
1069
         OUT_RING( cmdA );
 
1070
         ADVANCE_RING();
 
1071
      }   
 
1072
 
 
1073
      if (vmesa->dmaLow > VIA_DMA_HIGHWATER)
 
1074
         viaFlushDma( vmesa );
 
1075
   }
 
1076
   else {
 
1077
      if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS)) 
 
1078
         fprintf(stderr, "remove empty primitive\n");
 
1079
 
 
1080
      /* Remove the primitive header:
 
1081
       */
 
1082
      vmesa->dmaLastPrim = 0;
 
1083
      vmesa->dmaLow -= 8 * sizeof(GLuint);
 
1084
 
 
1085
      /* Maybe remove the cliprect as well:
 
1086
       */
 
1087
      if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) {
 
1088
         vmesa->dmaLow -= 8 * sizeof(GLuint);
 
1089
         vmesa->dmaCliprectAddr = ~0;
 
1090
      }
 
1091
   }
 
1092
 
 
1093
   vmesa->renderPrimitive = GL_POLYGON + 1;
 
1094
   vmesa->hwPrimitive = GL_POLYGON + 1;
 
1095
   vmesa->dmaLastPrim = 0;
 
1096
}
 
1097
 
 
1098
 
 
1099
/**********************************************************************/
 
1100
/*           Transition to/from hardware rasterization.               */
 
1101
/**********************************************************************/
 
1102
 
 
1103
 
 
1104
void viaFallback(struct via_context *vmesa, GLuint bit, GLboolean mode)
 
1105
{
 
1106
    GLcontext *ctx = vmesa->glCtx;
 
1107
    TNLcontext *tnl = TNL_CONTEXT(ctx);
 
1108
    GLuint oldfallback = vmesa->Fallback;
 
1109
    
 
1110
    if (mode) {
 
1111
        vmesa->Fallback |= bit;
 
1112
        if (oldfallback == 0) {
 
1113
            VIA_FLUSH_DMA(vmesa);
 
1114
 
 
1115
            if (VIA_DEBUG & DEBUG_FALLBACKS) 
 
1116
               fprintf(stderr, "ENTER FALLBACK %x\n", bit);
 
1117
 
 
1118
            _swsetup_Wakeup(ctx);
 
1119
            vmesa->renderIndex = ~0;
 
1120
        }
 
1121
    }
 
1122
    else {
 
1123
        vmesa->Fallback &= ~bit;
 
1124
        if (oldfallback == bit) {
 
1125
            _swrast_flush( ctx );
 
1126
 
 
1127
            if (VIA_DEBUG & DEBUG_FALLBACKS) 
 
1128
               fprintf(stderr, "LEAVE FALLBACK %x\n", bit);
 
1129
 
 
1130
            tnl->Driver.Render.Start = viaRenderStart;
 
1131
            tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
 
1132
            tnl->Driver.Render.Finish = viaRenderFinish;
 
1133
 
 
1134
            tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
 
1135
            tnl->Driver.Render.CopyPV = _tnl_copy_pv;
 
1136
            tnl->Driver.Render.Interp = _tnl_interp;
 
1137
            tnl->Driver.Render.ResetLineStipple = viaResetLineStipple;
 
1138
 
 
1139
            _tnl_invalidate_vertex_state( ctx, ~0 );
 
1140
            _tnl_invalidate_vertices( ctx, ~0 );
 
1141
            _tnl_install_attrs( ctx, 
 
1142
                                vmesa->vertex_attrs, 
 
1143
                                vmesa->vertex_attr_count,
 
1144
                                vmesa->ViewportMatrix.m, 0 ); 
 
1145
 
 
1146
            vmesa->newState |= (_VIA_NEW_RENDERSTATE|_VIA_NEW_VERTEX);
 
1147
        }
 
1148
    }    
 
1149
}
 
1150
 
 
1151
static void viaRunPipeline( GLcontext *ctx )
 
1152
{
 
1153
   struct via_context *vmesa = VIA_CONTEXT(ctx);
 
1154
 
 
1155
   if (vmesa->newState) {
 
1156
      vmesa->newRenderState |= vmesa->newState;
 
1157
      viaValidateState( ctx );
 
1158
   }
 
1159
 
 
1160
   _tnl_run_pipeline( ctx );
 
1161
}
 
1162
 
 
1163
 
 
1164
/**********************************************************************/
 
1165
/*                            Initialization.                         */
 
1166
/**********************************************************************/
 
1167
 
 
1168
 
 
1169
void viaInitTriFuncs(GLcontext *ctx)
 
1170
{
 
1171
    struct via_context *vmesa = VIA_CONTEXT(ctx);
 
1172
    TNLcontext *tnl = TNL_CONTEXT(ctx);
 
1173
    static int firsttime = 1;
 
1174
 
 
1175
    if (firsttime) {
 
1176
        init_rast_tab();
 
1177
        firsttime = 0;
 
1178
    }
 
1179
 
 
1180
    tnl->Driver.RunPipeline = viaRunPipeline;
 
1181
    tnl->Driver.Render.Start = viaRenderStart;
 
1182
    tnl->Driver.Render.Finish = viaRenderFinish;
 
1183
    tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
 
1184
    tnl->Driver.Render.ResetLineStipple = viaResetLineStipple;
 
1185
    tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
 
1186
    tnl->Driver.Render.CopyPV = _tnl_copy_pv;
 
1187
    tnl->Driver.Render.Interp = _tnl_interp;
 
1188
 
 
1189
    _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 
 
1190
                        (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
 
1191
   
 
1192
    vmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
 
1193
 
 
1194
}