llvmpipe: check for texture usage in all scenes
[mesa.git] / src / mesa / drivers / dri / unichrome / via_tris.c
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 "main/glheader.h"
29 #include "main/context.h"
30 #include "main/mtypes.h"
31 #include "main/macros.h"
32 #include "main/colormac.h"
33 #include "main/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] = { 0 }; \
334 GLuint spec[n] = { 0 }; \
335 GLuint coloroffset = vmesa->coloroffset; \
336 GLuint specoffset = vmesa->specoffset; \
337 (void)color; (void)spec; (void)coloroffset; (void)specoffset;
338
339
340 /***********************************************************************
341 * Helpers for rendering unfilled primitives *
342 ***********************************************************************/
343
344 static const GLenum hwPrim[GL_POLYGON + 2] = {
345 GL_POINTS,
346 GL_LINES,
347 GL_LINES,
348 GL_LINES,
349 GL_TRIANGLES,
350 GL_TRIANGLES,
351 GL_TRIANGLES,
352 GL_TRIANGLES,
353 GL_TRIANGLES,
354 GL_TRIANGLES,
355 GL_POLYGON+1
356 };
357
358
359 #define RASTERIZE(x) viaRasterPrimitive( ctx, x, hwPrim[x] )
360 #define RENDER_PRIMITIVE vmesa->renderPrimitive
361 #define TAG(x) x
362 #define IND VIA_FALLBACK_BIT
363 #include "tnl_dd/t_dd_unfilled.h"
364 #undef IND
365 #undef RASTERIZE
366
367 /***********************************************************************
368 * Generate GL render functions *
369 ***********************************************************************/
370 #define RASTERIZE(x)
371
372 #define IND (0)
373 #define TAG(x) x
374 #include "tnl_dd/t_dd_tritmp.h"
375
376 #define IND (VIA_OFFSET_BIT)
377 #define TAG(x) x##_offset
378 #include "tnl_dd/t_dd_tritmp.h"
379
380 #define IND (VIA_TWOSIDE_BIT)
381 #define TAG(x) x##_twoside
382 #include "tnl_dd/t_dd_tritmp.h"
383
384 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT)
385 #define TAG(x) x##_twoside_offset
386 #include "tnl_dd/t_dd_tritmp.h"
387
388 #define IND (VIA_UNFILLED_BIT)
389 #define TAG(x) x##_unfilled
390 #include "tnl_dd/t_dd_tritmp.h"
391
392 #define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
393 #define TAG(x) x##_offset_unfilled
394 #include "tnl_dd/t_dd_tritmp.h"
395
396 #define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT)
397 #define TAG(x) x##_twoside_unfilled
398 #include "tnl_dd/t_dd_tritmp.h"
399
400 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
401 #define TAG(x) x##_twoside_offset_unfilled
402 #include "tnl_dd/t_dd_tritmp.h"
403
404 #define IND (VIA_FALLBACK_BIT)
405 #define TAG(x) x##_fallback
406 #include "tnl_dd/t_dd_tritmp.h"
407
408 #define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
409 #define TAG(x) x##_offset_fallback
410 #include "tnl_dd/t_dd_tritmp.h"
411
412 #define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT)
413 #define TAG(x) x##_twoside_fallback
414 #include "tnl_dd/t_dd_tritmp.h"
415
416 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
417 #define TAG(x) x##_twoside_offset_fallback
418 #include "tnl_dd/t_dd_tritmp.h"
419
420 #define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
421 #define TAG(x) x##_unfilled_fallback
422 #include "tnl_dd/t_dd_tritmp.h"
423
424 #define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
425 #define TAG(x) x##_offset_unfilled_fallback
426 #include "tnl_dd/t_dd_tritmp.h"
427
428 #define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
429 #define TAG(x) x##_twoside_unfilled_fallback
430 #include "tnl_dd/t_dd_tritmp.h"
431
432 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT| \
433 VIA_FALLBACK_BIT)
434 #define TAG(x) x##_twoside_offset_unfilled_fallback
435 #include "tnl_dd/t_dd_tritmp.h"
436
437
438 /* Catchall case for flat, separate specular triangles (via has flat
439 * diffuse shading, but always does specular color with gouraud).
440 */
441 #undef DO_FALLBACK
442 #undef DO_OFFSET
443 #undef DO_UNFILLED
444 #undef DO_TWOSIDE
445 #undef DO_FLAT
446 #define DO_FALLBACK (0)
447 #define DO_OFFSET (ctx->_TriangleCaps & DD_TRI_OFFSET)
448 #define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED)
449 #define DO_TWOSIDE (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
450 #define DO_FLAT 1
451 #define TAG(x) x##_flat_specular
452 #define IND VIA_MAX_TRIFUNC
453 #include "tnl_dd/t_dd_tritmp.h"
454
455
456 static void init_rast_tab(void)
457 {
458 init();
459 init_offset();
460 init_twoside();
461 init_twoside_offset();
462 init_unfilled();
463 init_offset_unfilled();
464 init_twoside_unfilled();
465 init_twoside_offset_unfilled();
466 init_fallback();
467 init_offset_fallback();
468 init_twoside_fallback();
469 init_twoside_offset_fallback();
470 init_unfilled_fallback();
471 init_offset_unfilled_fallback();
472 init_twoside_unfilled_fallback();
473 init_twoside_offset_unfilled_fallback();
474
475 init_flat_specular(); /* special! */
476 }
477
478
479 /***********************************************************************
480 * Rasterization fallback helpers *
481 ***********************************************************************/
482
483
484 /* This code is hit only when a mix of accelerated and unaccelerated
485 * primitives are being drawn, and only for the unaccelerated
486 * primitives.
487 */
488 static void
489 via_fallback_tri(struct via_context *vmesa,
490 viaVertex *v0,
491 viaVertex *v1,
492 viaVertex *v2)
493 {
494 GLcontext *ctx = vmesa->glCtx;
495 SWvertex v[3];
496 _swsetup_Translate(ctx, v0, &v[0]);
497 _swsetup_Translate(ctx, v1, &v[1]);
498 _swsetup_Translate(ctx, v2, &v[2]);
499 viaSpanRenderStart( ctx );
500 _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
501 viaSpanRenderFinish( ctx );
502 }
503
504
505 static void
506 via_fallback_line(struct via_context *vmesa,
507 viaVertex *v0,
508 viaVertex *v1)
509 {
510 GLcontext *ctx = vmesa->glCtx;
511 SWvertex v[2];
512 _swsetup_Translate(ctx, v0, &v[0]);
513 _swsetup_Translate(ctx, v1, &v[1]);
514 viaSpanRenderStart( ctx );
515 _swrast_Line(ctx, &v[0], &v[1]);
516 viaSpanRenderFinish( ctx );
517 }
518
519
520 static void
521 via_fallback_point(struct via_context *vmesa,
522 viaVertex *v0)
523 {
524 GLcontext *ctx = vmesa->glCtx;
525 SWvertex v[1];
526 _swsetup_Translate(ctx, v0, &v[0]);
527 viaSpanRenderStart( ctx );
528 _swrast_Point(ctx, &v[0]);
529 viaSpanRenderFinish( ctx );
530 }
531
532 static void viaResetLineStipple( GLcontext *ctx )
533 {
534 struct via_context *vmesa = VIA_CONTEXT(ctx);
535 vmesa->regCmdB |= HC_HLPrst_MASK;
536 }
537
538 /**********************************************************************/
539 /* Render unclipped begin/end objects */
540 /**********************************************************************/
541 #define IND 0
542 #define V(x) (viaVertex *)(vertptr + ((x) * vertsize * sizeof(int)))
543 #define RENDER_POINTS(start, count) \
544 for (; start < count; start++) POINT(V(ELT(start)));
545 #define RENDER_LINE(v0, v1) LINE(V(v0), V(v1))
546 #define RENDER_TRI( v0, v1, v2) TRI( V(v0), V(v1), V(v2))
547 #define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
548 #define INIT(x) viaRasterPrimitive(ctx, x, hwPrim[x])
549 #undef LOCAL_VARS
550 #define LOCAL_VARS \
551 struct via_context *vmesa = VIA_CONTEXT(ctx); \
552 GLubyte *vertptr = (GLubyte *)vmesa->verts; \
553 const GLuint vertsize = vmesa->vertexSize; \
554 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
555 const GLboolean stipple = ctx->Line.StippleFlag; \
556 (void) elt; (void) stipple;
557 #define RESET_STIPPLE if ( stipple ) viaResetLineStipple( ctx );
558 #define RESET_OCCLUSION
559 #define PRESERVE_VB_DEFS
560 #define ELT(x) x
561 #define TAG(x) via_##x##_verts
562 #include "tnl/t_vb_rendertmp.h"
563 #undef ELT
564 #undef TAG
565 #define TAG(x) via_##x##_elts
566 #define ELT(x) elt[x]
567 #include "tnl/t_vb_rendertmp.h"
568 #undef ELT
569 #undef TAG
570 #undef NEED_EDGEFLAG_SETUP
571 #undef EDGEFLAG_GET
572 #undef EDGEFLAG_SET
573 #undef RESET_OCCLUSION
574
575
576 /**********************************************************************/
577 /* Render clipped primitives */
578 /**********************************************************************/
579
580
581
582 static void viaRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
583 GLuint n)
584 {
585 TNLcontext *tnl = TNL_CONTEXT(ctx);
586 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
587 GLuint prim = VIA_CONTEXT(ctx)->renderPrimitive;
588
589 /* Render the new vertices as an unclipped polygon.
590 */
591 {
592 GLuint *tmp = VB->Elts;
593 VB->Elts = (GLuint *)elts;
594 tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n,
595 PRIM_BEGIN|PRIM_END);
596 VB->Elts = tmp;
597 }
598
599 /* Restore the render primitive
600 */
601 if (prim != GL_POLYGON &&
602 prim != GL_POLYGON + 1)
603 tnl->Driver.Render.PrimitiveNotify( ctx, prim );
604 }
605
606 static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
607 {
608 TNLcontext *tnl = TNL_CONTEXT(ctx);
609 tnl->Driver.Render.Line(ctx, ii, jj);
610 }
611
612 static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
613 GLuint n)
614 {
615 struct via_context *vmesa = VIA_CONTEXT(ctx);
616 GLuint vertsize = vmesa->vertexSize;
617 GLuint *vb = viaExtendPrimitive(vmesa, (n - 2) * 3 * 4 * vertsize);
618 GLubyte *vertptr = (GLubyte *)vmesa->verts;
619 const GLuint *start = (const GLuint *)V(elts[0]);
620 int i;
621
622 for (i = 2; i < n; i++) {
623 COPY_DWORDS(vb, vertsize, V(elts[i - 1]));
624 COPY_DWORDS(vb, vertsize, V(elts[i]));
625 COPY_DWORDS(vb, vertsize, start);
626 }
627 }
628
629
630 /**********************************************************************/
631 /* Choose render functions */
632 /**********************************************************************/
633
634
635 #define _VIA_NEW_VERTEX (_NEW_TEXTURE | \
636 _DD_NEW_SEPARATE_SPECULAR | \
637 _DD_NEW_TRI_UNFILLED | \
638 _DD_NEW_TRI_LIGHT_TWOSIDE | \
639 _NEW_FOG)
640
641 #define _VIA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
642 _DD_NEW_TRI_UNFILLED | \
643 _DD_NEW_TRI_LIGHT_TWOSIDE | \
644 _DD_NEW_TRI_OFFSET | \
645 _DD_NEW_TRI_STIPPLE | \
646 _NEW_POLYGONSTIPPLE)
647
648
649 static void viaChooseRenderState(GLcontext *ctx)
650 {
651 TNLcontext *tnl = TNL_CONTEXT(ctx);
652 struct via_context *vmesa = VIA_CONTEXT(ctx);
653 GLuint flags = ctx->_TriangleCaps;
654 GLuint index = 0;
655
656 if (vmesa->ptexHack) {
657 vmesa->drawPoint = via_ptex_point;
658 vmesa->drawLine = via_ptex_line;
659 vmesa->drawTri = via_ptex_tri;
660 index |= VIA_FALLBACK_BIT;
661 }
662 else {
663 vmesa->drawPoint = via_draw_point;
664 vmesa->drawLine = via_draw_line;
665 vmesa->drawTri = via_draw_triangle;
666 }
667
668 if (flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) {
669 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
670 index |= VIA_TWOSIDE_BIT;
671 if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL)
672 index |= VIA_UNFILLED_BIT;
673 if (flags & DD_TRI_OFFSET)
674 index |= VIA_OFFSET_BIT;
675 if (flags & ANY_FALLBACK_FLAGS)
676 index |= VIA_FALLBACK_BIT;
677
678 /* Hook in fallbacks for specific primitives. */
679 if (flags & POINT_FALLBACK)
680 vmesa->drawPoint = via_fallback_point;
681
682 if (flags & LINE_FALLBACK)
683 vmesa->drawLine = via_fallback_line;
684
685 if (flags & TRI_FALLBACK)
686 vmesa->drawTri = via_fallback_tri;
687 }
688
689 if ((flags & DD_SEPARATE_SPECULAR) && ctx->Light.ShadeModel == GL_FLAT)
690 index = VIA_MAX_TRIFUNC; /* flat specular */
691
692 if (vmesa->renderIndex != index) {
693 vmesa->renderIndex = index;
694
695 tnl->Driver.Render.Points = rast_tab[index].points;
696 tnl->Driver.Render.Line = rast_tab[index].line;
697 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
698 tnl->Driver.Render.Quad = rast_tab[index].quad;
699
700 if (index == 0) {
701 tnl->Driver.Render.PrimTabVerts = via_render_tab_verts;
702 tnl->Driver.Render.PrimTabElts = via_render_tab_elts;
703 tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
704 tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly;
705 }
706 else {
707 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
708 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
709 tnl->Driver.Render.ClippedLine = viaRenderClippedLine;
710 tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly;
711 }
712 }
713 }
714
715
716 #define VIA_EMIT_TEX1 0x01
717 #define VIA_EMIT_TEX0 0x02
718 #define VIA_EMIT_PTEX0 0x04
719 #define VIA_EMIT_RGBA 0x08
720 #define VIA_EMIT_SPEC 0x10
721 #define VIA_EMIT_FOG 0x20
722 #define VIA_EMIT_W 0x40
723
724 #define EMIT_ATTR( ATTR, STYLE, INDEX, REGB ) \
725 do { \
726 vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = (ATTR); \
727 vmesa->vertex_attrs[vmesa->vertex_attr_count].format = (STYLE); \
728 vmesa->vertex_attr_count++; \
729 setupIndex |= (INDEX); \
730 regCmdB |= (REGB); \
731 } while (0)
732
733 #define EMIT_PAD( N ) \
734 do { \
735 vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = 0; \
736 vmesa->vertex_attrs[vmesa->vertex_attr_count].format = EMIT_PAD; \
737 vmesa->vertex_attrs[vmesa->vertex_attr_count].offset = (N); \
738 vmesa->vertex_attr_count++; \
739 } while (0)
740
741
742
743 static void viaChooseVertexState( GLcontext *ctx )
744 {
745 struct via_context *vmesa = VIA_CONTEXT(ctx);
746 TNLcontext *tnl = TNL_CONTEXT(ctx);
747 DECLARE_RENDERINPUTS(index_bitset);
748 GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z;
749 GLuint setupIndex = 0;
750
751 RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
752 vmesa->vertex_attr_count = 0;
753
754 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
755 * build up a hardware vertex.
756 */
757 if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) ||
758 RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
759 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W );
760 vmesa->coloroffset = 4;
761 }
762 else {
763 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 );
764 vmesa->coloroffset = 3;
765 }
766
767 /* t_context.c always includes a diffuse color */
768 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA,
769 HC_HVPMSK_Cd );
770
771 vmesa->specoffset = 0;
772 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
773 RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
774 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
775 vmesa->specoffset = vmesa->coloroffset + 1;
776 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC,
777 HC_HVPMSK_Cs );
778 }
779 else
780 EMIT_PAD( 3 );
781
782 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
783 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs );
784 else
785 EMIT_PAD( 1 );
786 }
787
788 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
789 if (vmesa->ptexHack)
790 EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0,
791 (HC_HVPMSK_S | HC_HVPMSK_T) );
792 else
793 EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0,
794 (HC_HVPMSK_S | HC_HVPMSK_T) );
795 }
796
797 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
798 EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1,
799 (HC_HVPMSK_S | HC_HVPMSK_T) );
800 }
801
802 if (setupIndex != vmesa->setupIndex) {
803 vmesa->vertexSize = _tnl_install_attrs( ctx,
804 vmesa->vertex_attrs,
805 vmesa->vertex_attr_count,
806 vmesa->ViewportMatrix.m, 0 );
807 vmesa->vertexSize >>= 2;
808 vmesa->setupIndex = setupIndex;
809 vmesa->regCmdB &= ~HC_HVPMSK_MASK;
810 vmesa->regCmdB |= regCmdB;
811
812 if (vmesa->ptexHack)
813 vmesa->hwVertexSize = vmesa->vertexSize - 1;
814 else
815 vmesa->hwVertexSize = vmesa->vertexSize;
816 }
817 }
818
819
820
821
822 /* Check if projective texture coordinates are used and if we can fake
823 * them. Fallback to swrast if we can't. Returns GL_TRUE if projective
824 * texture coordinates must be faked, GL_FALSE otherwise.
825 */
826 static GLboolean viaCheckPTexHack( GLcontext *ctx )
827 {
828 TNLcontext *tnl = TNL_CONTEXT(ctx);
829 struct vertex_buffer *VB = &tnl->vb;
830 DECLARE_RENDERINPUTS(index_bitset);
831 GLboolean fallback = GL_FALSE;
832 GLboolean ptexHack = GL_FALSE;
833
834 RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
835
836 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4) {
837 if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
838 ptexHack = GL_TRUE;
839 else
840 fallback = GL_TRUE;
841 }
842 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
843 fallback = GL_TRUE;
844
845 FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback);
846 return ptexHack;
847 }
848
849
850
851
852 /**********************************************************************/
853 /* High level hooks for t_vb_render.c */
854 /**********************************************************************/
855
856
857 static void viaRenderStart(GLcontext *ctx)
858 {
859 struct via_context *vmesa = VIA_CONTEXT(ctx);
860 TNLcontext *tnl = TNL_CONTEXT(ctx);
861 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
862
863 {
864 GLboolean ptexHack = viaCheckPTexHack( ctx );
865 if (ptexHack != vmesa->ptexHack) {
866 vmesa->ptexHack = ptexHack;
867 vmesa->newRenderState |= _VIA_NEW_RENDERSTATE;
868 }
869 }
870
871 if (vmesa->newState) {
872 vmesa->newRenderState |= vmesa->newState;
873 viaValidateState( ctx );
874 }
875
876 if (vmesa->Fallback) {
877 tnl->Driver.Render.Start(ctx);
878 return;
879 }
880
881 if (vmesa->newRenderState) {
882 viaChooseVertexState(ctx);
883 viaChooseRenderState(ctx);
884 vmesa->newRenderState = 0;
885 }
886
887 /* Important:
888 */
889 VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
890 }
891
892 static void viaRenderFinish(GLcontext *ctx)
893 {
894 VIA_FINISH_PRIM(VIA_CONTEXT(ctx));
895 }
896
897
898 /* System to flush dma and emit state changes based on the rasterized
899 * primitive.
900 */
901 void viaRasterPrimitive(GLcontext *ctx,
902 GLenum glprim,
903 GLenum hwprim)
904 {
905 struct via_context *vmesa = VIA_CONTEXT(ctx);
906 GLuint regCmdB;
907 RING_VARS;
908
909 if (VIA_DEBUG & DEBUG_PRIMS)
910 fprintf(stderr, "%s: %s/%s/%s\n",
911 __FUNCTION__, _mesa_lookup_enum_by_nr(glprim),
912 _mesa_lookup_enum_by_nr(hwprim),
913 _mesa_lookup_enum_by_nr(ctx->Light.ShadeModel));
914
915 assert (!vmesa->newState);
916
917 vmesa->renderPrimitive = glprim;
918
919 if (hwprim != vmesa->hwPrimitive ||
920 ctx->Light.ShadeModel != vmesa->hwShadeModel) {
921
922 VIA_FINISH_PRIM(vmesa);
923
924 /* Ensure no wrapping inside this function */
925 viaCheckDma( vmesa, 1024 );
926
927 if (vmesa->newEmitState) {
928 viaEmitState(vmesa);
929 }
930
931 vmesa->regCmdA_End = HC_ACMD_HCmdA;
932
933 if (ctx->Light.ShadeModel == GL_SMOOTH) {
934 vmesa->regCmdA_End |= HC_HShading_Gouraud;
935 }
936
937 vmesa->hwShadeModel = ctx->Light.ShadeModel;
938 regCmdB = vmesa->regCmdB;
939
940 switch (hwprim) {
941 case GL_POINTS:
942 vmesa->regCmdA_End |= HC_HPMType_Point | HC_HVCycle_Full;
943 vmesa->regCmdA_End |= HC_HShading_Gouraud; /* always Gouraud
944 shade points?!? */
945 break;
946 case GL_LINES:
947 vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_Full;
948 regCmdB |= HC_HLPrst_MASK;
949 if (ctx->Light.ShadeModel == GL_FLAT)
950 vmesa->regCmdA_End |= HC_HShading_FlatB;
951 break;
952 case GL_LINE_LOOP:
953 case GL_LINE_STRIP:
954 vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_AFP |
955 HC_HVCycle_AB | HC_HVCycle_NewB;
956 regCmdB |= HC_HVCycle_AB | HC_HVCycle_NewB | HC_HLPrst_MASK;
957 if (ctx->Light.ShadeModel == GL_FLAT)
958 vmesa->regCmdA_End |= HC_HShading_FlatB;
959 break;
960 case GL_TRIANGLES:
961 vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_Full;
962 if (ctx->Light.ShadeModel == GL_FLAT)
963 vmesa->regCmdA_End |= HC_HShading_FlatC;
964 break;
965 case GL_TRIANGLE_STRIP:
966 vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
967 HC_HVCycle_AC | HC_HVCycle_BB | HC_HVCycle_NewC;
968 regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
969 if (ctx->Light.ShadeModel == GL_FLAT)
970 vmesa->regCmdA_End |= HC_HShading_FlatC;
971 break;
972 case GL_TRIANGLE_FAN:
973 vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
974 HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
975 regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
976 if (ctx->Light.ShadeModel == GL_FLAT)
977 vmesa->regCmdA_End |= HC_HShading_FlatC;
978 break;
979 case GL_QUADS:
980 abort();
981 return;
982 case GL_QUAD_STRIP:
983 abort();
984 return;
985 case GL_POLYGON:
986 vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_AFP |
987 HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
988 regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC;
989 if (ctx->Light.ShadeModel == GL_FLAT)
990 vmesa->regCmdA_End |= HC_HShading_FlatC;
991 break;
992 default:
993 abort();
994 return;
995 }
996
997 /* assert((vmesa->dmaLow & 0x4) == 0); */
998
999 if (vmesa->dmaCliprectAddr == ~0) {
1000 if (VIA_DEBUG & DEBUG_DMA)
1001 fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow);
1002 vmesa->dmaCliprectAddr = vmesa->dmaLow;
1003 BEGIN_RING(8);
1004 OUT_RING( HC_HEADER2 );
1005 OUT_RING( (HC_ParaType_NotTex << 16) );
1006 OUT_RING( 0xCCCCCCCC );
1007 OUT_RING( 0xCCCCCCCC );
1008 OUT_RING( 0xCCCCCCCC );
1009 OUT_RING( 0xCCCCCCCC );
1010 OUT_RING( 0xCCCCCCCC );
1011 OUT_RING( 0xCCCCCCCC );
1012 ADVANCE_RING();
1013 }
1014
1015 assert(vmesa->dmaLastPrim == 0);
1016
1017 BEGIN_RING(8);
1018 OUT_RING( HC_HEADER2 );
1019 OUT_RING( (HC_ParaType_NotTex << 16) );
1020 OUT_RING( 0xCCCCCCCC );
1021 OUT_RING( 0xDDDDDDDD );
1022
1023 OUT_RING( HC_HEADER2 );
1024 OUT_RING( (HC_ParaType_CmdVdata << 16) );
1025 OUT_RING( regCmdB );
1026 OUT_RING( vmesa->regCmdA_End );
1027 ADVANCE_RING();
1028
1029 vmesa->hwPrimitive = hwprim;
1030 vmesa->dmaLastPrim = vmesa->dmaLow;
1031 }
1032 else {
1033 assert(!vmesa->newEmitState);
1034 }
1035 }
1036
1037 /* Callback for mesa:
1038 */
1039 static void viaRenderPrimitive( GLcontext *ctx, GLuint prim )
1040 {
1041 viaRasterPrimitive( ctx, prim, hwPrim[prim] );
1042 }
1043
1044
1045 void viaFinishPrimitive(struct via_context *vmesa)
1046 {
1047 if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS))
1048 fprintf(stderr, "%s\n", __FUNCTION__);
1049
1050 if (!vmesa->dmaLastPrim || vmesa->dmaCliprectAddr == ~0) {
1051 assert(0);
1052 }
1053 else if (vmesa->dmaLow != vmesa->dmaLastPrim) {
1054 GLuint cmdA = (vmesa->regCmdA_End | HC_HPLEND_MASK |
1055 HC_HPMValidN_MASK | HC_HE3Fire_MASK);
1056 RING_VARS;
1057
1058 vmesa->dmaLastPrim = 0;
1059
1060 /* KW: modified 0x1 to 0x4 below:
1061 */
1062 if ((vmesa->dmaLow & 0x4) || !vmesa->useAgp) {
1063 BEGIN_RING_NOCHECK( 1 );
1064 OUT_RING( cmdA );
1065 ADVANCE_RING();
1066 }
1067 else {
1068 BEGIN_RING_NOCHECK( 2 );
1069 OUT_RING( cmdA );
1070 OUT_RING( cmdA );
1071 ADVANCE_RING();
1072 }
1073
1074 if (vmesa->dmaLow > VIA_DMA_HIGHWATER)
1075 viaFlushDma( vmesa );
1076 }
1077 else {
1078 if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS))
1079 fprintf(stderr, "remove empty primitive\n");
1080
1081 /* Remove the primitive header:
1082 */
1083 vmesa->dmaLastPrim = 0;
1084 vmesa->dmaLow -= 8 * sizeof(GLuint);
1085
1086 /* Maybe remove the cliprect as well:
1087 */
1088 if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) {
1089 vmesa->dmaLow -= 8 * sizeof(GLuint);
1090 vmesa->dmaCliprectAddr = ~0;
1091 }
1092 }
1093
1094 vmesa->renderPrimitive = GL_POLYGON + 1;
1095 vmesa->hwPrimitive = GL_POLYGON + 1;
1096 vmesa->dmaLastPrim = 0;
1097 }
1098
1099
1100 /**********************************************************************/
1101 /* Transition to/from hardware rasterization. */
1102 /**********************************************************************/
1103
1104
1105 void viaFallback(struct via_context *vmesa, GLuint bit, GLboolean mode)
1106 {
1107 GLcontext *ctx = vmesa->glCtx;
1108 TNLcontext *tnl = TNL_CONTEXT(ctx);
1109 GLuint oldfallback = vmesa->Fallback;
1110
1111 if (mode) {
1112 vmesa->Fallback |= bit;
1113 if (oldfallback == 0) {
1114 VIA_FLUSH_DMA(vmesa);
1115
1116 if (VIA_DEBUG & DEBUG_FALLBACKS)
1117 fprintf(stderr, "ENTER FALLBACK %x\n", bit);
1118
1119 _swsetup_Wakeup(ctx);
1120 vmesa->renderIndex = ~0;
1121 }
1122 }
1123 else {
1124 vmesa->Fallback &= ~bit;
1125 if (oldfallback == bit) {
1126 _swrast_flush( ctx );
1127
1128 if (VIA_DEBUG & DEBUG_FALLBACKS)
1129 fprintf(stderr, "LEAVE FALLBACK %x\n", bit);
1130
1131 tnl->Driver.Render.Start = viaRenderStart;
1132 tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
1133 tnl->Driver.Render.Finish = viaRenderFinish;
1134
1135 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
1136 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
1137 tnl->Driver.Render.Interp = _tnl_interp;
1138 tnl->Driver.Render.ResetLineStipple = viaResetLineStipple;
1139
1140 _tnl_invalidate_vertex_state( ctx, ~0 );
1141 _tnl_invalidate_vertices( ctx, ~0 );
1142 _tnl_install_attrs( ctx,
1143 vmesa->vertex_attrs,
1144 vmesa->vertex_attr_count,
1145 vmesa->ViewportMatrix.m, 0 );
1146
1147 vmesa->newState |= (_VIA_NEW_RENDERSTATE|_VIA_NEW_VERTEX);
1148 }
1149 }
1150 }
1151
1152 static void viaRunPipeline( GLcontext *ctx )
1153 {
1154 struct via_context *vmesa = VIA_CONTEXT(ctx);
1155
1156 if (vmesa->newState) {
1157 vmesa->newRenderState |= vmesa->newState;
1158 viaValidateState( ctx );
1159 }
1160
1161 _tnl_run_pipeline( ctx );
1162 }
1163
1164
1165 /**********************************************************************/
1166 /* Initialization. */
1167 /**********************************************************************/
1168
1169
1170 void viaInitTriFuncs(GLcontext *ctx)
1171 {
1172 struct via_context *vmesa = VIA_CONTEXT(ctx);
1173 TNLcontext *tnl = TNL_CONTEXT(ctx);
1174 static int firsttime = 1;
1175
1176 if (firsttime) {
1177 init_rast_tab();
1178 firsttime = 0;
1179 }
1180
1181 tnl->Driver.RunPipeline = viaRunPipeline;
1182 tnl->Driver.Render.Start = viaRenderStart;
1183 tnl->Driver.Render.Finish = viaRenderFinish;
1184 tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive;
1185 tnl->Driver.Render.ResetLineStipple = viaResetLineStipple;
1186 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
1187 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
1188 tnl->Driver.Render.Interp = _tnl_interp;
1189
1190 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
1191 (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
1192
1193 vmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
1194
1195 }