Rename the various function types in t_context.h to include a tnl_ prefix.
[mesa.git] / src / mesa / drivers / dri / r128 / r128_tris.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ /* -*- 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 "glheader.h"
37 #include "mtypes.h"
38 #include "colormac.h"
39 #include "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_vb.h"
51 #include "r128_ioctl.h"
52
53 static const GLuint hw_prim[GL_POLYGON+1] = {
54 R128_CCE_VC_CNTL_PRIM_TYPE_POINT,
55 R128_CCE_VC_CNTL_PRIM_TYPE_LINE,
56 R128_CCE_VC_CNTL_PRIM_TYPE_LINE,
57 R128_CCE_VC_CNTL_PRIM_TYPE_LINE,
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 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST,
64 };
65
66 static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim );
67 static void r128RenderPrimitive( GLcontext *ctx, GLenum prim );
68
69
70 /***********************************************************************
71 * Emit primitives as inline vertices *
72 ***********************************************************************/
73
74 #if defined(USE_X86_ASM)
75 #define COPY_DWORDS( j, vb, vertsize, v ) \
76 do { \
77 int __tmp; \
78 __asm__ __volatile__( "rep ; movsl" \
79 : "=%c" (j), "=D" (vb), "=S" (__tmp) \
80 : "0" (vertsize), \
81 "D" ((long)vb), \
82 "S" ((long)v) ); \
83 } while (0)
84 #else
85 #define COPY_DWORDS( j, vb, vertsize, v ) \
86 do { \
87 for ( j = 0 ; j < vertsize ; j++ ) \
88 vb[j] = CPU_TO_LE32(((GLuint *)v)[j]); \
89 vb += vertsize; \
90 } while (0)
91 #endif
92
93 static __inline void r128_draw_quad( r128ContextPtr rmesa,
94 r128VertexPtr v0,
95 r128VertexPtr v1,
96 r128VertexPtr v2,
97 r128VertexPtr v3 )
98 {
99 GLuint vertsize = rmesa->vertex_size;
100 GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, 6 * vertsize * 4 );
101 GLuint j;
102
103 rmesa->num_verts += 6;
104 COPY_DWORDS( j, vb, vertsize, v0 );
105 COPY_DWORDS( j, vb, vertsize, v1 );
106 COPY_DWORDS( j, vb, vertsize, v3 );
107 COPY_DWORDS( j, vb, vertsize, v1 );
108 COPY_DWORDS( j, vb, vertsize, v2 );
109 COPY_DWORDS( j, vb, vertsize, v3 );
110 }
111
112
113 static __inline void r128_draw_triangle( r128ContextPtr rmesa,
114 r128VertexPtr v0,
115 r128VertexPtr v1,
116 r128VertexPtr v2 )
117 {
118 GLuint vertsize = rmesa->vertex_size;
119 GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, 3 * vertsize * 4 );
120 GLuint j;
121
122 rmesa->num_verts += 3;
123 COPY_DWORDS( j, vb, vertsize, v0 );
124 COPY_DWORDS( j, vb, vertsize, v1 );
125 COPY_DWORDS( j, vb, vertsize, v2 );
126 }
127
128 static __inline void r128_draw_line( r128ContextPtr rmesa,
129 r128VertexPtr v0,
130 r128VertexPtr v1 )
131 {
132 GLuint vertsize = rmesa->vertex_size;
133 GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, 2 * vertsize * 4 );
134 GLuint j;
135
136 rmesa->num_verts += 2;
137 COPY_DWORDS( j, vb, vertsize, v0 );
138 COPY_DWORDS( j, vb, vertsize, v1 );
139 }
140
141 static __inline void r128_draw_point( r128ContextPtr rmesa,
142 r128VertexPtr v0 )
143 {
144 int vertsize = rmesa->vertex_size;
145 GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, vertsize * 4 );
146 int j;
147
148 rmesa->num_verts += 1;
149 COPY_DWORDS( j, vb, vertsize, v0 );
150 }
151
152 /***********************************************************************
153 * Macros for t_dd_tritmp.h to draw basic primitives *
154 ***********************************************************************/
155
156 #define TRI( a, b, c ) \
157 do { \
158 if (DO_FALLBACK) \
159 rmesa->draw_tri( rmesa, a, b, c ); \
160 else \
161 r128_draw_triangle( rmesa, a, b, c ); \
162 } while (0)
163
164 #define QUAD( a, b, c, d ) \
165 do { \
166 if (DO_FALLBACK) { \
167 rmesa->draw_tri( rmesa, a, b, d ); \
168 rmesa->draw_tri( rmesa, b, c, d ); \
169 } else \
170 r128_draw_quad( rmesa, a, b, c, d ); \
171 } while (0)
172
173 #define LINE( v0, v1 ) \
174 do { \
175 if (DO_FALLBACK) \
176 rmesa->draw_line( rmesa, v0, v1 ); \
177 else \
178 r128_draw_line( rmesa, v0, v1 ); \
179 } while (0)
180
181 #define POINT( v0 ) \
182 do { \
183 if (DO_FALLBACK) \
184 rmesa->draw_point( rmesa, v0 ); \
185 else \
186 r128_draw_point( rmesa, v0 ); \
187 } while (0)
188
189
190 /***********************************************************************
191 * Build render functions from dd templates *
192 ***********************************************************************/
193
194 #define R128_OFFSET_BIT 0x01
195 #define R128_TWOSIDE_BIT 0x02
196 #define R128_UNFILLED_BIT 0x04
197 #define R128_FALLBACK_BIT 0x08
198 #define R128_MAX_TRIFUNC 0x10
199
200
201 static struct {
202 tnl_points_func points;
203 tnl_line_func line;
204 tnl_triangle_func triangle;
205 tnl_quad_func quad;
206 } rast_tab[R128_MAX_TRIFUNC];
207
208
209 #define DO_FALLBACK (IND & R128_FALLBACK_BIT)
210 #define DO_OFFSET (IND & R128_OFFSET_BIT)
211 #define DO_UNFILLED (IND & R128_UNFILLED_BIT)
212 #define DO_TWOSIDE (IND & R128_TWOSIDE_BIT)
213 #define DO_FLAT 0
214 #define DO_TRI 1
215 #define DO_QUAD 1
216 #define DO_LINE 1
217 #define DO_POINTS 1
218 #define DO_FULL_QUAD 1
219
220 #define HAVE_RGBA 1
221 #define HAVE_SPEC 1
222 #define HAVE_BACK_COLORS 0
223 #define HAVE_HW_FLATSHADE 1
224 #define VERTEX r128Vertex
225 #define TAB rast_tab
226
227 #define DEPTH_SCALE 1.0
228 #define UNFILLED_TRI unfilled_tri
229 #define UNFILLED_QUAD unfilled_quad
230 #define VERT_X(_v) _v->v.x
231 #define VERT_Y(_v) _v->v.y
232 #define VERT_Z(_v) _v->v.z
233 #define AREA_IS_CCW( a ) (a > 0)
234 #define GET_VERTEX(e) (rmesa->verts + (e * rmesa->vertex_size * sizeof(int)))
235
236 #define VERT_SET_RGBA( v, c ) \
237 do { \
238 r128_color_t *color = (r128_color_t *)&((v)->ui[coloroffset]); \
239 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
240 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
241 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
242 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
243 } while (0)
244
245 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
246
247 #define VERT_SET_SPEC( v0, c ) \
248 do { \
249 if (havespec) { \
250 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
251 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
252 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
253 } \
254 } while (0)
255 #define VERT_COPY_SPEC( v0, v1 ) \
256 do { \
257 if (havespec) { \
258 v0->v.specular.red = v1->v.specular.red; \
259 v0->v.specular.green = v1->v.specular.green; \
260 v0->v.specular.blue = v1->v.specular.blue; \
261 } \
262 } while (0)
263
264 /* These don't need LE32_TO_CPU() as they used to save and restore
265 * colors which are already in the correct format.
266 */
267 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
268 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
269 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
270 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
271
272
273 #define LOCAL_VARS(n) \
274 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
275 GLuint color[n], spec[n]; \
276 GLuint coloroffset = (rmesa->vertex_size == 4 ? 3 : 4); \
277 GLboolean havespec = (rmesa->vertex_size == 4 ? 0 : 1); \
278 (void) color; (void) spec; (void) coloroffset; (void) havespec;
279
280 /***********************************************************************
281 * Helpers for rendering unfilled primitives *
282 ***********************************************************************/
283
284 #define RASTERIZE(x) if (rmesa->hw_primitive != hw_prim[x]) \
285 r128RasterPrimitive( ctx, hw_prim[x] )
286 #define RENDER_PRIMITIVE rmesa->render_primitive
287 #define IND R128_FALLBACK_BIT
288 #define TAG(x) x
289 #include "tnl_dd/t_dd_unfilled.h"
290 #undef IND
291
292
293 /***********************************************************************
294 * Generate GL render functions *
295 ***********************************************************************/
296
297
298 #define IND (0)
299 #define TAG(x) x
300 #include "tnl_dd/t_dd_tritmp.h"
301
302 #define IND (R128_OFFSET_BIT)
303 #define TAG(x) x##_offset
304 #include "tnl_dd/t_dd_tritmp.h"
305
306 #define IND (R128_TWOSIDE_BIT)
307 #define TAG(x) x##_twoside
308 #include "tnl_dd/t_dd_tritmp.h"
309
310 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT)
311 #define TAG(x) x##_twoside_offset
312 #include "tnl_dd/t_dd_tritmp.h"
313
314 #define IND (R128_UNFILLED_BIT)
315 #define TAG(x) x##_unfilled
316 #include "tnl_dd/t_dd_tritmp.h"
317
318 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT)
319 #define TAG(x) x##_offset_unfilled
320 #include "tnl_dd/t_dd_tritmp.h"
321
322 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT)
323 #define TAG(x) x##_twoside_unfilled
324 #include "tnl_dd/t_dd_tritmp.h"
325
326 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT)
327 #define TAG(x) x##_twoside_offset_unfilled
328 #include "tnl_dd/t_dd_tritmp.h"
329
330 #define IND (R128_FALLBACK_BIT)
331 #define TAG(x) x##_fallback
332 #include "tnl_dd/t_dd_tritmp.h"
333
334 #define IND (R128_OFFSET_BIT|R128_FALLBACK_BIT)
335 #define TAG(x) x##_offset_fallback
336 #include "tnl_dd/t_dd_tritmp.h"
337
338 #define IND (R128_TWOSIDE_BIT|R128_FALLBACK_BIT)
339 #define TAG(x) x##_twoside_fallback
340 #include "tnl_dd/t_dd_tritmp.h"
341
342 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_FALLBACK_BIT)
343 #define TAG(x) x##_twoside_offset_fallback
344 #include "tnl_dd/t_dd_tritmp.h"
345
346 #define IND (R128_UNFILLED_BIT|R128_FALLBACK_BIT)
347 #define TAG(x) x##_unfilled_fallback
348 #include "tnl_dd/t_dd_tritmp.h"
349
350 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
351 #define TAG(x) x##_offset_unfilled_fallback
352 #include "tnl_dd/t_dd_tritmp.h"
353
354 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
355 #define TAG(x) x##_twoside_unfilled_fallback
356 #include "tnl_dd/t_dd_tritmp.h"
357
358 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT| \
359 R128_FALLBACK_BIT)
360 #define TAG(x) x##_twoside_offset_unfilled_fallback
361 #include "tnl_dd/t_dd_tritmp.h"
362
363
364 static void init_rast_tab( void )
365 {
366 init();
367 init_offset();
368 init_twoside();
369 init_twoside_offset();
370 init_unfilled();
371 init_offset_unfilled();
372 init_twoside_unfilled();
373 init_twoside_offset_unfilled();
374 init_fallback();
375 init_offset_fallback();
376 init_twoside_fallback();
377 init_twoside_offset_fallback();
378 init_unfilled_fallback();
379 init_offset_unfilled_fallback();
380 init_twoside_unfilled_fallback();
381 init_twoside_offset_unfilled_fallback();
382 }
383
384
385
386 /***********************************************************************
387 * Rasterization fallback helpers *
388 ***********************************************************************/
389
390
391 /* This code is hit only when a mix of accelerated and unaccelerated
392 * primitives are being drawn, and only for the unaccelerated
393 * primitives.
394 */
395 static void
396 r128_fallback_tri( r128ContextPtr rmesa,
397 r128Vertex *v0,
398 r128Vertex *v1,
399 r128Vertex *v2 )
400 {
401 GLcontext *ctx = rmesa->glCtx;
402 SWvertex v[3];
403 r128_translate_vertex( ctx, v0, &v[0] );
404 r128_translate_vertex( ctx, v1, &v[1] );
405 r128_translate_vertex( ctx, v2, &v[2] );
406 _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
407 }
408
409
410 static void
411 r128_fallback_line( r128ContextPtr rmesa,
412 r128Vertex *v0,
413 r128Vertex *v1 )
414 {
415 GLcontext *ctx = rmesa->glCtx;
416 SWvertex v[2];
417 r128_translate_vertex( ctx, v0, &v[0] );
418 r128_translate_vertex( ctx, v1, &v[1] );
419 _swrast_Line( ctx, &v[0], &v[1] );
420 }
421
422
423 static void
424 r128_fallback_point( r128ContextPtr rmesa,
425 r128Vertex *v0 )
426 {
427 GLcontext *ctx = rmesa->glCtx;
428 SWvertex v[1];
429 r128_translate_vertex( ctx, v0, &v[0] );
430 _swrast_Point( ctx, &v[0] );
431 }
432
433
434
435 /**********************************************************************/
436 /* Render unclipped begin/end objects */
437 /**********************************************************************/
438
439 #define VERT(x) (r128Vertex *)(r128verts + (x * vertsize * sizeof(int)))
440 #define RENDER_POINTS( start, count ) \
441 for ( ; start < count ; start++) \
442 r128_draw_point( rmesa, VERT(start) )
443 #define RENDER_LINE( v0, v1 ) \
444 r128_draw_line( rmesa, VERT(v0), VERT(v1) )
445 #define RENDER_TRI( v0, v1, v2 ) \
446 r128_draw_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
447 #define RENDER_QUAD( v0, v1, v2, v3 ) \
448 r128_draw_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
449 #define INIT(x) do { \
450 if (0) fprintf(stderr, "%s\n", __FUNCTION__); \
451 r128RenderPrimitive( ctx, x ); \
452 } while (0)
453 #undef LOCAL_VARS
454 #define LOCAL_VARS \
455 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
456 const GLuint vertsize = rmesa->vertex_size; \
457 const char *r128verts = (char *)rmesa->verts; \
458 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
459 (void) elt;
460 #define RESET_STIPPLE
461 #define RESET_OCCLUSION
462 #define PRESERVE_VB_DEFS
463 #define ELT(x) (x)
464 #define TAG(x) r128_##x##_verts
465 #include "tnl/t_vb_rendertmp.h"
466 #undef ELT
467 #undef TAG
468 #define TAG(x) r128_##x##_elts
469 #define ELT(x) elt[x]
470 #include "tnl/t_vb_rendertmp.h"
471
472
473 /**********************************************************************/
474 /* Render clipped primitives */
475 /**********************************************************************/
476
477 static void r128RenderClippedPoly( GLcontext *ctx, const GLuint *elts,
478 GLuint n )
479 {
480 TNLcontext *tnl = TNL_CONTEXT(ctx);
481 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
482
483 /* Render the new vertices as an unclipped polygon.
484 */
485 {
486 GLuint *tmp = VB->Elts;
487 VB->Elts = (GLuint *)elts;
488 tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
489 VB->Elts = tmp;
490 }
491 }
492
493 static void r128RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
494 {
495 TNLcontext *tnl = TNL_CONTEXT(ctx);
496 tnl->Driver.Render.Line( ctx, ii, jj );
497 }
498
499 static void r128FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
500 GLuint n )
501 {
502 r128ContextPtr rmesa = R128_CONTEXT( ctx );
503 GLuint vertsize = rmesa->vertex_size;
504 GLuint *vb = r128AllocDmaLow( rmesa, (n-2) * 3 * 4 * vertsize );
505 GLubyte *r128verts = (GLubyte *)rmesa->verts;
506 const GLuint *start = (const GLuint *)VERT(elts[0]);
507 int i,j;
508
509 rmesa->num_verts += (n-2) * 3;
510
511 for (i = 2 ; i < n ; i++) {
512 COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i-1]) );
513 COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i]) );
514 COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) start );
515 }
516 }
517
518
519
520
521 /**********************************************************************/
522 /* Choose render functions */
523 /**********************************************************************/
524
525 #define _R128_NEW_RENDER_STATE (_DD_NEW_LINE_STIPPLE | \
526 _DD_NEW_LINE_SMOOTH | \
527 _DD_NEW_POINT_SMOOTH | \
528 _DD_NEW_TRI_SMOOTH | \
529 _DD_NEW_TRI_UNFILLED | \
530 _DD_NEW_TRI_LIGHT_TWOSIDE | \
531 _DD_NEW_TRI_OFFSET) \
532
533
534 #define POINT_FALLBACK (DD_POINT_SMOOTH)
535 #define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
536 #define TRI_FALLBACK (DD_TRI_SMOOTH)
537 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
538 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
539
540
541 static void r128ChooseRenderState(GLcontext *ctx)
542 {
543 r128ContextPtr rmesa = R128_CONTEXT(ctx);
544 GLuint flags = ctx->_TriangleCaps;
545 GLuint index = 0;
546
547 if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) {
548 rmesa->draw_point = r128_draw_point;
549 rmesa->draw_line = r128_draw_line;
550 rmesa->draw_tri = r128_draw_triangle;
551
552 if (flags & ANY_RASTER_FLAGS) {
553 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT;
554 if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT;
555 if (flags & DD_TRI_UNFILLED) index |= R128_UNFILLED_BIT;
556 }
557
558 /* Hook in fallbacks for specific primitives.
559 */
560 if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) {
561 if (flags & POINT_FALLBACK) rmesa->draw_point = r128_fallback_point;
562 if (flags & LINE_FALLBACK) rmesa->draw_line = r128_fallback_line;
563 if (flags & TRI_FALLBACK) rmesa->draw_tri = r128_fallback_tri;
564 index |= R128_FALLBACK_BIT;
565 }
566 }
567
568 if (index != rmesa->RenderIndex) {
569 TNLcontext *tnl = TNL_CONTEXT(ctx);
570 tnl->Driver.Render.Points = rast_tab[index].points;
571 tnl->Driver.Render.Line = rast_tab[index].line;
572 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
573 tnl->Driver.Render.Quad = rast_tab[index].quad;
574
575 if (index == 0) {
576 tnl->Driver.Render.PrimTabVerts = r128_render_tab_verts;
577 tnl->Driver.Render.PrimTabElts = r128_render_tab_elts;
578 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
579 tnl->Driver.Render.ClippedPolygon = r128FastRenderClippedPoly;
580 } else {
581 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
582 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
583 tnl->Driver.Render.ClippedLine = r128RenderClippedLine;
584 tnl->Driver.Render.ClippedPolygon = r128RenderClippedPoly;
585 }
586
587 rmesa->RenderIndex = index;
588 }
589 }
590
591 /**********************************************************************/
592 /* Validate state at pipeline start */
593 /**********************************************************************/
594
595 static void r128RunPipeline( GLcontext *ctx )
596 {
597 r128ContextPtr rmesa = R128_CONTEXT(ctx);
598
599 if (rmesa->new_state || rmesa->NewGLState & _NEW_TEXTURE)
600 r128DDUpdateHWState( ctx );
601
602 if (!rmesa->Fallback && rmesa->NewGLState) {
603 if (rmesa->NewGLState & _R128_NEW_VERTEX_STATE)
604 r128ChooseVertexState( ctx );
605
606 if (rmesa->NewGLState & _R128_NEW_RENDER_STATE)
607 r128ChooseRenderState( ctx );
608
609 rmesa->NewGLState = 0;
610 }
611
612 _tnl_run_pipeline( ctx );
613 }
614
615 /**********************************************************************/
616 /* High level hooks for t_vb_render.c */
617 /**********************************************************************/
618
619 /* This is called when Mesa switches between rendering triangle
620 * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
621 * and lines, points and bitmaps.
622 *
623 * As the r128 uses triangles to render lines and points, it is
624 * necessary to turn off hardware culling when rendering these
625 * primitives.
626 */
627
628 static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim )
629 {
630 r128ContextPtr rmesa = R128_CONTEXT(ctx);
631
632 rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
633
634 if ( ctx->Polygon.StippleFlag && hwprim == GL_TRIANGLES ) {
635 rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA;
636 }
637 else {
638 rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR;
639 }
640
641 rmesa->new_state |= R128_NEW_CONTEXT;
642 rmesa->dirty |= R128_UPLOAD_CONTEXT;
643
644 if (rmesa->hw_primitive != hwprim) {
645 FLUSH_BATCH( rmesa );
646 rmesa->hw_primitive = hwprim;
647 }
648 }
649
650 static void r128RenderPrimitive( GLcontext *ctx, GLenum prim )
651 {
652 r128ContextPtr rmesa = R128_CONTEXT(ctx);
653 GLuint hw = hw_prim[prim];
654 rmesa->render_primitive = prim;
655 if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
656 return;
657 r128RasterPrimitive( ctx, hw );
658 }
659
660
661 static void r128RenderStart( GLcontext *ctx )
662 {
663 /* Check for projective texturing. Make sure all texcoord
664 * pointers point to something. (fix in mesa?)
665 */
666 r128CheckTexSizes( ctx );
667 }
668
669 static void r128RenderFinish( GLcontext *ctx )
670 {
671 if (R128_CONTEXT(ctx)->RenderIndex & R128_FALLBACK_BIT)
672 _swrast_flush( ctx );
673 }
674
675
676 /**********************************************************************/
677 /* Transition to/from hardware rasterization. */
678 /**********************************************************************/
679
680 void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
681 {
682 TNLcontext *tnl = TNL_CONTEXT(ctx);
683 r128ContextPtr rmesa = R128_CONTEXT(ctx);
684 GLuint oldfallback = rmesa->Fallback;
685
686 if (mode) {
687 rmesa->Fallback |= bit;
688 if (oldfallback == 0) {
689 FLUSH_BATCH( rmesa );
690 _swsetup_Wakeup( ctx );
691 rmesa->RenderIndex = ~0;
692 }
693 }
694 else {
695 rmesa->Fallback &= ~bit;
696 if (oldfallback == bit) {
697 _swrast_flush( ctx );
698 tnl->Driver.Render.Start = r128RenderStart;
699 tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
700 tnl->Driver.Render.Finish = r128RenderFinish;
701 tnl->Driver.Render.BuildVertices = r128BuildVertices;
702 rmesa->NewGLState |= (_R128_NEW_RENDER_STATE|
703 _R128_NEW_VERTEX_STATE);
704 }
705 }
706 }
707
708
709 /**********************************************************************/
710 /* Initialization. */
711 /**********************************************************************/
712
713 void r128InitTriFuncs( GLcontext *ctx )
714 {
715 r128ContextPtr rmesa = R128_CONTEXT(ctx);
716 TNLcontext *tnl = TNL_CONTEXT(ctx);
717 static int firsttime = 1;
718
719 if (firsttime) {
720 init_rast_tab();
721 firsttime = 0;
722 }
723
724 tnl->Driver.RunPipeline = r128RunPipeline;
725 tnl->Driver.Render.Start = r128RenderStart;
726 tnl->Driver.Render.Finish = r128RenderFinish;
727 tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
728 tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
729 tnl->Driver.Render.BuildVertices = r128BuildVertices;
730 rmesa->NewGLState |= (_R128_NEW_RENDER_STATE|
731 _R128_NEW_VERTEX_STATE);
732
733 /* r128Fallback( ctx, 0x100000, 1 ); */
734 }