2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
35 #include "swrast/swrast.h"
36 #include "swrast_setup/swrast_setup.h"
37 #include "tnl/t_context.h"
38 #include "tnl/t_pipeline.h"
40 #include "via_context.h"
42 #include "via_state.h"
45 #include "via_ioctl.h"
47 /***********************************************************************
48 * Emit primitives as inline vertices *
49 ***********************************************************************/
52 #define COPY_DWORDS(vb, vertsize, v) \
56 __asm__ __volatile__("rep ; movsl" \
57 : "=%c" (j), "=D" (vb), "=S" (__tmp) \
63 #define COPY_DWORDS(vb, vertsize, v) \
66 for (j = 0; j < vertsize; j++) \
67 vb[j] = ((GLuint *)v)[j]; \
72 static void __inline__
via_draw_triangle(viaContextPtr vmesa
,
77 GLuint vertsize
= vmesa
->vertexSize
;
78 GLuint
*vb
= viaExtendPrimitive(vmesa
, 3 * 4 * vertsize
);
79 /* fprintf(stderr, "%s: %p %p %p\n", __FUNCTION__, v0, v1, v2); */
80 COPY_DWORDS(vb
, vertsize
, v0
);
81 COPY_DWORDS(vb
, vertsize
, v1
);
82 COPY_DWORDS(vb
, vertsize
, v2
);
86 static void __inline__
via_draw_quad(viaContextPtr vmesa
,
92 GLuint vertsize
= vmesa
->vertexSize
;
93 GLuint
*vb
= viaExtendPrimitive(vmesa
, 6 * 4 * vertsize
);
95 /* fprintf(stderr, "%s: %p %p %p %p\n", __FUNCTION__, v0, v1, v2, v3); */
96 COPY_DWORDS(vb
, vertsize
, v0
);
97 COPY_DWORDS(vb
, vertsize
, v1
);
98 COPY_DWORDS(vb
, vertsize
, v3
);
99 COPY_DWORDS(vb
, vertsize
, v1
);
100 COPY_DWORDS(vb
, vertsize
, v2
);
101 COPY_DWORDS(vb
, vertsize
, v3
);
104 static __inline__
void via_draw_line(viaContextPtr vmesa
,
108 GLuint vertsize
= vmesa
->vertexSize
;
109 GLuint
*vb
= viaExtendPrimitive(vmesa
, 2 * 4 * vertsize
);
110 COPY_DWORDS(vb
, vertsize
, v0
);
111 COPY_DWORDS(vb
, vertsize
, v1
);
115 static __inline__
void via_draw_point(viaContextPtr vmesa
,
118 GLuint vertsize
= vmesa
->vertexSize
;
119 GLuint
*vb
= viaExtendPrimitive(vmesa
, 4 * vertsize
);
120 COPY_DWORDS(vb
, vertsize
, v0
);
126 /***********************************************************************
127 * Macros for via_dd_tritmp.h to draw basic primitives *
128 ***********************************************************************/
130 #define TRI(a, b, c) \
132 if (VIA_DEBUG) fprintf(stderr, "hw TRI\n"); \
134 vmesa->drawTri(vmesa, a, b, c); \
136 via_draw_triangle(vmesa, a, b, c); \
139 #define QUAD(a, b, c, d) \
141 if (VIA_DEBUG) fprintf(stderr, "hw QUAD\n");\
143 vmesa->drawTri(vmesa, a, b, d); \
144 vmesa->drawTri(vmesa, b, c, d); \
147 via_draw_quad(vmesa, a, b, c, d); \
150 #define LINE(v0, v1) \
152 if(VIA_DEBUG) fprintf(stderr, "hw LINE\n");\
154 vmesa->drawLine(vmesa, v0, v1); \
156 via_draw_line(vmesa, v0, v1); \
161 if (VIA_DEBUG) fprintf(stderr, "hw POINT\n");\
163 vmesa->drawPoint(vmesa, v0); \
165 via_draw_point(vmesa, v0); \
169 /***********************************************************************
170 * Build render functions from dd templates *
171 ***********************************************************************/
173 #define VIA_OFFSET_BIT 0x01
174 #define VIA_TWOSIDE_BIT 0x02
175 #define VIA_UNFILLED_BIT 0x04
176 #define VIA_FALLBACK_BIT 0x08
177 #define VIA_MAX_TRIFUNC 0x10
181 tnl_points_func points
;
183 tnl_triangle_func triangle
;
185 } rast_tab
[VIA_MAX_TRIFUNC
];
188 #define DO_FALLBACK (IND & VIA_FALLBACK_BIT)
189 #define DO_OFFSET (IND & VIA_OFFSET_BIT)
190 #define DO_UNFILLED (IND & VIA_UNFILLED_BIT)
191 #define DO_TWOSIDE (IND & VIA_TWOSIDE_BIT)
197 #define DO_FULL_QUAD 1
201 #define HAVE_BACK_COLORS 0
202 #define HAVE_HW_FLATSHADE 1
203 #define VERTEX viaVertex
206 /* Only used to pull back colors into vertices (ie, we know color is
209 #define VIA_COLOR(dst, src) \
217 #define VIA_SPEC(dst, src) \
225 #define DEPTH_SCALE vmesa->polygon_offset_scale
226 #define UNFILLED_TRI unfilled_tri
227 #define UNFILLED_QUAD unfilled_quad
228 #define VERT_X(_v) _v->v.x
229 #define VERT_Y(_v) _v->v.y
230 #define VERT_Z(_v) _v->v.z
231 #define AREA_IS_CCW(a) (a > 0)
232 #define GET_VERTEX(e) (vmesa->verts + (e * vmesa->vertexSize * sizeof(int)))
234 #define VERT_SET_RGBA( v, c ) \
236 via_color_t *color = (via_color_t *)&((v)->ui[coloroffset]); \
237 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
238 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
239 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
240 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
243 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
245 #define VERT_SET_SPEC( v0, c ) \
248 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
249 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
250 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
253 #define VERT_COPY_SPEC( v0, v1 ) \
256 v0->v.specular.red = v1->v.specular.red; \
257 v0->v.specular.green = v1->v.specular.green; \
258 v0->v.specular.blue = v1->v.specular.blue; \
263 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
264 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
265 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
266 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
269 #define LOCAL_VARS(n) \
270 viaContextPtr vmesa = VIA_CONTEXT(ctx); \
271 GLuint color[n], spec[n]; \
272 GLuint coloroffset = (vmesa->vertexSize == 4 ? 3 : 4); \
273 GLboolean havespec = (vmesa->vertexSize > 4); \
274 (void)color; (void)spec; (void)coloroffset; (void)havespec;
277 /***********************************************************************
278 * Helpers for rendering unfilled primitives *
279 ***********************************************************************/
281 static const GLenum hwPrim
[GL_POLYGON
+ 1] = {
295 #define RASTERIZE(x) viaRasterPrimitive( ctx, x, hwPrim[x] )
296 #define RENDER_PRIMITIVE vmesa->renderPrimitive
298 #define IND VIA_FALLBACK_BIT
299 #include "tnl_dd/t_dd_unfilled.h"
303 /***********************************************************************
304 * Generate GL render functions *
305 ***********************************************************************/
310 #include "tnl_dd/t_dd_tritmp.h"
312 #define IND (VIA_OFFSET_BIT)
313 #define TAG(x) x##_offset
314 #include "tnl_dd/t_dd_tritmp.h"
316 #define IND (VIA_TWOSIDE_BIT)
317 #define TAG(x) x##_twoside
318 #include "tnl_dd/t_dd_tritmp.h"
320 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT)
321 #define TAG(x) x##_twoside_offset
322 #include "tnl_dd/t_dd_tritmp.h"
324 #define IND (VIA_UNFILLED_BIT)
325 #define TAG(x) x##_unfilled
326 #include "tnl_dd/t_dd_tritmp.h"
328 #define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
329 #define TAG(x) x##_offset_unfilled
330 #include "tnl_dd/t_dd_tritmp.h"
332 #define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT)
333 #define TAG(x) x##_twoside_unfilled
334 #include "tnl_dd/t_dd_tritmp.h"
336 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT)
337 #define TAG(x) x##_twoside_offset_unfilled
338 #include "tnl_dd/t_dd_tritmp.h"
340 #define IND (VIA_FALLBACK_BIT)
341 #define TAG(x) x##_fallback
342 #include "tnl_dd/t_dd_tritmp.h"
344 #define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
345 #define TAG(x) x##_offset_fallback
346 #include "tnl_dd/t_dd_tritmp.h"
348 #define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT)
349 #define TAG(x) x##_twoside_fallback
350 #include "tnl_dd/t_dd_tritmp.h"
352 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT)
353 #define TAG(x) x##_twoside_offset_fallback
354 #include "tnl_dd/t_dd_tritmp.h"
356 #define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
357 #define TAG(x) x##_unfilled_fallback
358 #include "tnl_dd/t_dd_tritmp.h"
360 #define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
361 #define TAG(x) x##_offset_unfilled_fallback
362 #include "tnl_dd/t_dd_tritmp.h"
364 #define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT)
365 #define TAG(x) x##_twoside_unfilled_fallback
366 #include "tnl_dd/t_dd_tritmp.h"
368 #define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT| \
370 #define TAG(x) x##_twoside_offset_unfilled_fallback
371 #include "tnl_dd/t_dd_tritmp.h"
374 static void init_rast_tab(void)
379 init_twoside_offset();
381 init_offset_unfilled();
382 init_twoside_unfilled();
383 init_twoside_offset_unfilled();
385 init_offset_fallback();
386 init_twoside_fallback();
387 init_twoside_offset_fallback();
388 init_unfilled_fallback();
389 init_offset_unfilled_fallback();
390 init_twoside_unfilled_fallback();
391 init_twoside_offset_unfilled_fallback();
395 /***********************************************************************
396 * Rasterization fallback helpers *
397 ***********************************************************************/
400 /* This code is hit only when a mix of accelerated and unaccelerated
401 * primitives are being drawn, and only for the unaccelerated
405 via_fallback_tri(viaContextPtr vmesa
,
410 GLcontext
*ctx
= vmesa
->glCtx
;
412 via_translate_vertex(ctx
, v0
, &v
[0]);
413 via_translate_vertex(ctx
, v1
, &v
[1]);
414 via_translate_vertex(ctx
, v2
, &v
[2]);
415 viaSpanRenderStart( ctx
);
416 _swrast_Triangle(ctx
, &v
[0], &v
[1], &v
[2]);
417 viaSpanRenderFinish( ctx
);
422 via_fallback_line(viaContextPtr vmesa
,
426 GLcontext
*ctx
= vmesa
->glCtx
;
428 via_translate_vertex(ctx
, v0
, &v
[0]);
429 via_translate_vertex(ctx
, v1
, &v
[1]);
430 viaSpanRenderStart( ctx
);
431 _swrast_Line(ctx
, &v
[0], &v
[1]);
432 viaSpanRenderFinish( ctx
);
437 via_fallback_point(viaContextPtr vmesa
,
440 GLcontext
*ctx
= vmesa
->glCtx
;
442 via_translate_vertex(ctx
, v0
, &v
[0]);
443 viaSpanRenderStart( ctx
);
444 _swrast_Point(ctx
, &v
[0]);
445 viaSpanRenderFinish( ctx
);
448 /**********************************************************************/
449 /* Render unclipped begin/end objects */
450 /**********************************************************************/
452 #define V(x) (viaVertex *)(vertptr + ((x) * vertsize * sizeof(int)))
453 #define RENDER_POINTS(start, count) \
454 for (; start < count; start++) POINT(V(ELT(start)));
455 #define RENDER_LINE(v0, v1) LINE(V(v0), V(v1))
456 #define RENDER_TRI( v0, v1, v2) TRI( V(v0), V(v1), V(v2))
457 #define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
458 #define INIT(x) viaRasterPrimitive(ctx, x, hwPrim[x])
461 viaContextPtr vmesa = VIA_CONTEXT(ctx); \
462 GLubyte *vertptr = (GLubyte *)vmesa->verts; \
463 const GLuint vertsize = vmesa->vertexSize; \
464 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
466 #define RESET_STIPPLE
467 #define RESET_OCCLUSION
468 #define PRESERVE_VB_DEFS
470 #define TAG(x) via_fast##x##_verts
471 #include "tnl/t_vb_rendertmp.h"
474 #define TAG(x) via_fast##x##_elts
475 #define ELT(x) elt[x]
476 #include "tnl/t_vb_rendertmp.h"
479 #undef NEED_EDGEFLAG_SETUP
482 #undef RESET_OCCLUSION
485 /**********************************************************************/
486 /* Render clipped primitives */
487 /**********************************************************************/
491 static void viaRenderClippedPoly(GLcontext
*ctx
, const GLuint
*elts
,
494 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
495 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
496 GLuint prim
= VIA_CONTEXT(ctx
)->renderPrimitive
;
498 /* Render the new vertices as an unclipped polygon.
501 GLuint
*tmp
= VB
->Elts
;
502 VB
->Elts
= (GLuint
*)elts
;
503 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
](ctx
, 0, n
,
504 PRIM_BEGIN
|PRIM_END
);
508 /* Restore the render primitive
510 if (prim
!= GL_POLYGON
)
511 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
514 static void viaRenderClippedLine(GLcontext
*ctx
, GLuint ii
, GLuint jj
)
516 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
517 tnl
->Driver
.Render
.Line(ctx
, ii
, jj
);
520 static void viaFastRenderClippedPoly(GLcontext
*ctx
, const GLuint
*elts
,
523 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
524 GLuint vertsize
= vmesa
->vertexSize
;
525 GLuint
*vb
= viaExtendPrimitive(vmesa
, (n
- 2) * 3 * 4 * vertsize
);
526 GLubyte
*vertptr
= (GLubyte
*)vmesa
->verts
;
527 const GLuint
*start
= (const GLuint
*)V(elts
[0]);
530 for (i
= 2; i
< n
; i
++) {
531 COPY_DWORDS(vb
, vertsize
, V(elts
[i
- 1]));
532 COPY_DWORDS(vb
, vertsize
, V(elts
[i
]));
533 COPY_DWORDS(vb
, vertsize
, start
);
537 /**********************************************************************/
538 /* Choose render functions */
539 /**********************************************************************/
543 #define _VIA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
544 _DD_NEW_TRI_UNFILLED | \
545 _DD_NEW_TRI_LIGHT_TWOSIDE | \
546 _DD_NEW_TRI_OFFSET | \
547 _DD_NEW_TRI_STIPPLE | \
550 /* Via does support line stipple in hardware, and it is partially
551 * working in the older versions of this driver:
553 #define LINE_FALLBACK (DD_LINE_STIPPLE)
554 #define POINT_FALLBACK (0)
555 #define TRI_FALLBACK (0)
556 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
557 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
559 void viaChooseRenderState(GLcontext
*ctx
)
561 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
562 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
563 GLuint flags
= ctx
->_TriangleCaps
;
565 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
567 if (VIA_DEBUG
) fprintf(stderr
, "_TriangleCaps = %x\n", flags
);
568 if (flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) {
569 if (flags
& ANY_RASTER_FLAGS
) {
570 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= VIA_TWOSIDE_BIT
;
571 if (flags
& DD_TRI_OFFSET
) index
|= VIA_OFFSET_BIT
;
572 if (flags
& DD_TRI_UNFILLED
) index
|= VIA_UNFILLED_BIT
;
575 vmesa
->drawPoint
= via_draw_point
;
576 vmesa
->drawLine
= via_draw_line
;
577 vmesa
->drawTri
= via_draw_triangle
;
579 /* Hook in fallbacks for specific primitives.
581 if (flags
& ANY_FALLBACK_FLAGS
) {
582 if (flags
& POINT_FALLBACK
)
583 vmesa
->drawPoint
= via_fallback_point
;
585 if (flags
& LINE_FALLBACK
)
586 vmesa
->drawLine
= via_fallback_line
;
588 if (flags
& TRI_FALLBACK
)
589 vmesa
->drawTri
= via_fallback_tri
;
591 index
|= VIA_FALLBACK_BIT
;
595 fprintf(stderr
, "index = %x\n", index
);
596 fprintf(stderr
, "renderIndex = %x\n", vmesa
->renderIndex
);
598 if (vmesa
->renderIndex
!= index
) {
599 vmesa
->renderIndex
= index
;
601 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
602 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
603 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
605 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
608 tnl
->Driver
.Render
.PrimTabVerts
= via_fastrender_tab_verts
;
609 tnl
->Driver
.Render
.PrimTabElts
= via_fastrender_tab_elts
;
610 tnl
->Driver
.Render
.ClippedLine
= line
; /* from tritmp.h */
611 tnl
->Driver
.Render
.ClippedPolygon
= viaFastRenderClippedPoly
;
614 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
615 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
616 tnl
->Driver
.Render
.ClippedLine
= viaRenderClippedLine
;
617 tnl
->Driver
.Render
.ClippedPolygon
= viaRenderClippedPoly
;
620 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
627 /**********************************************************************/
628 /* High level hooks for t_vb_render.c */
629 /**********************************************************************/
631 static void viaRunPipeline(GLcontext
*ctx
)
633 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
635 if (vmesa
->newState
) {
636 viaValidateState( ctx
);
637 if (!vmesa
->Fallback
) {
638 viaChooseVertexState(ctx
);
639 viaChooseRenderState(ctx
);
643 _tnl_run_pipeline(ctx
);
646 static void viaRenderStart(GLcontext
*ctx
)
648 /* Check for projective texturing. Make sure all texcoord
649 * pointers point to something. (fix in mesa?)
651 viaCheckTexSizes(ctx
);
654 static void viaRenderFinish(GLcontext
*ctx
)
656 if (VIA_CONTEXT(ctx
)->renderIndex
& VIA_FALLBACK_BIT
)
659 VIA_FINISH_PRIM(VIA_CONTEXT(ctx
));
664 /* System to flush dma and emit state changes based on the rasterized
667 void viaRasterPrimitive(GLcontext
*ctx
,
671 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
676 fprintf(stderr
, "%s: %s/%s\n", __FUNCTION__
, _mesa_lookup_enum_by_nr(glprim
),
677 _mesa_lookup_enum_by_nr(hwprim
));
679 VIA_FINISH_PRIM(vmesa
);
681 viaCheckDma( vmesa
, 1024 ); /* Ensure no wrapping inside this function */
683 if (vmesa
->newEmitState
) {
688 regCmdB
= vmesa
->regCmdB
;
692 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Point
| HC_HVCycle_Full
;
693 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
694 vmesa
->regCmdA_End
|= HC_HShading_FlatA
;
697 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Line
| HC_HVCycle_Full
;
698 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
699 vmesa
->regCmdA_End
|= HC_HShading_FlatB
;
703 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Line
| HC_HVCycle_AFP
|
704 HC_HVCycle_AB
| HC_HVCycle_NewB
;
705 regCmdB
|= HC_HVCycle_AB
| HC_HVCycle_NewB
| HC_HLPrst_MASK
;
706 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
707 vmesa
->regCmdA_End
|= HC_HShading_FlatB
;
710 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Tri
| HC_HVCycle_Full
;
711 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
712 vmesa
->regCmdA_End
|= HC_HShading_FlatC
;
714 case GL_TRIANGLE_STRIP
:
715 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Tri
| HC_HVCycle_AFP
|
716 HC_HVCycle_AC
| HC_HVCycle_BB
| HC_HVCycle_NewC
;
717 regCmdB
|= HC_HVCycle_AA
| HC_HVCycle_BC
| HC_HVCycle_NewC
;
718 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
719 vmesa
->regCmdA_End
|= HC_HShading_FlatB
;
721 case GL_TRIANGLE_FAN
:
722 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Tri
| HC_HVCycle_AFP
|
723 HC_HVCycle_AA
| HC_HVCycle_BC
| HC_HVCycle_NewC
;
724 regCmdB
|= HC_HVCycle_AA
| HC_HVCycle_BC
| HC_HVCycle_NewC
;
725 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
726 vmesa
->regCmdA_End
|= HC_HShading_FlatC
;
735 vmesa
->regCmdA_End
= vmesa
->regCmdA
| HC_HPMType_Tri
| HC_HVCycle_AFP
|
736 HC_HVCycle_AA
| HC_HVCycle_BC
| HC_HVCycle_NewC
;
737 regCmdB
|= HC_HVCycle_AA
| HC_HVCycle_BC
| HC_HVCycle_NewC
;
738 if (ctx
->Light
.ShadeModel
== GL_FLAT
)
739 vmesa
->regCmdA_End
|= HC_HShading_FlatC
;
746 /* assert((vmesa->dmaLow & 0x4) == 0); */
748 if (vmesa
->dmaCliprectAddr
== 0) {
749 if (VIA_DEBUG
) fprintf(stderr
, "reserve cliprect space at %x\n", vmesa
->dmaLow
);
750 assert(vmesa
->dmaLow
);
751 vmesa
->dmaCliprectAddr
= vmesa
->dmaLow
;
753 OUT_RING( HC_HEADER2
);
754 OUT_RING( (HC_ParaType_NotTex
<< 16) );
755 OUT_RING( 0xCCCCCCCC );
756 OUT_RING( 0xCCCCCCCC );
757 OUT_RING( 0xCCCCCCCC );
758 OUT_RING( 0xCCCCCCCC );
759 OUT_RING( 0xCCCCCCCC );
760 OUT_RING( 0xCCCCCCCC );
766 OUT_RING( HC_HEADER2
);
767 OUT_RING( (HC_ParaType_NotTex
<< 16) );
768 OUT_RING( 0xCCCCCCCC );
769 OUT_RING( 0xDDDDDDDD );
771 OUT_RING( HC_HEADER2
);
772 OUT_RING( (HC_ParaType_CmdVdata
<< 16) );
774 OUT_RING( vmesa
->regCmdA_End
);
778 vmesa
->renderPrimitive
= glprim
;
779 vmesa
->hwPrimitive
= hwprim
;
780 vmesa
->dmaLastPrim
= vmesa
->dmaLow
;
783 /* Callback for mesa:
785 static void viaRenderPrimitive( GLcontext
*ctx
, GLuint prim
)
787 viaRasterPrimitive( ctx
, prim
, hwPrim
[prim
] );
791 void viaFinishPrimitive(viaContextPtr vmesa
)
794 fprintf(stderr
, "%s\n", __FUNCTION__
);
796 if (!vmesa
->dmaLastPrim
|| !vmesa
->dmaCliprectAddr
) {
799 else if (vmesa
->dmaLow
!= vmesa
->dmaLastPrim
) {
800 GLuint cmdA
= vmesa
->regCmdA_End
| HC_HPLEND_MASK
| HC_HPMValidN_MASK
| HC_HE3Fire_MASK
;
803 vmesa
->dmaLastPrim
= 0;
805 /* KW: modified 0x1 to 0x4 below:
807 if ((vmesa
->dmaLow
& 0x1) || !vmesa
->useAgp
) {
808 BEGIN_RING_NOCHECK( 1 );
813 BEGIN_RING_NOCHECK( 2 );
819 if (vmesa
->dmaLow
> VIA_DMA_HIGHWATER
)
820 viaFlushDma( vmesa
);
824 fprintf(stderr
, "remove empty primitive\n");
826 /* Remove the primitive header:
828 vmesa
->dmaLastPrim
= 0;
829 vmesa
->dmaLow
-= 8 * sizeof(GLuint
);
831 /* Maybe remove the cliprect as well:
833 if (vmesa
->dmaCliprectAddr
== vmesa
->dmaLow
- 8 * sizeof(GLuint
)) {
834 vmesa
->dmaLow
-= 8 * sizeof(GLuint
);
835 vmesa
->dmaCliprectAddr
= 0;
839 vmesa
->renderPrimitive
= GL_POLYGON
+ 1;
840 vmesa
->hwPrimitive
= GL_POLYGON
+ 1;
841 vmesa
->dmaLastPrim
= 0;
845 /**********************************************************************/
846 /* Transition to/from hardware rasterization. */
847 /**********************************************************************/
850 void viaFallback(viaContextPtr vmesa
, GLuint bit
, GLboolean mode
)
852 GLcontext
*ctx
= vmesa
->glCtx
;
853 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
854 GLuint oldfallback
= vmesa
->Fallback
;
855 if (VIA_DEBUG
) fprintf(stderr
, "%s old %x bit %x mode %d\n", __FUNCTION__
,
856 vmesa
->Fallback
, bit
, mode
);
859 vmesa
->Fallback
|= bit
;
860 if (oldfallback
== 0) {
861 if (VIA_DEBUG
) fprintf(stderr
, "ENTER FALLBACK\n");
862 VIA_FLUSH_DMA(vmesa
);
863 _swsetup_Wakeup(ctx
);
864 vmesa
->renderIndex
= ~0;
868 vmesa
->Fallback
&= ~bit
;
869 if (oldfallback
== bit
) {
870 if (VIA_DEBUG
) fprintf(stderr
, "LEAVE FALLBACK\n");
871 tnl
->Driver
.Render
.Start
= viaRenderStart
;
872 tnl
->Driver
.Render
.PrimitiveNotify
= viaRenderPrimitive
;
873 tnl
->Driver
.Render
.Finish
= viaRenderFinish
;
874 tnl
->Driver
.Render
.BuildVertices
= viaBuildVertices
;
875 vmesa
->newState
|= (_VIA_NEW_RENDERSTATE
|_VIA_NEW_VERTEX
);
882 /**********************************************************************/
883 /* Initialization. */
884 /**********************************************************************/
887 void viaInitTriFuncs(GLcontext
*ctx
)
889 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
890 static int firsttime
= 1;
897 tnl
->Driver
.RunPipeline
= viaRunPipeline
;
898 tnl
->Driver
.Render
.Start
= viaRenderStart
;
899 tnl
->Driver
.Render
.Finish
= viaRenderFinish
;
900 tnl
->Driver
.Render
.PrimitiveNotify
= viaRenderPrimitive
;
901 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
902 tnl
->Driver
.Render
.BuildVertices
= viaBuildVertices
;