diff options
Diffstat (limited to 'src/mesa/drivers/dri/unichrome/via_tris.c')
-rw-r--r-- | src/mesa/drivers/dri/unichrome/via_tris.c | 1717 |
1 files changed, 1717 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/unichrome/via_tris.c b/src/mesa/drivers/dri/unichrome/via_tris.c new file mode 100644 index 0000000000..47f081d58a --- /dev/null +++ b/src/mesa/drivers/dri/unichrome/via_tris.c @@ -0,0 +1,1717 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <math.h> + +#include "glheader.h" +#include "context.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "via_context.h" +#include "via_tris.h" +#include "via_state.h" +#include "via_vb.h" +#include "via_ioctl.h" + +static void viaRenderPrimitive(GLcontext *ctx, GLenum prim); +GLuint RasterCounter = 0; +extern GLuint idle; +extern GLuint busy; +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#if defined(USE_X86_ASM) +#define COPY_DWORDS(j, vb, vertsize, v) \ + do { \ + int __tmp; \ + __asm__ __volatile__("rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v)); \ + } while (0) +#else +#define COPY_DWORDS(j, vb, vertsize, v) \ + do { \ + for (j = 0; j < vertsize; j++) \ + vb[j] = ((GLuint *)v)[j]; \ + vb += vertsize; \ + } while (0) +#endif + +static void __inline__ via_draw_triangle(viaContextPtr vmesa, + viaVertexPtr v0, + viaVertexPtr v1, + viaVertexPtr v2) +{ + GLuint vertsize = vmesa->vertex_size; + GLuint *vb = viaCheckDma(vmesa, 3 * 4 * vertsize); + int j; + +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + COPY_DWORDS(j, vb, vertsize, v2); + vmesa->dmaLow += 3 * 4 * vertsize; + vmesa->primitiveRendered = GL_TRUE; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +static void __inline__ via_draw_quad(viaContextPtr vmesa, + viaVertexPtr v0, + viaVertexPtr v1, + viaVertexPtr v2, + viaVertexPtr v3) +{ + GLuint vertsize = vmesa->vertex_size; + GLuint *vb = viaCheckDma(vmesa, 6 * 4 * vertsize); + int j; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + COPY_DWORDS(j, vb, vertsize, v3); + COPY_DWORDS(j, vb, vertsize, v1); + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v3); + vmesa->dmaLow += 6 * 4 * vertsize; + vmesa->primitiveRendered = GL_TRUE; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +static __inline__ void via_draw_point(viaContextPtr vmesa, + viaVertexPtr v0) +{ + /*GLfloat sz = vmesa->glCtx->Point._Size * .5;*/ + int vertsize = vmesa->vertex_size; + /*GLuint *vb = viaCheckDma(vmesa, 2 * 4 * vertsize);*/ + GLuint *vb = viaCheckDma(vmesa, 4 * vertsize); + int j; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + COPY_DWORDS(j, vb, vertsize, v0); + vmesa->dmaLow += 4 * vertsize; + vmesa->primitiveRendered = GL_TRUE; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +/* + * Draw line in hardware. + * Checked out - AC. + */ +static __inline__ void via_draw_line(viaContextPtr vmesa, + viaVertexPtr v0, + viaVertexPtr v1) +{ + GLuint vertsize = vmesa->vertex_size; + GLuint *vb = viaCheckDma(vmesa, 2 * 4 * vertsize); + int j; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + vmesa->dmaLow += 2 * 4 * vertsize; + vmesa->primitiveRendered = GL_TRUE; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +/*********************************************************************** + * Macros for via_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI(a, b, c) \ + do { \ + if (VIA_DEBUG) fprintf(stderr, "hw TRI\n"); \ + if (DO_FALLBACK) \ + vmesa->drawTri(vmesa, a, b, c); \ + else \ + via_draw_triangle(vmesa, a, b, c); \ + } while (0) + +#define QUAD(a, b, c, d) \ + do { \ + if (VIA_DEBUG) fprintf(stderr, "hw QUAD\n");\ + if (DO_FALLBACK) { \ + vmesa->drawTri(vmesa, a, b, d); \ + vmesa->drawTri(vmesa, b, c, d); \ + } \ + else \ + via_draw_quad(vmesa, a, b, c, d); \ + } while (0) + +#define LINE(v0, v1) \ + do { \ + if( VIA_DEBUG) fprintf(stderr, "hw LINE\n");\ + if (DO_FALLBACK) \ + vmesa->drawLine(vmesa, v0, v1); \ + else \ + via_draw_line(vmesa, v0, v1); \ + } while (0) + +#define POINT(v0) \ + do { \ + if (VIA_DEBUG) fprintf(stderr, "hw POINT\n");\ + if (DO_FALLBACK) \ + vmesa->drawPoint(vmesa, v0); \ + else \ + via_draw_point(vmesa, v0); \ + } while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define VIA_OFFSET_BIT 0x01 +#define VIA_TWOSIDE_BIT 0x02 +#define VIA_UNFILLED_BIT 0x04 +#define VIA_FALLBACK_BIT 0x08 +#define VIA_MAX_TRIFUNC 0x10 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[VIA_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & VIA_FALLBACK_BIT) +#define DO_OFFSET (IND & VIA_OFFSET_BIT) +#define DO_UNFILLED (IND & VIA_UNFILLED_BIT) +#define DO_TWOSIDE (IND & VIA_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX viaVertex +#define TAB rast_tab + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define VIA_COLOR(dst, src) \ + do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ + dst[3] = src[3]; \ + } while (0) + +#define VIA_SPEC(dst, src) \ + do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ + } while (0) + + +#define DEPTH_SCALE (1.0 / 0xffff) +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW(a) (a > 0) +#define GET_VERTEX(e) (vmesa->verts + (e<<vmesa->vertex_stride_shift)) + +#define VERT_SET_RGBA(v, c) VIA_COLOR(v->ub4[coloroffset], c) +#define VERT_COPY_RGBA(v0, v1) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA(idx) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA(idx) v[idx]->ui[coloroffset] = color[idx] +#define VERT_SET_SPEC(v, c) if (havespec) VIA_SPEC(v->ub4[5], c) +#define VERT_COPY_SPEC(v0, v1) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5]) +#define VERT_SAVE_SPEC(idx) if (havespec) spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC(idx) if (havespec) v[idx]->ui[5] = spec[idx] + +#define SET_PRIMITIVE_RENDERED vmesa->primitiveRendered = GL_TRUE; + +#define LOCAL_VARS(n) \ + viaContextPtr vmesa = VIA_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (vmesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (vmesa->vertex_size > 4); \ + (void)color; (void)spec; (void)coloroffset; (void)havespec; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ +/* +static const GLuint hwPrim[GL_POLYGON + 1] = { + PR_LINES, + PR_LINES, + PR_LINES, + PR_LINES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES +}; +*/ + +#define RASTERIZE(x) \ + if (vmesa->hwPrimitive != x) { \ + viaRasterPrimitiveFinish(ctx); \ + viaRasterPrimitive(ctx, x, x); \ + } + +#define RENDER_PRIMITIVE vmesa->renderPrimitive +#define TAG(x) x +#define IND VIA_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND +#undef RASTERIZE + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ +#define RASTERIZE(x) + +#define IND (0) +#define TAG(x) x +#include "via_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT) +#define TAG(x) x##_offset +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "via_dd_tritmp.h" + +#define IND (VIA_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "via_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "via_dd_tritmp.h" + +#define IND (VIA_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "via_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT| \ + VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "via_dd_tritmp.h" + + +static void init_rast_tab(void) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +via_fallback_tri(viaContextPtr vmesa, + viaVertex *v0, + viaVertex *v1, + viaVertex *v2) +{ + GLcontext *ctx = vmesa->glCtx; + SWvertex v[3]; +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + via_translate_vertex(ctx, v0, &v[0]); + via_translate_vertex(ctx, v1, &v[1]); + via_translate_vertex(ctx, v2, &v[2]); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); +} + + +static void +via_fallback_line(viaContextPtr vmesa, + viaVertex *v0, + viaVertex *v1) +{ + GLcontext *ctx = vmesa->glCtx; + SWvertex v[2]; +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + via_translate_vertex(ctx, v0, &v[0]); + via_translate_vertex(ctx, v1, &v[1]); + _swrast_Line(ctx, &v[0], &v[1]); +} + + +static void +via_fallback_point(viaContextPtr vmesa, + viaVertex *v0) +{ + GLcontext *ctx = vmesa->glCtx; + SWvertex v[1]; +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + via_translate_vertex(ctx, v0, &v[0]); + _swrast_Point(ctx, &v[0]); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/* (No Twoside / Offset / Unfilled) */ +/**********************************************************************/ +#define IND 0 +#define V(x) (viaVertex *)(vertptr + ((x) << vertshift)) +#define RENDER_POINTS(start, count) \ + for (; start < count; start++) POINT(V(ELT(start))); +#define RENDER_LINE(v0, v1) LINE(V(v0), V(v1)) + +#define RENDER_TRI( v0, v1, v2) \ + if (VIA_DEBUG) fprintf(stderr, "RENDER_TRI - simple\n"); \ + TRI( V(v0), V(v1), V(v2)) + +#define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3)) + +#define INIT(x) viaRasterPrimitive(ctx, x, x) + +#undef LOCAL_VARS +#define LOCAL_VARS \ + viaContextPtr vmesa = VIA_CONTEXT(ctx); \ + GLubyte *vertptr = (GLubyte *)vmesa->verts; \ + const GLuint vertshift = vmesa->vertex_stride_shift; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void)elt; +#define POSTFIX \ + viaRasterPrimitiveFinish(ctx) +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) via_fast##x##_verts +#include "via_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) via_fast##x##_elts +#define ELT(x) elt[x] +#include "via_vb_rendertmp.h" +#undef ELT +#undef TAG +#undef NEED_EDGEFLAG_SETUP +#undef EDGEFLAG_GET +#undef EDGEFLAG_SET +#undef RESET_OCCLUSION + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/* (Can handle Twoside / Offset / Unfilled */ +/**********************************************************************/ +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + +#define RENDER_POINTS(start, count) \ + tnl->Driver.Render.Points(ctx, start, count) + +#define RENDER_LINE(v1, v2) \ + LineFunc(ctx, v1, v2) + +#define RENDER_TRI(v1, v2, v3) \ + if (VIA_DEBUG) fprintf(stderr, "RENDER_TRI - complex\n"); \ + if (VIA_DEBUG) fprintf(stderr, "TriangleFunc = %x\n", (unsigned int)TriangleFunc); \ + TriangleFunc(ctx, v1, v2, v3) + +#define RENDER_QUAD(v1, v2, v3, v4) \ + QuadFunc(ctx, v1, v2, v3, v4) + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const line_func LineFunc = tnl->Driver.Render.Line; \ + const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ + const quad_func QuadFunc = tnl->Driver.Render.Quad; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; (void) stipple; + +#define POSTFIX \ + viaRasterPrimitiveFinish(ctx) +#define ELT(x) x +#define TAG(x) via_##x##_verts +/*#define INIT(x) tnl->Driver.Render.PrimitiveNotify(ctx, x)*/ +#define INIT(x) viaRasterPrimitive(ctx, x, x) +#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple(ctx) +#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE +#define PRESERVE_VB_DEFS +#include "via_vb_rendertmp.h" +#undef ELT +#undef TAG +#define ELT(x) elt[x] +#define TAG(x) via_##x##_elts +#include "via_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void viaRenderClippedPoly(GLcontext *ctx, const GLuint *elts, + GLuint n) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, + PRIM_BEGIN|PRIM_END); + VB->Elts = tmp; + } +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + vmesa->primitiveRendered = GL_TRUE; + + tnl->Driver.Render.Line(ctx, ii, jj); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts, + GLuint n) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); + GLuint vertsize = vmesa->vertex_size; + GLuint *vb = viaCheckDma(vmesa, (n - 2) * 3 * 4 * vertsize); + GLubyte *vertptr = (GLubyte *)vmesa->verts; + const GLuint vertshift = vmesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)V(elts[0]); + GLuint *temp1; + GLuint *temp2; + int i,j; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + vmesa->primitiveRendered = GL_TRUE; + + for (i = 2; i < n; i++) { + /*=* [DBG] exy : fix flat-shading + clipping error *=*/ + /*COPY_DWORDS(j, vb, vertsize, start); + COPY_DWORDS(j, vb, vertsize, V(elts[i - 1])); + temp1 = (GLuint *)V(elts[i - 1]); + COPY_DWORDS(j, vb, vertsize, V(elts[i])); + temp2 = (GLuint *)V(elts[i]);*/ + COPY_DWORDS(j, vb, vertsize, V(elts[i - 1])); + COPY_DWORDS(j, vb, vertsize, V(elts[i])); + temp1 = (GLuint *)V(elts[i - 1]); + COPY_DWORDS(j, vb, vertsize, start); + temp2 = (GLuint *)V(elts[i]); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "start = %d - x = %f, y = %f, z = %f, w = %f, u = %f, v = %f\n", elts[0], *(GLfloat *)&start[0], *(GLfloat *)&start[1], *(GLfloat *)&start[2], *(GLfloat *)&start[3], *(GLfloat *)&start[6], *(GLfloat *)&start[7]); + if (VIA_DEBUG) fprintf(stderr, "%d - x = %f, y = %f, z = %f, w = %f, u = %f, v = %f\n", elts[i - 1], *(GLfloat *)&temp1[0], *(GLfloat *)&temp1[1], *(GLfloat *)&temp1[2], *(GLfloat *)&temp1[3], *(GLfloat *)&temp1[6], *(GLfloat *)&temp1[7]); + if (VIA_DEBUG) fprintf(stderr, "%d - x = %f, y = %f, z = %f, w = %f, u = %f, v = %f\n", elts[i], *(GLfloat *)&temp2[0], *(GLfloat *)&temp2[1], *(GLfloat *)&temp2[2], *(GLfloat *)&temp2[3], *(GLfloat *)&temp2[6], *(GLfloat *)&temp2[7]); +#endif + } + vmesa->dmaLow += (n - 2) * 3 * 4 * vertsize; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + +#define _VIA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_POLYGONSTIPPLE) + +#define POINT_FALLBACK (0) +/*#define LINE_FALLBACK (DD_LINE_STIPPLE) +*/ +#define LINE_FALLBACK (0) +#define TRI_FALLBACK (0) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) + +static void viaChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + viaContextPtr vmesa = VIA_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); + + if (VIA_DEBUG) fprintf(stderr, "_TriangleCaps = %x\n", flags); +#endif + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= VIA_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= VIA_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= VIA_UNFILLED_BIT; + } + + vmesa->drawPoint = via_draw_point; + vmesa->drawLine = via_draw_line; + vmesa->drawTri = via_draw_triangle; + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) { + if (flags & POINT_FALLBACK) + vmesa->drawPoint = via_fallback_point; + + if (flags & LINE_FALLBACK) + vmesa->drawLine = via_fallback_line; + + if (flags & TRI_FALLBACK) + vmesa->drawTri = via_fallback_tri; + + index |= VIA_FALLBACK_BIT; + } + } +#ifdef DEBUG + if (VIA_DEBUG) { + fprintf(stderr, "index = %x\n", index); + fprintf(stderr, "renderIndex = %x\n", vmesa->renderIndex); + } +#endif + if (vmesa->renderIndex != index) { + vmesa->renderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "tnl->Driver.Render.xxx = rast_tab[index].xxx = %x\n", (unsigned int)tnl->Driver.Render.Triangle); +#endif + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = via_fastrender_tab_verts; + tnl->Driver.Render.PrimTabElts = via_fastrender_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly; + } + else { + tnl->Driver.Render.PrimTabVerts = via_render_tab_verts; + tnl->Driver.Render.PrimTabElts = via_render_tab_elts; + tnl->Driver.Render.ClippedLine = viaRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly; + } + } +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +static const GLenum reducedPrim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + + +static void emit_all_state(viaContextPtr vmesa) +{ + GLcontext *ctx = vmesa->glCtx; + GLuint *vb = viaCheckDma(vmesa, 0x110); + GLuint i = 0; + GLuint j = 0; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = ((HC_SubA_HEnable << 24) | vmesa->regEnable); + *vb++ = ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL); + *vb++ = ((HC_SubA_HROP << 24) | vmesa->regHROP); + i += 5; + + if (vmesa->hasDepth && vmesa->hasStencil) { + GLuint pitch, format, offset; + + format = HC_HZWBFM_24; + + offset = vmesa->depth.offset; + pitch = vmesa->depth.pitch; + + *vb++ = ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF)); + + *vb++ = ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24)); + *vb++ = ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK | + format | pitch); + *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD); + /* set stencil */ + *vb++ = ((HC_SubA_HSTREF << 24) | vmesa->regHSTREF); + *vb++ = ((HC_SubA_HSTMD << 24) | vmesa->regHSTMD); + + i += 6; + } + else if (vmesa->hasDepth) { + GLuint pitch, format, offset; + + if (vmesa->depthBits == 16) { + /* We haven't support 16bit depth yet */ + format = HC_HZWBFM_16; + /*format = HC_HZWBFM_32;*/ +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "z format = 16\n"); +#endif + } + else { + format = HC_HZWBFM_32; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "z format = 32\n"); +#endif + } + + + offset = vmesa->depth.offset; + pitch = vmesa->depth.pitch; + + *vb++ = ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF)); + + *vb++ = ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24)); + *vb++ = ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK | + format | pitch); + *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD); + i += 4; + } + else if (vmesa->hasStencil) { + GLuint pitch, format, offset; + + format = HC_HZWBFM_24; + + offset = vmesa->depth.offset; + pitch = vmesa->depth.pitch; + + *vb++ = ((HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF)); + + *vb++ = ((HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24)); + *vb++ = ((HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK | + format | pitch); + *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD); + /* set stencil */ + *vb++ = ((HC_SubA_HSTREF << 24) | vmesa->regHSTREF); + *vb++ = ((HC_SubA_HSTMD << 24) | vmesa->regHSTMD); + + i += 6; + } + + if (ctx->Color.AlphaEnabled) { + *vb++ = ((HC_SubA_HATMD << 24) | vmesa->regHATMD); + i++; + } + + if (ctx->Color.BlendEnabled) { + *vb++ = ((HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat); + *vb++ = ((HC_SubA_HABLCop << 24) | vmesa->regHABLCop); + *vb++ = ((HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat); + *vb++ = ((HC_SubA_HABLAop << 24) | vmesa->regHABLAop); + *vb++ = ((HC_SubA_HABLRCa << 24) | vmesa->regHABLRCa); + *vb++ = ((HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa); + *vb++ = ((HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias); + *vb++ = ((HC_SubA_HABLRCb << 24) | vmesa->regHABLRCb); + *vb++ = ((HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb); + *vb++ = ((HC_SubA_HABLRAa << 24) | vmesa->regHABLRAa); + *vb++ = ((HC_SubA_HABLRAb << 24) | vmesa->regHABLRAb); + i += 11; + } + + if (ctx->Fog.Enabled) { + *vb++ = ((HC_SubA_HFogLF << 24) | vmesa->regHFogLF); + *vb++ = ((HC_SubA_HFogCL << 24) | vmesa->regHFogCL); + *vb++ = ((HC_SubA_HFogCH << 24) | vmesa->regHFogCH); + i += 3; + } + + if (ctx->Line.StippleFlag) { + *vb++ = ((HC_SubA_HLP << 24) | ctx->Line.StipplePattern); + *vb++ = ((HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor); + } + else { + *vb++ = ((HC_SubA_HLP << 24) | 0xFFFF); + *vb++ = ((HC_SubA_HLPRF << 24) | 0x1); + } + + i += 2; + + *vb++ = ((HC_SubA_HPixGC << 24) | 0x0); + i++; + + if (i & 0x1) { + *vb++ = HC_DUMMY; + i++; + } + + if (ctx->Texture.Unit[0]._ReallyEnabled) { + + struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0]; + struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1]; + + { + viaTextureObjectPtr t = (viaTextureObjectPtr)texUnit0->_Current->DriverData; + GLuint nDummyValue = 0; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (HC_SubType_TexGeneral << 24); + + if (ctx->Texture.Unit[1]._ReallyEnabled) { +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "multi texture\n"); +#endif + nDummyValue = (HC_SubA_HTXSMD << 24) | (1 << 3); + + if (t && t->needClearCache) { + *vb++ = nDummyValue | HC_HTXCHCLR_MASK; + *vb++ = nDummyValue; + } + else { + *vb++ = nDummyValue; + *vb++ = nDummyValue; + } + } + else { +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "single texture\n"); +#endif + nDummyValue = (HC_SubA_HTXSMD << 24) | 0; + + if (t && t->needClearCache) { + *vb++ = nDummyValue | HC_HTXCHCLR_MASK; + *vb++ = nDummyValue; + } + else { + *vb++ = nDummyValue; + *vb++ = nDummyValue; + } + } + *vb++ = HC_HEADER2; + *vb++ = HC_ParaType_NotTex << 16; + *vb++ = (HC_SubA_HEnable << 24) | vmesa->regEnable; + *vb++ = (HC_SubA_HEnable << 24) | vmesa->regEnable; + i += 8; + } + + if (texUnit0->Enabled) { + struct gl_texture_object *texObj = texUnit0->_Current; + viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData; + GLuint numLevels = t->lastLevel - t->firstLevel + 1; + GLuint nDummyValue = 0; +#ifdef DEBUG + if (VIA_DEBUG) { + fprintf(stderr, "texture0 enabled\n"); + fprintf(stderr, "texture level %d\n", t->actualLevel); + } +#endif + if (numLevels == 8) { + nDummyValue = t->regTexFM; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (0 << 24); + *vb++ = t->regTexFM; + *vb++ = (HC_SubA_HTXnL0OS << 24) | + ((t->actualLevel) << HC_HTXnLVmax_SHIFT); + *vb++ = t->regTexWidthLog2[0]; + *vb++ = t->regTexWidthLog2[1]; + *vb++ = t->regTexHeightLog2[0]; + *vb++ = t->regTexHeightLog2[1]; + *vb++ = t->regTexBaseH[0]; + *vb++ = t->regTexBaseH[1]; + *vb++ = t->regTexBaseH[2]; + + *vb++ = t->regTexBaseAndPitch[0].baseL; + *vb++ = t->regTexBaseAndPitch[0].pitchLog2; + *vb++ = t->regTexBaseAndPitch[1].baseL; + *vb++ = t->regTexBaseAndPitch[1].pitchLog2; + *vb++ = t->regTexBaseAndPitch[2].baseL; + *vb++ = t->regTexBaseAndPitch[2].pitchLog2; + *vb++ = t->regTexBaseAndPitch[3].baseL; + *vb++ = t->regTexBaseAndPitch[3].pitchLog2; + *vb++ = t->regTexBaseAndPitch[4].baseL; + *vb++ = t->regTexBaseAndPitch[4].pitchLog2; + *vb++ = t->regTexBaseAndPitch[5].baseL; + *vb++ = t->regTexBaseAndPitch[5].pitchLog2; + *vb++ = t->regTexBaseAndPitch[6].baseL; + *vb++ = t->regTexBaseAndPitch[6].pitchLog2; + *vb++ = t->regTexBaseAndPitch[7].baseL; + *vb++ = t->regTexBaseAndPitch[7].pitchLog2; + i += 27; + } + else if (numLevels > 1) { + nDummyValue = t->regTexFM; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (0 << 24); + *vb++ = t->regTexFM; + *vb++ = (HC_SubA_HTXnL0OS << 24) | + ((t->actualLevel) << HC_HTXnLVmax_SHIFT); + *vb++ = t->regTexWidthLog2[0]; + *vb++ = t->regTexHeightLog2[0]; + + if (numLevels > 6) { + *vb++ = t->regTexWidthLog2[1]; + *vb++ = t->regTexHeightLog2[1]; + i += 2; + } + + *vb++ = t->regTexBaseH[0]; + + if (numLevels > 3) { + *vb++ = t->regTexBaseH[1]; + i++; + } + if (numLevels > 6) { + *vb++ = t->regTexBaseH[2]; + i++; + } + if (numLevels > 9) { + *vb++ = t->regTexBaseH[3]; + i++; + } + + i += 7; + + for (j = 0; j < numLevels; j++) { + *vb++ = t->regTexBaseAndPitch[j].baseL; + *vb++ = t->regTexBaseAndPitch[j].pitchLog2; + i += 2; + } + } + else { + nDummyValue = t->regTexFM; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (0 << 24); + *vb++ = t->regTexFM; + *vb++ = (HC_SubA_HTXnL0OS << 24) | + ((t->actualLevel) << HC_HTXnLVmax_SHIFT); + *vb++ = t->regTexWidthLog2[0]; + *vb++ = t->regTexHeightLog2[0]; + *vb++ = t->regTexBaseH[0]; + *vb++ = t->regTexBaseAndPitch[0].baseL; + *vb++ = t->regTexBaseAndPitch[0].pitchLog2; + i += 9; + } + + *vb++ = (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB_0; + *vb++ = (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD_0; + *vb++ = (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat_0; + *vb++ = (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop_0; + *vb++ = (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog_0; + *vb++ = (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat_0; + *vb++ = (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb_0; + *vb++ = (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa_0; + *vb++ = (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog_0; + i += 9; + /*=* John Sheng [2003.7.18] texture combine */ + *vb++ = (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa_0; + *vb++ = (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc_0; + *vb++ = (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias_0; + i += 3; + + if (t->regTexFM == HC_HTXnFM_Index8) { + struct gl_color_table *table = &texObj->Palette; + GLfloat *tableF = (GLfloat *)table->Table; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Palette << 16) | (0 << 24); + i += 2; + for (j = 0; j < table->Size; j++) { + *vb++ = tableF[j]; + i++; + } + } + if (i & 0x1) { + *vb++ = HC_DUMMY; + i++; + } + } + + if (texUnit1->Enabled) { + struct gl_texture_object *texObj = texUnit1->_Current; + viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData; + GLuint numLevels = t->lastLevel - t->firstLevel + 1; + GLuint nDummyValue = 0; +#ifdef DEBUG + if (VIA_DEBUG) { + fprintf(stderr, "texture1 enabled\n"); + fprintf(stderr, "texture level %d\n", t->actualLevel); + } +#endif + if (numLevels == 8) { + nDummyValue = t->regTexFM; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (1 << 24); + *vb++ = t->regTexFM; + *vb++ = (HC_SubA_HTXnL0OS << 24) | + ((t->actualLevel) << HC_HTXnLVmax_SHIFT); + *vb++ = t->regTexWidthLog2[0]; + *vb++ = t->regTexWidthLog2[1]; + *vb++ = t->regTexHeightLog2[0]; + *vb++ = t->regTexHeightLog2[1]; + *vb++ = t->regTexBaseH[0]; + *vb++ = t->regTexBaseH[1]; + *vb++ = t->regTexBaseH[2]; + + *vb++ = t->regTexBaseAndPitch[0].baseL; + *vb++ = t->regTexBaseAndPitch[0].pitchLog2; + *vb++ = t->regTexBaseAndPitch[1].baseL; + *vb++ = t->regTexBaseAndPitch[1].pitchLog2; + *vb++ = t->regTexBaseAndPitch[2].baseL; + *vb++ = t->regTexBaseAndPitch[2].pitchLog2; + *vb++ = t->regTexBaseAndPitch[3].baseL; + *vb++ = t->regTexBaseAndPitch[3].pitchLog2; + *vb++ = t->regTexBaseAndPitch[4].baseL; + *vb++ = t->regTexBaseAndPitch[4].pitchLog2; + *vb++ = t->regTexBaseAndPitch[5].baseL; + *vb++ = t->regTexBaseAndPitch[5].pitchLog2; + *vb++ = t->regTexBaseAndPitch[6].baseL; + *vb++ = t->regTexBaseAndPitch[6].pitchLog2; + *vb++ = t->regTexBaseAndPitch[7].baseL; + *vb++ = t->regTexBaseAndPitch[7].pitchLog2; + i += 27; + } + else if (numLevels > 1) { + nDummyValue = t->regTexFM; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (1 << 24); + *vb++ = t->regTexFM; + *vb++ = (HC_SubA_HTXnL0OS << 24) | + ((t->actualLevel) << HC_HTXnLVmax_SHIFT); + *vb++ = t->regTexWidthLog2[0]; + *vb++ = t->regTexHeightLog2[0]; + + if (numLevels > 6) { + *vb++ = t->regTexWidthLog2[1]; + *vb++ = t->regTexHeightLog2[1]; + i += 2; + } + + *vb++ = t->regTexBaseH[0]; + + if (numLevels > 3) { + *vb++ = t->regTexBaseH[1]; + i++; + } + if (numLevels > 6) { + *vb++ = t->regTexBaseH[2]; + i++; + } + if (numLevels > 9) { + *vb++ = t->regTexBaseH[3]; + i++; + } + + i += 7; + + for (j = 0; j < numLevels; j++) { + *vb++ = t->regTexBaseAndPitch[j].baseL; + *vb++ = t->regTexBaseAndPitch[j].pitchLog2; + i += 2; + } + } + else { + nDummyValue = t->regTexFM; + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Tex << 16) | (1 << 24); + *vb++ = t->regTexFM; + *vb++ = (HC_SubA_HTXnL0OS << 24) | + ((t->actualLevel) << HC_HTXnLVmax_SHIFT); + *vb++ = t->regTexWidthLog2[0]; + *vb++ = t->regTexHeightLog2[0]; + *vb++ = t->regTexBaseH[0]; + *vb++ = t->regTexBaseAndPitch[0].baseL; + *vb++ = t->regTexBaseAndPitch[0].pitchLog2; + i += 9; + } + + *vb++ = (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB_1; + *vb++ = (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD_1; + *vb++ = (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat_1; + *vb++ = (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop_1; + *vb++ = (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog_1; + *vb++ = (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat_1; + *vb++ = (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb_1; + *vb++ = (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa_1; + *vb++ = (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog_1; + i += 9; + + if (t->regTexFM == HC_HTXnFM_Index8) { + struct gl_color_table *table = &texObj->Palette; + GLfloat *tableF = (GLfloat *)table->Table; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_Palette << 16) | (1 << 24); + i += 2; + for (j = 0; j < table->Size; j++) { + *vb++ = tableF[j]; + i++; + } + } + if (i & 0x1) { + *vb++ = HC_DUMMY; + i++; + } + } + } + + + if (ctx->Polygon.StippleFlag) { + GLuint *stipple = &ctx->PolygonStipple[0]; + + *vb++ = HC_HEADER2; + *vb++ = ((HC_ParaType_Palette << 16) | (HC_SubType_Stipple << 24)); + + *vb++ = stipple[31]; + *vb++ = stipple[30]; + *vb++ = stipple[29]; + *vb++ = stipple[28]; + *vb++ = stipple[27]; + *vb++ = stipple[26]; + *vb++ = stipple[25]; + *vb++ = stipple[24]; + *vb++ = stipple[23]; + *vb++ = stipple[22]; + *vb++ = stipple[21]; + *vb++ = stipple[20]; + *vb++ = stipple[19]; + *vb++ = stipple[18]; + *vb++ = stipple[17]; + *vb++ = stipple[16]; + *vb++ = stipple[15]; + *vb++ = stipple[14]; + *vb++ = stipple[13]; + *vb++ = stipple[12]; + *vb++ = stipple[11]; + *vb++ = stipple[10]; + *vb++ = stipple[9]; + *vb++ = stipple[8]; + *vb++ = stipple[7]; + *vb++ = stipple[6]; + *vb++ = stipple[5]; + *vb++ = stipple[4]; + *vb++ = stipple[3]; + *vb++ = stipple[2]; + *vb++ = stipple[1]; + *vb++ = stipple[0]; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = ((HC_SubA_HSPXYOS << 24) | (0x20 - (vmesa->driDrawable->h & 0x1F))); + *vb++ = ((HC_SubA_HSPXYOS << 24) | (0x20 - (vmesa->driDrawable->h & 0x1F))); + i += 38; + } + + vmesa->dmaLow += (i << 2); + + vmesa->dirty = 0; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +static void emit_partial_state(viaContextPtr vmesa) +{ + GLcontext *ctx = vmesa->glCtx; + GLuint dirty = vmesa->dirty; + GLuint *vb = viaCheckDma(vmesa, 0x110); + GLuint i = 0; + +#ifdef DEBUG + if( VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif + +#ifdef PERFORMANCE_MEASURE + if (VIA_PERFORMANCE) P_M; +#endif + vb = vb; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = ((HC_SubA_HEnable << 24) | vmesa->regEnable); + *vb++ = ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL); + *vb++ = ((HC_SubA_HROP << 24) | vmesa->regHROP); + i += 5; + + if (dirty & VIA_UPLOAD_DESTBUFFER) { + } + + if (dirty & VIA_UPLOAD_DEPTHBUFFER) { + } + + if (dirty * VIA_UPLOAD_DEPTH) { + *vb++ = ((HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD); + i++; + } + + if (dirty * VIA_UPLOAD_ALPHATEST) { + *vb++ = ((HC_SubA_HATMD << 24) | vmesa->regHATMD); + i++; + } + + + if (dirty & VIA_UPLOAD_BLEND) { + *vb++ = ((HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat); + *vb++ = ((HC_SubA_HABLCop << 24) | vmesa->regHABLCop); + *vb++ = ((HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat); + *vb++ = ((HC_SubA_HABLAop << 24) | vmesa->regHABLAop); + *vb++ = ((HC_SubA_HABLRCa << 24) | vmesa->regHABLRCa); + *vb++ = ((HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa); + *vb++ = ((HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias); + *vb++ = ((HC_SubA_HABLRCb << 24) | vmesa->regHABLRCb); + *vb++ = ((HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb); + *vb++ = ((HC_SubA_HABLRAa << 24) | vmesa->regHABLRAa); + *vb++ = ((HC_SubA_HABLRAb << 24) | vmesa->regHABLRAb); + i += 11; + } + + if (dirty & VIA_UPLOAD_FOG) { + *vb++ = ((HC_SubA_HFogLF << 24) | vmesa->regHFogLF); + *vb++ = ((HC_SubA_HFogCL << 24) | vmesa->regHFogCL); + *vb++ = ((HC_SubA_HFogCH << 24) | vmesa->regHFogCH); + i += 3; + } + + if (dirty & VIA_UPLOAD_LINESTIPPLE) { + *vb++ = ((HC_SubA_HLP << 24) | ctx->Line.StipplePattern); + *vb++ = ((HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor); + } + else { + *vb++ = ((HC_SubA_HLP << 24) | 0xFFFF); + *vb++ = ((HC_SubA_HLPRF << 24) | 0x1); + } + i += 2; + + *vb++ = ((HC_SubA_HPixGC << 24) | 0x0); + i++; + + if (i & 0x1) { + *vb++ = HC_DUMMY; + i++; + } + + if (dirty & VIA_UPLOAD_TEXTURE) { + + } + + if (dirty & VIA_UPLOAD_POLYGONSTIPPLE) { + + } + + vmesa->dmaLow += (i << 2); + + vmesa->dirty = 0; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + +/* Determine the rasterized primitive when not drawing unfilled + * polygons. + * + * Used only for the default render stage which always decomposes + * primitives to trianges/lines/points. For the accelerated stage, + * which renders strips as strips, the equivalent calculations are + * performed in via_render.c. + */ +static void viaRenderPrimitive(GLcontext *ctx, GLenum prim) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); + GLuint rprim = reducedPrim[prim]; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif + vmesa->renderPrimitive = prim; + viaRasterPrimitive(ctx, rprim, rprim); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +static void viaRunPipeline(GLcontext *ctx) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); + + if (VIA_DEBUG) fprintf(stderr, "newState = %x\n", vmesa->newState); +#endif + + if (vmesa->newState) { + if (vmesa->newState & _NEW_TEXTURE) + viaUpdateTextureState(ctx); /* may modify vmesa->newState */ + + viaChooseVertexState(ctx); + viaChooseRenderState(ctx); + vmesa->newState = 0; + } + + if (vmesa->needUploadAllState) + emit_all_state(vmesa); + else + emit_partial_state(vmesa); + + _tnl_run_pipeline(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +static void viaRenderStart(GLcontext *ctx) +{ +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif + + /* Check for projective texturing. Make sure all texcoord + * pointers point to something. (fix in mesa?) + */ + viaCheckTexSizes(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +static void viaRenderFinish(GLcontext *ctx) +{ +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); +#endif + if (VIA_CONTEXT(ctx)->renderIndex & VIA_FALLBACK_BIT) + _swrast_flush(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void viaRasterPrimitive(GLcontext *ctx, + GLenum rprim, + GLuint hwprim) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); + GLuint *vb = viaCheckDma(vmesa, 32); + GLuint regCmdB; +#ifdef DEBUG + if (VIA_DEBUG) { + fprintf(stderr, "%s - in\n", __FUNCTION__); + fprintf(stderr, "hwprim = %x\n", hwprim); + } +#endif + /*=* [DBG] exy : fix wireframe + clipping error *=*/ + if (((rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)))) { + hwprim = GL_LINES; + } + + if (RasterCounter > 0) { + +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "enter twice:%d\n",RasterCounter); +#endif + RasterCounter++; + return; + } + RasterCounter++; + + vmesa->primitiveRendered = GL_FALSE; + regCmdB = vmesa->regCmdB; + + switch (hwprim) { + case GL_POINTS: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Points\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Point | HC_HVCycle_Full; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatA; + break; + case GL_LINES: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Lines\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Line | HC_HVCycle_Full; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatB; + break; + case GL_LINE_LOOP: + case GL_LINE_STRIP: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Line Loop / Line Strip\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Line | HC_HVCycle_AFP | + HC_HVCycle_AB | HC_HVCycle_NewB; + regCmdB |= HC_HVCycle_AB | HC_HVCycle_NewB | HC_HLPrst_MASK; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatB; + break; + case GL_TRIANGLES: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Triangles\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_Full; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatC; + break; + case GL_TRIANGLE_STRIP: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Triangle Strip\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_AFP | + HC_HVCycle_AC | HC_HVCycle_BB | HC_HVCycle_NewC; + regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatB; + break; + case GL_TRIANGLE_FAN: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Triangle Fan\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_AFP | + HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC; + regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatC; + break; + case GL_QUADS: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "No HW Quads\n"); +#endif + return; + case GL_QUAD_STRIP: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "No HW Quad Strip\n"); +#endif + return; + case GL_POLYGON: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Polygon\n"); +#endif + vmesa->regCmdA_End = vmesa->regCmdA | HC_HPMType_Tri | HC_HVCycle_AFP | + HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC; + regCmdB |= HC_HVCycle_AA | HC_HVCycle_BC | HC_HVCycle_NewC; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatC; + break; + default: +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "Unknow\n"); +#endif + return; + } + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_NotTex << 16); + *vb++ = 0xCCCCCCCC; + *vb++ = 0xDDDDDDDD; + + *vb++ = HC_HEADER2; + *vb++ = (HC_ParaType_CmdVdata << 16); + *vb++ = regCmdB; + *vb++ = vmesa->regCmdA_End; + vmesa->dmaLow += 32; + + vmesa->reducedPrimitive = rprim; + vmesa->hwPrimitive = rprim; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + +void viaRasterPrimitiveFinish(GLcontext *ctx) +{ + viaContextPtr vmesa = VIA_CONTEXT(ctx); +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__); + + if (VIA_DEBUG) fprintf(stderr, "primitiveRendered = %x\n", vmesa->primitiveRendered); +#endif + if (RasterCounter > 1) { + RasterCounter--; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "finish enter twice: %d\n",RasterCounter); +#endif + return; + } + RasterCounter = 0; + + + if (vmesa->primitiveRendered) { + GLuint *vb = viaCheckDma(vmesa, 0); + GLuint cmdA = vmesa->regCmdA_End | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK; + + if ((vmesa->dmaLow & 0x1) || !vmesa->useAgp) { + *vb++ = cmdA ; + vmesa->dmaLow += 4; + } + else { + *vb++ = cmdA; + *vb++ = cmdA; + vmesa->dmaLow += 8; + } + } + else { + if (vmesa->dmaLow >= (32 + DMA_OFFSET)) + vmesa->dmaLow -= 32; + } + + if (0) viaFlushPrimsLocked(vmesa); + if (0) { + volatile GLuint *pnMMIOBase = vmesa->regMMIOBase; + volatile GLuint *pnEngBase = (volatile GLuint *)((GLuint)pnMMIOBase + 0x400); + int nStatus = *pnEngBase; + if (((nStatus & 0xFFFEFFFF) == 0x00020000)) { +#ifdef PERFORMANCE_MEASURE + idle++; +#endif + viaFlushPrims(vmesa); + } +#ifdef PERFORMANCE_MEASURE + else { + busy++; + } +#endif + } +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__); +#endif +} + + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + + +void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = vmesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = vmesa->Fallback; +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__, + vmesa->Fallback, bit, mode); +#endif + + if (mode) { + vmesa->Fallback |= bit; + if (oldfallback == 0) { +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "ENTER FALLBACK\n"); +#endif + VIA_FIREVERTICES(vmesa); + _swsetup_Wakeup(ctx); + vmesa->renderIndex = ~0; + } + } + else { + vmesa->Fallback &= ~bit; + if (oldfallback == bit) { +#ifdef DEBUG + if (VIA_DEBUG) fprintf(stderr, "LEAVE FALLBACK\n"); +#endif + tnl->Driver.Render.Start = viaRenderStart; + tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive; + tnl->Driver.Render.Finish = viaRenderFinish; + tnl->Driver.Render.BuildVertices = viaBuildVertices; + vmesa->newState |= (_VIA_NEW_RENDERSTATE|_VIA_NEW_VERTEX); + } + } + +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void viaInitTriFuncs(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = viaRunPipeline; + tnl->Driver.Render.Start = viaRenderStart; + tnl->Driver.Render.Finish = viaRenderFinish; + tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = viaBuildVertices; +} |