Merge commit 'origin/gallium-0.1'
[mesa.git] / src / mesa / drivers / dri / s3v / s3v_tris.c
1 /*
2 * Author: Max Lingua <sunmax@libero.it>
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 #include <sys/ioctl.h>
9
10 #include "s3v_context.h"
11 #include "s3v_vb.h"
12 #include "s3v_tris.h"
13
14 #include "main/glheader.h"
15 #include "main/mtypes.h"
16 #include "main/macros.h"
17 #include "main/colormac.h"
18
19 #include "swrast/swrast.h"
20 #include "swrast_setup/swrast_setup.h"
21 #include "tnl/tnl.h"
22 #include "tnl/t_context.h"
23 #include "tnl/t_pipeline.h"
24
25
26 /***********************************************************************
27 * Build hardware rasterization functions *
28 ***********************************************************************/
29
30 #define DO_TRI 1
31 #define HAVE_RGBA 1
32 #define HAVE_SPEC 0
33 #define HAVE_BACK_COLORS 0
34 #define HAVE_HW_FLATSHADE 1
35 #define VERTEX s3vVertex
36 #define TAB rast_tab
37
38 #define VERT_SET_RGBA( v, c ) \
39 do { \
40 UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c); \
41 /* *(v->ub4[4]) = c; \ */ \
42 } while (0)
43 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
44 /*
45 #define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
46 */
47 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
48 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
49
50 #define S3V_OFFSET_BIT 0x01
51 #define S3V_TWOSIDE_BIT 0x02
52 #define S3V_UNFILLED_BIT 0x04
53 #define S3V_FALLBACK_BIT 0x08
54 #define S3V_MAX_TRIFUNC 0x10
55
56
57 static struct {
58 tnl_points_func points;
59 tnl_line_func line;
60 tnl_triangle_func triangle;
61 tnl_quad_func quad;
62 } rast_tab[S3V_MAX_TRIFUNC];
63
64 #define S3V_RAST_CULL_BIT 0x01
65 #define S3V_RAST_FLAT_BIT 0x02
66 #define S3V_RAST_TEX_BIT 0x04
67
68 static s3v_point_func s3v_point_tab[0x8];
69 static s3v_line_func s3v_line_tab[0x8];
70 static s3v_tri_func s3v_tri_tab[0x8];
71 static s3v_quad_func s3v_quad_tab[0x8];
72
73 #define IND (0)
74 #define TAG(x) x
75 #include "s3v_tritmp.h"
76
77 #define IND (S3V_RAST_CULL_BIT)
78 #define TAG(x) x##_cull
79 #include "s3v_tritmp.h"
80
81 #define IND (S3V_RAST_FLAT_BIT)
82 #define TAG(x) x##_flat
83 #include "s3v_tritmp.h"
84
85 #define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT)
86 #define TAG(x) x##_cull_flat
87 #include "s3v_tritmp.h"
88
89 #define IND (S3V_RAST_TEX_BIT)
90 #define TAG(x) x##_tex
91 #include "s3v_tritmp.h"
92
93 #define IND (S3V_RAST_CULL_BIT|S3V_RAST_TEX_BIT)
94 #define TAG(x) x##_cull_tex
95 #include "s3v_tritmp.h"
96
97 #define IND (S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
98 #define TAG(x) x##_flat_tex
99 #include "s3v_tritmp.h"
100
101 #define IND (S3V_RAST_CULL_BIT|S3V_RAST_FLAT_BIT|S3V_RAST_TEX_BIT)
102 #define TAG(x) x##_cull_flat_tex
103 #include "s3v_tritmp.h"
104
105 static void init_rast_tab( void )
106 {
107 DEBUG(("*** init_rast_tab ***\n"));
108
109 s3v_init();
110 s3v_init_cull();
111 s3v_init_flat();
112 s3v_init_cull_flat();
113 s3v_init_tex();
114 s3v_init_cull_tex();
115 s3v_init_flat_tex();
116 s3v_init_cull_flat_tex();
117 }
118
119 /***********************************************************************
120 * Rasterization fallback helpers *
121 ***********************************************************************/
122
123
124 /* This code is hit only when a mix of accelerated and unaccelerated
125 * primitives are being drawn, and only for the unaccelerated
126 * primitives.
127 */
128
129 #if 0
130 static void
131 s3v_fallback_quad( s3vContextPtr vmesa,
132 const s3vVertex *v0,
133 const s3vVertex *v1,
134 const s3vVertex *v2,
135 const s3vVertex *v3 )
136 {
137 GLcontext *ctx = vmesa->glCtx;
138 SWvertex v[4];
139 s3v_translate_vertex( ctx, v0, &v[0] );
140 s3v_translate_vertex( ctx, v1, &v[1] );
141 s3v_translate_vertex( ctx, v2, &v[2] );
142 s3v_translate_vertex( ctx, v3, &v[3] );
143 DEBUG(("s3v_fallback_quad\n"));
144 /* _swrast_Quad( ctx, &v[0], &v[1], &v[2], &v[3] ); */
145 }
146
147 static void
148 s3v_fallback_tri( s3vContextPtr vmesa,
149 const s3vVertex *v0,
150 const s3vVertex *v1,
151 const s3vVertex *v2 )
152 {
153 GLcontext *ctx = vmesa->glCtx;
154 SWvertex v[3];
155 s3v_translate_vertex( ctx, v0, &v[0] );
156 s3v_translate_vertex( ctx, v1, &v[1] );
157 s3v_translate_vertex( ctx, v2, &v[2] );
158 DEBUG(("s3v_fallback_tri\n"));
159 /* _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); */
160 }
161
162 static void
163 s3v_fallback_line( s3vContextPtr vmesa,
164 const s3vVertex *v0,
165 const s3vVertex *v1 )
166 {
167 GLcontext *ctx = vmesa->glCtx;
168 SWvertex v[2];
169 s3v_translate_vertex( ctx, v0, &v[0] );
170 s3v_translate_vertex( ctx, v1, &v[1] );
171 DEBUG(("s3v_fallback_line\n"));
172 _swrast_Line( ctx, &v[0], &v[1] );
173 }
174
175 /*
176 static void
177 s3v_fallback_point( s3vContextPtr vmesa,
178 const s3vVertex *v0 )
179 {
180 GLcontext *ctx = vmesa->glCtx;
181 SWvertex v[1];
182 s3v_translate_vertex( ctx, v0, &v[0] );
183 _swrast_Point( ctx, &v[0] );
184 }
185 */
186 #endif
187
188 /***********************************************************************
189 * Choose rasterization functions *
190 ***********************************************************************/
191
192 #define _S3V_NEW_RASTER_STATE (_NEW_FOG | \
193 _NEW_TEXTURE | \
194 _DD_NEW_TRI_SMOOTH | \
195 _DD_NEW_LINE_SMOOTH | \
196 _DD_NEW_POINT_SMOOTH | \
197 _DD_NEW_TRI_STIPPLE | \
198 _DD_NEW_LINE_STIPPLE)
199
200 #define LINE_FALLBACK (0)
201 #define TRI_FALLBACK (0)
202
203 static void s3v_nodraw_triangle(GLcontext *ctx, s3vVertex *v0,
204 s3vVertex *v1, s3vVertex *v2)
205 {
206 (void) (ctx && v0 && v1 && v2);
207 }
208
209 static void s3v_nodraw_quad(GLcontext *ctx,
210 s3vVertex *v0, s3vVertex *v1,
211 s3vVertex *v2, s3vVertex *v3)
212 {
213 (void) (ctx && v0 && v1 && v2 && v3);
214 }
215
216 void s3vChooseRasterState(GLcontext *ctx);
217
218 void s3vChooseRasterState(GLcontext *ctx)
219 {
220 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
221 GLuint flags = ctx->_TriangleCaps;
222 GLuint ind = 0;
223
224 DEBUG(("*** s3vChooseRasterState ***\n"));
225
226 if (ctx->Polygon.CullFlag) {
227 if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
228 vmesa->draw_tri = (s3v_tri_func)s3v_nodraw_triangle;
229 vmesa->draw_quad = (s3v_quad_func)s3v_nodraw_quad;
230 return;
231 }
232 ind |= S3V_RAST_CULL_BIT;
233 /* s3v_update_cullsign(ctx); */
234 } /* else vmesa->backface_sign = 0; */
235
236 if ( flags & DD_FLATSHADE )
237 ind |= S3V_RAST_FLAT_BIT;
238
239 if ( ctx->Texture.Unit[0]._ReallyEnabled ) {
240 ind |= S3V_RAST_TEX_BIT;
241 }
242
243 DEBUG(("ind = %i\n", ind));
244
245 vmesa->draw_line = s3v_line_tab[ind];
246 vmesa->draw_tri = s3v_tri_tab[ind];
247 vmesa->draw_quad = s3v_quad_tab[ind];
248 vmesa->draw_point = s3v_point_tab[ind];
249
250 #if 0
251 /* Hook in fallbacks for specific primitives. CURRENTLY DISABLED
252 */
253
254 if (flags & LINE_FALLBACK)
255 vmesa->draw_line = s3v_fallback_line;
256
257 if (flags & TRI_FALLBACK) {
258 DEBUG(("TRI_FALLBACK\n"));
259 vmesa->draw_tri = s3v_fallback_tri;
260 vmesa->draw_quad = s3v_fallback_quad;
261 }
262 #endif
263 }
264
265
266
267
268 /***********************************************************************
269 * Macros for t_dd_tritmp.h to draw basic primitives *
270 ***********************************************************************/
271
272 #define TRI( v0, v1, v2 ) \
273 do { \
274 /*
275 if (DO_FALLBACK) \
276 vmesa->draw_tri( vmesa, v0, v1, v2 ); \
277 else */ \
278 DEBUG(("TRI: max was here\n")); /* \
279 s3v_draw_tex_triangle( vmesa, v0, v1, v2 ); */ \
280 vmesa->draw_tri( vmesa, v0, v1, v2 ); \
281 } while (0)
282
283 #define QUAD( v0, v1, v2, v3 ) \
284 do { \
285 DEBUG(("QUAD: max was here\n")); \
286 vmesa->draw_quad( vmesa, v0, v1, v2, v3 ); \
287 } while (0)
288
289 #define LINE( v0, v1 ) \
290 do { \
291 DEBUG(("LINE: max was here\n")); \
292 vmesa->draw_line( vmesa, v0, v1 ); \
293 } while (0)
294
295 #define POINT( v0 ) \
296 do { \
297 vmesa->draw_point( vmesa, v0 ); \
298 } while (0)
299
300
301 /***********************************************************************
302 * Build render functions from dd templates *
303 ***********************************************************************/
304
305 /*
306 #define S3V_OFFSET_BIT 0x01
307 #define S3V_TWOSIDE_BIT 0x02
308 #define S3V_UNFILLED_BIT 0x04
309 #define S3V_FALLBACK_BIT 0x08
310 #define S3V_MAX_TRIFUNC 0x10
311
312
313 static struct {
314 points_func points;
315 line_func line;
316 triangle_func triangle;
317 quad_func quad;
318 } rast_tab[S3V_MAX_TRIFUNC];
319 */
320
321 #define DO_FALLBACK (IND & S3V_FALLBACK_BIT)
322 #define DO_OFFSET (IND & S3V_OFFSET_BIT)
323 #define DO_UNFILLED (IND & S3V_UNFILLED_BIT)
324 #define DO_TWOSIDE (IND & S3V_TWOSIDE_BIT)
325 #define DO_FLAT 0
326 #define DO_TRI 1
327 #define DO_QUAD 1
328 #define DO_LINE 1
329 #define DO_POINTS 1
330 #define DO_FULL_QUAD 1
331
332 #define HAVE_RGBA 1
333 #define HAVE_SPEC 0
334 #define HAVE_BACK_COLORS 0
335 #define HAVE_HW_FLATSHADE 1
336 #define VERTEX s3vVertex
337 #define TAB rast_tab
338
339 #define DEPTH_SCALE 1.0
340 #define UNFILLED_TRI unfilled_tri
341 #define UNFILLED_QUAD unfilled_quad
342 #define VERT_X(_v) _v->v.x
343 #define VERT_Y(_v) _v->v.y
344 #define VERT_Z(_v) _v->v.z
345 #define AREA_IS_CCW( a ) (a > 0)
346 #define GET_VERTEX(e) (vmesa->verts + (e<<vmesa->vertex_stride_shift))
347
348 #if 0
349 #define VERT_SET_RGBA( v, c ) \
350 do { \
351 /* UNCLAMPED_FLOAT_TO_RGBA_CHAN( v->ub4[4], c) */ \
352 } while (0)
353
354 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[4] = v1->ui[4]
355 /*
356 #define VERT_COPY_RGBA1( v0, v1 ) v0->ui[4] = v1->ui[4]
357 */
358 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[4]
359 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[4] = color[idx]
360 #endif
361
362 #define LOCAL_VARS(n) \
363 s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
364 GLuint color[n]; \
365 (void) color;
366
367
368 /***********************************************************************
369 * Helpers for rendering unfilled primitives *
370 ***********************************************************************/
371
372 static const GLuint hw_prim[GL_POLYGON+1] = {
373 PrimType_Points,
374 PrimType_Lines,
375 PrimType_Lines,
376 PrimType_Lines,
377 PrimType_Triangles,
378 PrimType_Triangles,
379 PrimType_Triangles,
380 PrimType_Triangles,
381 PrimType_Triangles,
382 PrimType_Triangles
383 };
384
385 static void s3vResetLineStipple( GLcontext *ctx );
386 static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim );
387 static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim );
388 /*
389 extern static void s3v_lines_emit(GLcontext *ctx, GLuint start, GLuint end);
390 extern static void s3v_tris_emit(GLcontext *ctx, GLuint start, GLuint end);
391 */
392 #define RASTERIZE(x) if (vmesa->hw_primitive != hw_prim[x]) \
393 s3vRasterPrimitive( ctx, hw_prim[x] )
394 #define RENDER_PRIMITIVE vmesa->render_primitive
395 #define TAG(x) x
396 #define IND S3V_FALLBACK_BIT
397 #include "tnl_dd/t_dd_unfilled.h"
398 #undef IND
399
400 /***********************************************************************
401 * Generate GL render functions *
402 ***********************************************************************/
403
404 #define IND (0)
405 #define TAG(x) x
406 #include "tnl_dd/t_dd_tritmp.h"
407
408 #define IND (S3V_OFFSET_BIT)
409 #define TAG(x) x##_offset
410 #include "tnl_dd/t_dd_tritmp.h"
411
412 #define IND (S3V_TWOSIDE_BIT)
413 #define TAG(x) x##_twoside
414 #include "tnl_dd/t_dd_tritmp.h"
415
416 #define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT)
417 #define TAG(x) x##_twoside_offset
418 #include "tnl_dd/t_dd_tritmp.h"
419
420 #define IND (S3V_UNFILLED_BIT)
421 #define TAG(x) x##_unfilled
422 #include "tnl_dd/t_dd_tritmp.h"
423
424 #define IND (S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
425 #define TAG(x) x##_offset_unfilled
426 #include "tnl_dd/t_dd_tritmp.h"
427
428 #define IND (S3V_TWOSIDE_BIT|S3V_UNFILLED_BIT)
429 #define TAG(x) x##_twoside_unfilled
430 #include "tnl_dd/t_dd_tritmp.h"
431
432 #define IND (S3V_TWOSIDE_BIT|S3V_OFFSET_BIT|S3V_UNFILLED_BIT)
433 #define TAG(x) x##_twoside_offset_unfilled
434 #include "tnl_dd/t_dd_tritmp.h"
435
436
437 static void init_render_tab( void )
438 {
439 DEBUG(("*** init_render_tab ***\n"));
440
441 init();
442 init_offset();
443 init_twoside();
444 init_twoside_offset();
445 init_unfilled();
446 init_offset_unfilled();
447 init_twoside_unfilled();
448 init_twoside_offset_unfilled();
449 }
450
451
452 /**********************************************************************/
453 /* Render unclipped begin/end objects */
454 /**********************************************************************/
455
456 #define VERT(x) (s3vVertex *)(s3vverts + (x << shift))
457
458 #define RENDER_POINTS( start, count ) \
459 DEBUG(("RENDER_POINTS...(ok)\n")); \
460 for ( ; start < count ; start++) \
461 vmesa->draw_line( vmesa, VERT(start), VERT(start) )
462 /* vmesa->draw_point( vmesa, VERT(start) ) */
463
464 #define RENDER_LINE( v0, v1 ) \
465 /* DEBUG(("RENDER_LINE...(ok)\n")); \ */ \
466 vmesa->draw_line( vmesa, VERT(v0), VERT(v1) ); \
467 DEBUG(("RENDER_LINE...(ok)\n"))
468
469 #define RENDER_TRI( v0, v1, v2 ) \
470 DEBUG(("RENDER_TRI...(ok)\n")); \
471 vmesa->draw_tri( vmesa, VERT(v0), VERT(v1), VERT(v2) )
472
473 #define RENDER_QUAD( v0, v1, v2, v3 ) \
474 DEBUG(("RENDER_QUAD...(ok)\n")); \
475 /* s3v_draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2),VERT(v3) ) */\
476 /* s3v_draw_triangle( vmesa, VERT(v0), VERT(v1), VERT(v2) ); \
477 s3v_draw_triangle( vmesa, VERT(v0), VERT(v2), VERT(v3) ) */ \
478 vmesa->draw_quad( vmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
479
480 #define INIT(x) s3vRenderPrimitive( ctx, x );
481 #undef LOCAL_VARS
482 #define LOCAL_VARS \
483 s3vContextPtr vmesa = S3V_CONTEXT(ctx); \
484 const GLuint shift = vmesa->vertex_stride_shift; \
485 const char *s3vverts = (char *)vmesa->verts; \
486 const GLboolean stipple = ctx->Line.StippleFlag; \
487 (void) stipple;
488 #define RESET_STIPPLE if ( stipple ) s3vResetLineStipple( ctx );
489 #define RESET_OCCLUSION
490 #define PRESERVE_VB_DEFS
491 #define ELT(x) (x)
492 #define TAG(x) s3v_##x##_verts
493 #include "tnl_dd/t_dd_rendertmp.h"
494
495
496 /**********************************************************************/
497 /* Render clipped primitives */
498 /**********************************************************************/
499
500 static void s3vRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
501 GLuint n )
502 {
503 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
504 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
505 TNLcontext *tnl = TNL_CONTEXT(ctx);
506 GLuint prim = vmesa->render_primitive;
507
508 DEBUG(("I AM in: s3vRenderClippedPoly\n"));
509
510 /* Render the new vertices as an unclipped polygon.
511 */
512 if (1)
513 {
514 GLuint *tmp = VB->Elts;
515 VB->Elts = (GLuint *)elts;
516 tnl->Driver.Render.PrimTabElts[GL_POLYGON]
517 ( ctx, 0, n, PRIM_BEGIN|PRIM_END );
518
519 VB->Elts = tmp;
520 }
521
522 /* Restore the render primitive
523 */
524 #if 1
525 if (prim != GL_POLYGON) {
526 DEBUG(("and prim != GL_POLYGON\n"));
527 tnl->Driver.Render.PrimitiveNotify( ctx, prim );
528 }
529
530 #endif
531 }
532
533 static void s3vRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
534 {
535 TNLcontext *tnl = TNL_CONTEXT(ctx);
536 /*tnl->Driver.LineFunc = s3v_line_tab[2];*/ /* _swsetup_Line; */
537
538 DEBUG(("I AM in: s3vRenderClippedLine\n"));
539 tnl->Driver.Render.Line( ctx, ii, jj );
540 }
541
542
543 /**********************************************************************/
544 /* Choose render functions */
545 /**********************************************************************/
546
547
548
549 #define _S3V_NEW_RENDERSTATE (_DD_NEW_TRI_UNFILLED | \
550 _DD_NEW_TRI_LIGHT_TWOSIDE | \
551 _DD_NEW_TRI_OFFSET)
552
553 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
554
555 static void s3vChooseRenderState(GLcontext *ctx)
556 {
557 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
558 TNLcontext *tnl = TNL_CONTEXT(ctx);
559 GLuint flags = ctx->_TriangleCaps;
560 GLuint index = 0;
561
562 DEBUG(("s3vChooseRenderState\n"));
563
564 if (flags & ANY_RASTER_FLAGS) {
565 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= S3V_TWOSIDE_BIT;
566 if (flags & DD_TRI_OFFSET) index |= S3V_OFFSET_BIT;
567 if (flags & DD_TRI_UNFILLED) index |= S3V_UNFILLED_BIT;
568 }
569
570 DEBUG(("vmesa->RenderIndex = %i\n", vmesa->RenderIndex));
571 DEBUG(("index = %i\n", index));
572
573 if (vmesa->RenderIndex != index) {
574 vmesa->RenderIndex = index;
575
576 tnl->Driver.Render.Points = rast_tab[index].points;
577 tnl->Driver.Render.Line = rast_tab[index].line;
578 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
579 tnl->Driver.Render.Quad = rast_tab[index].quad;
580
581 if (vmesa->RenderIndex == 0)
582 tnl->Driver.Render.PrimTabVerts = s3v_render_tab_verts;
583 else
584 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
585 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
586 tnl->Driver.Render.ClippedLine = s3vRenderClippedLine;
587 tnl->Driver.Render.ClippedPolygon = s3vRenderClippedPoly;
588 }
589 }
590
591
592 /**********************************************************************/
593 /* High level hooks for t_vb_render.c */
594 /**********************************************************************/
595
596
597
598 /* Determine the rasterized primitive when not drawing unfilled
599 * polygons.
600 *
601 * Used only for the default render stage which always decomposes
602 * primitives to trianges/lines/points. For the accelerated stage,
603 * which renders strips as strips, the equivalent calculations are
604 * performed in s3v_render.c.
605 */
606
607 static void s3vRasterPrimitive( GLcontext *ctx, GLuint hwprim )
608 {
609 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
610 /* __DRIdrawablePrivate *dPriv = vmesa->driDrawable; */
611 GLuint cmd = vmesa->CMD;
612
613 unsigned int _hw_prim = hwprim;
614
615 DEBUG(("s3vRasterPrimitive: hwprim = 0x%x ", _hw_prim));
616
617 /* printf("* vmesa->CMD = 0x%x\n", vmesa->CMD); */
618
619 if (vmesa->hw_primitive != _hw_prim)
620 {
621 DEBUG(("(new one) ***\n"));
622 cmd &= ~DO_MASK;
623 cmd &= ~ALPHA_BLEND_MASK;
624 vmesa->hw_primitive = _hw_prim;
625
626 if (_hw_prim == PrimType_Triangles) {
627 /* TRI */
628 DEBUG(("->switching to tri\n"));
629 cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
630 } else if (_hw_prim == PrimType_Lines
631 || _hw_prim == PrimType_Points) {
632 /* LINE */
633 DEBUG(("->switching to line\n"));
634 cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
635 } else {
636 /* ugh? */
637 DEBUG(("->switching to your sis'ass\n"));
638 }
639
640 DEBUG(("\n"));
641
642 vmesa->restore_primitive = _hw_prim;
643 /* 0xacc16827: good value -> lightened newave!!! */
644 vmesa->CMD = cmd;
645 CMDCHANGE();
646 }
647 }
648
649 static void s3vRenderPrimitive( GLcontext *ctx, GLenum prim )
650 {
651 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
652 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
653 GLuint cmd = vmesa->CMD;
654
655 unsigned int _hw_prim = hw_prim[prim];
656
657 vmesa->render_primitive = prim;
658 vmesa->hw_primitive = _hw_prim;
659
660 DEBUG(("s3vRenderPrimitive #%i ", prim));
661 DEBUG(("_hw_prim = 0x%x\n", _hw_prim));
662
663 /* printf(" vmesa->CMD = 0x%x\n", vmesa->CMD); */
664
665 if (_hw_prim != vmesa->restore_primitive) {
666 DEBUG(("_hw_prim != vmesa->restore_primitive (was 0x%x)\n",
667 vmesa->restore_primitive));
668 #if 1
669 cmd &= ~DO_MASK;
670 cmd &= ~ALPHA_BLEND_MASK;
671 /*
672 printf(" cmd = 0x%x\n", cmd);
673 printf(" vmesa->_3d_mode=%i; vmesa->_tri[vmesa->_3d_mode]=0x%x\n",
674 vmesa->_3d_mode, vmesa->_tri[vmesa->_3d_mode]);
675 printf("vmesa->alpha[0] = 0x%x; vmesa->alpha[1] = 0x%x\n",
676 vmesa->_alpha[0], vmesa->_alpha[1]);
677 */
678 if (_hw_prim == PrimType_Triangles) { /* TRI */
679 DEBUG(("->switching to tri\n"));
680 cmd |= (vmesa->_tri[vmesa->_3d_mode] | vmesa->_alpha[vmesa->_3d_mode]);
681 DEBUG(("vmesa->TexStride = %i\n", vmesa->TexStride));
682 DEBUG(("vmesa->TexOffset = %i\n", vmesa->TexOffset));
683 DMAOUT_CHECK(3DTRI_Z_BASE, 12);
684 } else { /* LINE */
685 DEBUG(("->switching to line\n"));
686 cmd |= (DO_3D_LINE | vmesa->_alpha[0]);
687 DMAOUT_CHECK(3DLINE_Z_BASE, 12);
688 }
689
690 DMAOUT(vmesa->s3vScreen->depthOffset & 0x003FFFF8);
691 DMAOUT(vmesa->DestBase);
692 /* DMAOUT(vmesa->ScissorLR); */
693 /* DMAOUT(vmesa->ScissorTB); */
694
695 /* NOTE: we need to restore all these values since we
696 * are coming back from a vmesa->restore_primitive */
697 DMAOUT( (0 << 16) | (dPriv->w-1) );
698 DMAOUT( (0 << 16) | (dPriv->h-1) );
699 DMAOUT( (vmesa->SrcStride << 16) | vmesa->TexStride );
700 DMAOUT(vmesa->SrcStride);
701 DMAOUT(vmesa->TexOffset);
702 DMAOUT(vmesa->TextureBorderColor);
703 DMAOUT(0); /* FOG */
704 DMAOUT(0);
705 DMAOUT(0);
706 DMAOUT(cmd);
707 /* 0xacc16827: good value -> lightened newave!!! */
708 DMAFINISH();
709
710 vmesa->CMD = cmd;
711 #endif
712 }
713
714 DEBUG(("\n"));
715
716 vmesa->restore_primitive = _hw_prim;
717 }
718
719 static void s3vRunPipeline( GLcontext *ctx )
720 {
721 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
722
723 DEBUG(("*** s3vRunPipeline ***\n"));
724
725 if ( vmesa->new_state )
726 s3vDDUpdateHWState( ctx );
727
728 if (vmesa->new_gl_state) {
729
730 if (vmesa->new_gl_state & _NEW_TEXTURE) {
731 s3vUpdateTextureState( ctx );
732 }
733
734 if (!vmesa->Fallback) {
735 if (vmesa->new_gl_state & _S3V_NEW_VERTEX)
736 s3vChooseVertexState( ctx );
737
738 if (vmesa->new_gl_state & _S3V_NEW_RASTER_STATE)
739 s3vChooseRasterState( ctx );
740
741 if (vmesa->new_gl_state & _S3V_NEW_RENDERSTATE)
742 s3vChooseRenderState( ctx );
743 }
744
745 vmesa->new_gl_state = 0;
746
747 }
748
749 _tnl_run_pipeline( ctx );
750 }
751
752 static void s3vRenderStart( GLcontext *ctx )
753 {
754 /* Check for projective texturing. Make sure all texcoord
755 * pointers point to something. (fix in mesa?)
756 */
757
758 DEBUG(("s3vRenderStart\n"));
759 /* s3vCheckTexSizes( ctx ); */
760 }
761
762 static void s3vRenderFinish( GLcontext *ctx )
763 {
764 if (0)
765 _swrast_flush( ctx ); /* never needed */
766 }
767
768 static void s3vResetLineStipple( GLcontext *ctx )
769 {
770 /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
771
772 /* Reset the hardware stipple counter.
773 */
774 /*
775 CHECK_DMA_BUFFER(vmesa, 1);
776 WRITE(vmesa->buf, UpdateLineStippleCounters, 0);
777 */
778 }
779
780
781 /**********************************************************************/
782 /* Transition to/from hardware rasterization. */
783 /**********************************************************************/
784
785
786 void s3vFallback( s3vContextPtr vmesa, GLuint bit, GLboolean mode )
787 {
788 GLcontext *ctx = vmesa->glCtx;
789 TNLcontext *tnl = TNL_CONTEXT(ctx);
790 GLuint oldfallback = vmesa->Fallback;
791
792 DEBUG(("*** s3vFallback: "));
793
794 if (mode) {
795 vmesa->Fallback |= bit;
796 if (oldfallback == 0) {
797 DEBUG(("oldfallback == 0 ***\n"));
798 _swsetup_Wakeup( ctx );
799 _tnl_need_projected_coords( ctx, GL_TRUE );
800 vmesa->RenderIndex = ~0;
801 }
802 }
803 else {
804 DEBUG(("***\n"));
805 vmesa->Fallback &= ~bit;
806 if (oldfallback == bit) {
807 _swrast_flush( ctx );
808 tnl->Driver.Render.Start = s3vRenderStart;
809 tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
810 tnl->Driver.Render.Finish = s3vRenderFinish;
811 tnl->Driver.Render.BuildVertices = s3vBuildVertices;
812 tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
813 vmesa->new_gl_state |= (_S3V_NEW_RENDERSTATE|
814 _S3V_NEW_RASTER_STATE|
815 _S3V_NEW_VERTEX);
816 }
817 }
818 }
819
820
821 /**********************************************************************/
822 /* Initialization. */
823 /**********************************************************************/
824
825
826 void s3vInitTriFuncs( GLcontext *ctx )
827 {
828 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
829 TNLcontext *tnl = TNL_CONTEXT(ctx);
830 static int firsttime = 1;
831
832 if (firsttime) {
833 init_rast_tab();
834 init_render_tab();
835 firsttime = 0;
836 }
837
838 vmesa->RenderIndex = ~0;
839
840 tnl->Driver.RunPipeline = s3vRunPipeline;
841 tnl->Driver.Render.Start = s3vRenderStart;
842 tnl->Driver.Render.Finish = s3vRenderFinish;
843 tnl->Driver.Render.PrimitiveNotify = s3vRenderPrimitive;
844 tnl->Driver.Render.ResetLineStipple = s3vResetLineStipple;
845 /*
846 tnl->Driver.RenderInterp = _swsetup_RenderInterp;
847 tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
848 */
849 tnl->Driver.Render.BuildVertices = s3vBuildVertices;
850 }