From f4092abdf94af6a99aff944d6264bc1284e8bdd4 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Mon, 10 Oct 2011 17:43:39 +0200 Subject: Imported nx-X11-3.1.0-1.tar.gz Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository --- .../Mesa/src/mesa/drivers/dri/unichrome/via_tris.c | 1190 ++++++++++++++++++++ 1 file changed, 1190 insertions(+) create mode 100644 nx-X11/extras/Mesa/src/mesa/drivers/dri/unichrome/via_tris.c (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/unichrome/via_tris.c') diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/unichrome/via_tris.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/unichrome/via_tris.c new file mode 100644 index 000000000..9cb88ae23 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/unichrome/via_tris.c @@ -0,0 +1,1190 @@ +/* + * 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 "enums.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_span.h" +#include "via_ioctl.h" +#include "via_3d_reg.h" +#include "via_tex.h" + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ +#define LINE_FALLBACK (0) +#define POINT_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) + + +#if 0 +#define COPY_DWORDS(vb, vertsize, v) \ +do { \ + via_sse_memcpy(vb, v, vertsize * 4); \ + vb += vertsize; \ +} while (0) +#else +#if defined( USE_X86_ASM ) +#define COPY_DWORDS(vb, vertsize, v) \ + do { \ + int j; \ + 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(vb, vertsize, v) \ + do { \ + int j; \ + for (j = 0; j < vertsize; j++) \ + vb[j] = ((GLuint *)v)[j]; \ + vb += vertsize; \ + } while (0) +#endif +#endif + +static void via_draw_triangle(struct via_context *vmesa, + viaVertexPtr v0, + viaVertexPtr v1, + viaVertexPtr v2) +{ + GLuint vertsize = vmesa->vertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 3 * 4 * vertsize); + + COPY_DWORDS(vb, vertsize, v0); + COPY_DWORDS(vb, vertsize, v1); + COPY_DWORDS(vb, vertsize, v2); +} + + +static void via_draw_quad(struct via_context *vmesa, + viaVertexPtr v0, + viaVertexPtr v1, + viaVertexPtr v2, + viaVertexPtr v3) +{ + GLuint vertsize = vmesa->vertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 6 * 4 * vertsize); + + COPY_DWORDS(vb, vertsize, v0); + COPY_DWORDS(vb, vertsize, v1); + COPY_DWORDS(vb, vertsize, v3); + COPY_DWORDS(vb, vertsize, v1); + COPY_DWORDS(vb, vertsize, v2); + COPY_DWORDS(vb, vertsize, v3); +} + +static void via_draw_line(struct via_context *vmesa, + viaVertexPtr v0, + viaVertexPtr v1) +{ + GLuint vertsize = vmesa->vertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 2 * 4 * vertsize); + COPY_DWORDS(vb, vertsize, v0); + COPY_DWORDS(vb, vertsize, v1); +} + + +static void via_draw_point(struct via_context *vmesa, + viaVertexPtr v0) +{ + GLuint vertsize = vmesa->vertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 4 * vertsize); + COPY_DWORDS(vb, vertsize, v0); +} + + +/* Fallback drawing functions for the ptex hack. + */ +#define PTEX_VERTEX( tmp, vertex_size, v) \ +do { \ + GLuint j; \ + GLfloat rhw = 1.0 / v->f[vertex_size]; \ + for ( j = 0 ; j < vertex_size ; j++ ) \ + tmp.f[j] = v->f[j]; \ + tmp.f[3] *= v->f[vertex_size]; \ + tmp.f[vertex_size-2] *= rhw; \ + tmp.f[vertex_size-1] *= rhw; \ +} while (0) + +static void via_ptex_tri (struct via_context *vmesa, + viaVertexPtr v0, + viaVertexPtr v1, + viaVertexPtr v2) +{ + GLuint vertsize = vmesa->hwVertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 3*4*vertsize); + viaVertex tmp; + + PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp); + PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp); + PTEX_VERTEX(tmp, vertsize, v2); COPY_DWORDS(vb, vertsize, &tmp); +} + +static void via_ptex_line (struct via_context *vmesa, + viaVertexPtr v0, + viaVertexPtr v1) +{ + GLuint vertsize = vmesa->hwVertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 2*4*vertsize); + viaVertex tmp; + + PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp); + PTEX_VERTEX(tmp, vertsize, v1); COPY_DWORDS(vb, vertsize, &tmp); +} + +static void via_ptex_point (struct via_context *vmesa, + viaVertexPtr v0) +{ + GLuint vertsize = vmesa->hwVertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, 1*4*vertsize); + viaVertex tmp; + + PTEX_VERTEX(tmp, vertsize, v0); COPY_DWORDS(vb, vertsize, &tmp); +} + + + + + +/*********************************************************************** + * Macros for via_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI(a, b, c) \ + do { \ + 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 (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 (DO_FALLBACK) \ + vmesa->drawLine(vmesa, v0, v1); \ + else \ + via_draw_line(vmesa, v0, v1); \ + } while (0) + +#define POINT(v0) \ + do { \ + 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 { + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[VIA_MAX_TRIFUNC + 1]; + + +#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 vmesa->polygon_offset_scale +#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->vertexSize * sizeof(int))) + +#define VERT_SET_RGBA( v, c ) \ +do { \ + via_color_t *color = (via_color_t *)&((v)->ui[coloroffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] + +#define VERT_SET_SPEC( v, c ) \ +do { \ + if (specoffset) { \ + via_color_t *color = (via_color_t *)&((v)->ui[specoffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \ + } \ +} while (0) +#define VERT_COPY_SPEC( v0, v1 ) \ +do { \ + if (specoffset) { \ + v0->ub4[specoffset][0] = v1->ub4[specoffset][0]; \ + v0->ub4[specoffset][1] = v1->ub4[specoffset][1]; \ + v0->ub4[specoffset][2] = v1->ub4[specoffset][2]; \ + } \ +} while (0) + + +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] + + +#define LOCAL_VARS(n) \ + struct via_context *vmesa = VIA_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = vmesa->coloroffset; \ + GLuint specoffset = vmesa->specoffset; \ + (void)color; (void)spec; (void)coloroffset; (void)specoffset; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLenum hwPrim[GL_POLYGON + 2] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_POLYGON+1 +}; + + +#define RASTERIZE(x) viaRasterPrimitive( ctx, x, hwPrim[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 "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_OFFSET_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_UNFILLED_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_OFFSET_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (VIA_TWOSIDE_BIT|VIA_UNFILLED_BIT|VIA_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_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 "tnl_dd/t_dd_tritmp.h" + + +/* Catchall case for flat, separate specular triangles (via has flat + * diffuse shading, but always does specular color with gouraud). + */ +#undef DO_FALLBACK +#undef DO_OFFSET +#undef DO_UNFILLED +#undef DO_TWOSIDE +#undef DO_FLAT +#define DO_FALLBACK (0) +#define DO_OFFSET (ctx->_TriangleCaps & DD_TRI_OFFSET) +#define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define DO_TWOSIDE (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) +#define DO_FLAT 1 +#define TAG(x) x##_flat_specular +#define IND VIA_MAX_TRIFUNC +#include "tnl_dd/t_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(); + + init_flat_specular(); /* special! */ +} + + +/*********************************************************************** + * 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(struct via_context *vmesa, + viaVertex *v0, + viaVertex *v1, + viaVertex *v2) +{ + GLcontext *ctx = vmesa->glCtx; + SWvertex v[3]; + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + _swsetup_Translate(ctx, v2, &v[2]); + viaSpanRenderStart( ctx ); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); + viaSpanRenderFinish( ctx ); +} + + +static void +via_fallback_line(struct via_context *vmesa, + viaVertex *v0, + viaVertex *v1) +{ + GLcontext *ctx = vmesa->glCtx; + SWvertex v[2]; + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + viaSpanRenderStart( ctx ); + _swrast_Line(ctx, &v[0], &v[1]); + viaSpanRenderFinish( ctx ); +} + + +static void +via_fallback_point(struct via_context *vmesa, + viaVertex *v0) +{ + GLcontext *ctx = vmesa->glCtx; + SWvertex v[1]; + _swsetup_Translate(ctx, v0, &v[0]); + viaSpanRenderStart( ctx ); + _swrast_Point(ctx, &v[0]); + viaSpanRenderFinish( ctx ); +} + +static void viaResetLineStipple( GLcontext *ctx ) +{ + struct via_context *vmesa = VIA_CONTEXT(ctx); + vmesa->regCmdB |= HC_HLPrst_MASK; +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ +#define IND 0 +#define V(x) (viaVertex *)(vertptr + ((x) * vertsize * sizeof(int))) +#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) 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, hwPrim[x]) +#undef LOCAL_VARS +#define LOCAL_VARS \ + struct via_context *vmesa = VIA_CONTEXT(ctx); \ + GLubyte *vertptr = (GLubyte *)vmesa->verts; \ + const GLuint vertsize = vmesa->vertexSize; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) elt; (void) stipple; +#define RESET_STIPPLE if ( stipple ) viaResetLineStipple( ctx ); +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) via_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) via_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#undef NEED_EDGEFLAG_SETUP +#undef EDGEFLAG_GET +#undef EDGEFLAG_SET +#undef RESET_OCCLUSION + + +/**********************************************************************/ +/* 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; + GLuint prim = VIA_CONTEXT(ctx)->renderPrimitive; + + /* 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; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON && + prim != GL_POLYGON + 1) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +} + +static void viaRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line(ctx, ii, jj); +} + +static void viaFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts, + GLuint n) +{ + struct via_context *vmesa = VIA_CONTEXT(ctx); + GLuint vertsize = vmesa->vertexSize; + GLuint *vb = viaExtendPrimitive(vmesa, (n - 2) * 3 * 4 * vertsize); + GLubyte *vertptr = (GLubyte *)vmesa->verts; + const GLuint *start = (const GLuint *)V(elts[0]); + int i; + + for (i = 2; i < n; i++) { + COPY_DWORDS(vb, vertsize, V(elts[i - 1])); + COPY_DWORDS(vb, vertsize, V(elts[i])); + COPY_DWORDS(vb, vertsize, start); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + + +#define _VIA_NEW_VERTEX (_NEW_TEXTURE | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _NEW_FOG) + +#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) + + +static void viaChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct via_context *vmesa = VIA_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (vmesa->ptexHack) { + vmesa->drawPoint = via_ptex_point; + vmesa->drawLine = via_ptex_line; + vmesa->drawTri = via_ptex_tri; + index |= VIA_FALLBACK_BIT; + } + else { + vmesa->drawPoint = via_draw_point; + vmesa->drawLine = via_draw_line; + vmesa->drawTri = via_draw_triangle; + } + + if (flags & (ANY_FALLBACK_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; + if (flags & ANY_FALLBACK_FLAGS) index |= VIA_FALLBACK_BIT; + + /* Hook in fallbacks for specific primitives. + */ + 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; + } + + + if ((flags & DD_SEPARATE_SPECULAR) && + ctx->Light.ShadeModel == GL_FLAT) { + index = VIA_MAX_TRIFUNC; /* flat specular */ + } + + 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; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = via_render_tab_verts; + tnl->Driver.Render.PrimTabElts = via_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly; + } + else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = viaRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly; + } + } +} + + +#define VIA_EMIT_TEX1 0x01 +#define VIA_EMIT_TEX0 0x02 +#define VIA_EMIT_PTEX0 0x04 +#define VIA_EMIT_RGBA 0x08 +#define VIA_EMIT_SPEC 0x10 +#define VIA_EMIT_FOG 0x20 +#define VIA_EMIT_W 0x40 + +#define EMIT_ATTR( ATTR, STYLE, INDEX, REGB ) \ +do { \ + vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = (ATTR); \ + vmesa->vertex_attrs[vmesa->vertex_attr_count].format = (STYLE); \ + vmesa->vertex_attr_count++; \ + setupIndex |= (INDEX); \ + regCmdB |= (REGB); \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + vmesa->vertex_attrs[vmesa->vertex_attr_count].attrib = 0; \ + vmesa->vertex_attrs[vmesa->vertex_attr_count].format = EMIT_PAD; \ + vmesa->vertex_attrs[vmesa->vertex_attr_count].offset = (N); \ + vmesa->vertex_attr_count++; \ +} while (0) + + + +static void viaChooseVertexState( GLcontext *ctx ) +{ + struct via_context *vmesa = VIA_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint index = tnl->render_inputs; + GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z; + GLuint setupIndex = 0; + + vmesa->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if (index & (_TNL_BITS_TEX_ANY|_TNL_BIT_FOG)) { + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W ); + vmesa->coloroffset = 4; + } + else { + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); + vmesa->coloroffset = 3; + } + + /* t_context.c always includes a diffuse color */ + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA, + HC_HVPMSK_Cd ); + + vmesa->specoffset = 0; + if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) { + if ((index & _TNL_BIT_COLOR1)) { + vmesa->specoffset = vmesa->coloroffset + 1; + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC, + HC_HVPMSK_Cs ); + } + else + EMIT_PAD( 3 ); + + if ((index & _TNL_BIT_FOG)) + EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs ); + else + EMIT_PAD( 1 ); + } + + if (index & _TNL_BIT_TEX(0)) { + if (vmesa->ptexHack) + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0, + (HC_HVPMSK_S | HC_HVPMSK_T) ); + else + EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0, + (HC_HVPMSK_S | HC_HVPMSK_T) ); + } + + if (index & _TNL_BIT_TEX(1)) { + EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1, + (HC_HVPMSK_S | HC_HVPMSK_T) ); + } + + if (setupIndex != vmesa->setupIndex) { + vmesa->vertexSize = _tnl_install_attrs( ctx, + vmesa->vertex_attrs, + vmesa->vertex_attr_count, + vmesa->ViewportMatrix.m, 0 ); + vmesa->vertexSize >>= 2; + vmesa->setupIndex = setupIndex; + vmesa->regCmdB &= ~HC_HVPMSK_MASK; + vmesa->regCmdB |= regCmdB; + + if (vmesa->ptexHack) + vmesa->hwVertexSize = vmesa->vertexSize - 1; + else + vmesa->hwVertexSize = vmesa->vertexSize; + } +} + + + + +/* Check if projective texture coordinates are used and if we can fake + * them. Fallback to swrast if we can't. Returns GL_TRUE if projective + * texture coordinates must be faked, GL_FALSE otherwise. + */ +static GLboolean viaCheckPTexHack( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint index = tnl->render_inputs; + GLboolean fallback = GL_FALSE; + GLboolean ptexHack = GL_FALSE; + + if (index & _TNL_BIT_TEX(0) && VB->TexCoordPtr[0]->size == 4) { + if ((index & _TNL_BITS_TEX_ANY) == _TNL_BIT_TEX(0)) + ptexHack = GL_TRUE; + else + fallback = GL_TRUE; + } + if ((index & _TNL_BIT_TEX(1)) && VB->TexCoordPtr[1]->size == 4) + fallback = GL_TRUE; + + FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback); + return ptexHack; +} + + + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void viaRenderStart(GLcontext *ctx) +{ + struct via_context *vmesa = VIA_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + { + GLboolean ptexHack = viaCheckPTexHack( ctx ); + if (ptexHack != vmesa->ptexHack) { + vmesa->ptexHack = ptexHack; + vmesa->newRenderState |= _VIA_NEW_RENDERSTATE; + } + } + + if (vmesa->newState) { + vmesa->newRenderState |= vmesa->newState; + viaValidateState( ctx ); + } + + if (vmesa->Fallback) { + tnl->Driver.Render.Start(ctx); + return; + } + + if (vmesa->newRenderState) { + viaChooseVertexState(ctx); + viaChooseRenderState(ctx); + vmesa->newRenderState = 0; + } + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; +} + +static void viaRenderFinish(GLcontext *ctx) +{ + VIA_FINISH_PRIM(VIA_CONTEXT(ctx)); +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void viaRasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLenum hwprim) +{ + struct via_context *vmesa = VIA_CONTEXT(ctx); + GLuint regCmdB; + RING_VARS; + + if (VIA_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: %s/%s/%s\n", + __FUNCTION__, _mesa_lookup_enum_by_nr(glprim), + _mesa_lookup_enum_by_nr(hwprim), + _mesa_lookup_enum_by_nr(ctx->Light.ShadeModel)); + + assert (!vmesa->newState); + + vmesa->renderPrimitive = glprim; + + if (hwprim != vmesa->hwPrimitive || + ctx->Light.ShadeModel != vmesa->hwShadeModel) { + + VIA_FINISH_PRIM(vmesa); + + /* Ensure no wrapping inside this function */ + viaCheckDma( vmesa, 1024 ); + + if (vmesa->newEmitState) { + viaEmitState(vmesa); + } + + vmesa->regCmdA_End = HC_ACMD_HCmdA; + + if (ctx->Light.ShadeModel == GL_SMOOTH) { + vmesa->regCmdA_End |= HC_HShading_Gouraud; + } + + vmesa->hwShadeModel = ctx->Light.ShadeModel; + regCmdB = vmesa->regCmdB; + + switch (hwprim) { + case GL_POINTS: + vmesa->regCmdA_End |= HC_HPMType_Point | HC_HVCycle_Full; + vmesa->regCmdA_End |= HC_HShading_Gouraud; /* always Gouraud + shade points?!? */ + break; + case GL_LINES: + vmesa->regCmdA_End |= HC_HPMType_Line | HC_HVCycle_Full; + regCmdB |= HC_HLPrst_MASK; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatB; + break; + case GL_LINE_LOOP: + case GL_LINE_STRIP: + vmesa->regCmdA_End |= 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: + vmesa->regCmdA_End |= HC_HPMType_Tri | HC_HVCycle_Full; + if (ctx->Light.ShadeModel == GL_FLAT) + vmesa->regCmdA_End |= HC_HShading_FlatC; + break; + case GL_TRIANGLE_STRIP: + vmesa->regCmdA_End |= 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_FlatC; + break; + case GL_TRIANGLE_FAN: + vmesa->regCmdA_End |= 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: + abort(); + return; + case GL_QUAD_STRIP: + abort(); + return; + case GL_POLYGON: + vmesa->regCmdA_End |= 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: + abort(); + return; + } + +/* assert((vmesa->dmaLow & 0x4) == 0); */ + + if (vmesa->dmaCliprectAddr == ~0) { + if (VIA_DEBUG & DEBUG_DMA) + fprintf(stderr, "reserve cliprect space at %x\n", vmesa->dmaLow); + vmesa->dmaCliprectAddr = vmesa->dmaLow; + BEGIN_RING(8); + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_NotTex << 16) ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xCCCCCCCC ); + ADVANCE_RING(); + } + + assert(vmesa->dmaLastPrim == 0); + + BEGIN_RING(8); + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_NotTex << 16) ); + OUT_RING( 0xCCCCCCCC ); + OUT_RING( 0xDDDDDDDD ); + + OUT_RING( HC_HEADER2 ); + OUT_RING( (HC_ParaType_CmdVdata << 16) ); + OUT_RING( regCmdB ); + OUT_RING( vmesa->regCmdA_End ); + ADVANCE_RING(); + + vmesa->hwPrimitive = hwprim; + vmesa->dmaLastPrim = vmesa->dmaLow; + } + else { + assert(!vmesa->newEmitState); + } +} + +/* Callback for mesa: + */ +static void viaRenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + viaRasterPrimitive( ctx, prim, hwPrim[prim] ); +} + + +void viaFinishPrimitive(struct via_context *vmesa) +{ + if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS)) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (!vmesa->dmaLastPrim || vmesa->dmaCliprectAddr == ~0) { + assert(0); + } + else if (vmesa->dmaLow != vmesa->dmaLastPrim) { + GLuint cmdA = (vmesa->regCmdA_End | HC_HPLEND_MASK | + HC_HPMValidN_MASK | HC_HE3Fire_MASK); + RING_VARS; + + vmesa->dmaLastPrim = 0; + + /* KW: modified 0x1 to 0x4 below: + */ + if ((vmesa->dmaLow & 0x4) || !vmesa->useAgp) { + BEGIN_RING_NOCHECK( 1 ); + OUT_RING( cmdA ); + ADVANCE_RING(); + } + else { + BEGIN_RING_NOCHECK( 2 ); + OUT_RING( cmdA ); + OUT_RING( cmdA ); + ADVANCE_RING(); + } + + if (vmesa->dmaLow > VIA_DMA_HIGHWATER) + viaFlushDma( vmesa ); + } + else { + if (VIA_DEBUG & (DEBUG_DMA|DEBUG_PRIMS)) + fprintf(stderr, "remove empty primitive\n"); + + /* Remove the primitive header: + */ + vmesa->dmaLastPrim = 0; + vmesa->dmaLow -= 8 * sizeof(GLuint); + + /* Maybe remove the cliprect as well: + */ + if (vmesa->dmaCliprectAddr == vmesa->dmaLow - 8 * sizeof(GLuint)) { + vmesa->dmaLow -= 8 * sizeof(GLuint); + vmesa->dmaCliprectAddr = ~0; + } + } + + vmesa->renderPrimitive = GL_POLYGON + 1; + vmesa->hwPrimitive = GL_POLYGON + 1; + vmesa->dmaLastPrim = 0; +} + + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + + +void viaFallback(struct via_context *vmesa, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = vmesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = vmesa->Fallback; + + if (mode) { + vmesa->Fallback |= bit; + if (oldfallback == 0) { + VIA_FLUSH_DMA(vmesa); + + if (VIA_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "ENTER FALLBACK %x\n", bit); + + _swsetup_Wakeup(ctx); + vmesa->renderIndex = ~0; + } + } + else { + vmesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + + if (VIA_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "LEAVE FALLBACK %x\n", bit); + + tnl->Driver.Render.Start = viaRenderStart; + tnl->Driver.Render.PrimitiveNotify = viaRenderPrimitive; + tnl->Driver.Render.Finish = viaRenderFinish; + + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.ResetLineStipple = viaResetLineStipple; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + _tnl_install_attrs( ctx, + vmesa->vertex_attrs, + vmesa->vertex_attr_count, + vmesa->ViewportMatrix.m, 0 ); + + vmesa->newState |= (_VIA_NEW_RENDERSTATE|_VIA_NEW_VERTEX); + } + } +} + +static void viaRunPipeline( GLcontext *ctx ) +{ + struct via_context *vmesa = VIA_CONTEXT(ctx); + + if (vmesa->newState) { + vmesa->newRenderState |= vmesa->newState; + viaValidateState( ctx ); + } + + _tnl_run_pipeline( ctx ); +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void viaInitTriFuncs(GLcontext *ctx) +{ + struct via_context *vmesa = VIA_CONTEXT(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 = viaResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) ); + + vmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; + +} -- cgit v1.2.3