/* * 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 #include #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->vertexSize; 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->vertexSize; 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->vertexSize; /*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->vertexSize; 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<vertexStrideShift)) #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->vertexSize == 4 ? 3 : 4); \ GLboolean havespec = (vmesa->vertexSize > 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->vertexStrideShift; \ 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->vertexSize; GLuint *vb = viaCheckDma(vmesa, (n - 2) * 3 * 4 * vertsize); GLubyte *vertptr = (GLubyte *)vmesa->verts; const GLuint vertshift = vmesa->vertexStrideShift; 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._EnabledUnits) { 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._EnabledUnits > 1) { #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; /*=* John Sheng [2003.6.20] fix pci *=*/ /*if (vmesa->dmaLow & 0x1) {*/ 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; }