diff options
author | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-10-10 17:43:39 +0200 |
commit | f4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch) | |
tree | 2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/extras/Mesa/src/mesa/drivers/dri/sis/sis_tris.c | |
parent | a840692edc9c6d19cd7c057f68e39c7d95eb767d (diff) | |
download | nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2 nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip |
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz
Keywords:
Imported nx-X11-3.1.0-1.tar.gz
into Git repository
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/sis/sis_tris.c')
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/dri/sis/sis_tris.c | 1071 |
1 files changed, 1071 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/sis/sis_tris.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/sis/sis_tris.c new file mode 100644 index 000000000..fb0fd1ac0 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/sis/sis_tris.c @@ -0,0 +1,1071 @@ +/* $XFree86*/ /* -*- c-basic-offset: 3 -*- */ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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 +on 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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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. + +**************************************************************************/ + +/* + * Authors: + * Sung-Ching Lin <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "macros.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "sis_context.h" +#include "sis_tris.h" +#include "sis_state.h" +#include "sis_lock.h" +#include "sis_span.h" +#include "sis_alloc.h" +#include "sis_tex.h" + +static const GLuint hw_prim[GL_POLYGON+1] = { + OP_3D_POINT_DRAW, /* GL_POINTS */ + OP_3D_LINE_DRAW, /* GL_LINES */ + OP_3D_LINE_DRAW, /* GL_LINE_LOOP */ + OP_3D_LINE_DRAW, /* GL_LINE_STRIP */ + OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLES */ + OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_STRIP */ + OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_FAN */ + OP_3D_TRIANGLE_DRAW, /* GL_QUADS */ + OP_3D_TRIANGLE_DRAW, /* GL_QUAD_STRIP */ + OP_3D_TRIANGLE_DRAW /* GL_POLYGON */ +}; + +static const GLuint hw_prim_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = { + OP_3D_FIRE_TSARGBa, + OP_3D_FIRE_TSARGBb, + OP_3D_FIRE_TSARGBc +}; + +static const GLuint hw_prim_mmio_shade[OP_3D_TRIANGLE_DRAW+1] = { + SHADE_FLAT_VertexA, + SHADE_FLAT_VertexB, + SHADE_FLAT_VertexC +}; + +static const GLuint hw_prim_agp_type[OP_3D_TRIANGLE_DRAW+1] = { + MASK_PsPointList, + MASK_PsLineList, + MASK_PsTriangleList +}; + +static const GLuint hw_prim_agp_shade[OP_3D_TRIANGLE_DRAW+1] = { + MASK_PsShadingFlatA, + MASK_PsShadingFlatB, + MASK_PsShadingFlatC +}; + +static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim ); +static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#define HAVE_QUADS 0 +#define HAVE_LINES 1 +#define HAVE_POINTS 1 +#define CTX_ARG sisContextPtr smesa +#define GET_VERTEX_DWORDS() smesa->vertex_size +#define ALLOC_VERTS( n, size ) sisAllocDmaLow( smesa, n * size * sizeof(int) ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + const char *vertptr = smesa->verts; +#define VERT(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int))) +#define VERTEX sisVertex +#undef TAG +#define TAG(x) sis_##x +#include "tnl_dd/t_dd_triemit.h" +#undef TAG +#undef LOCAL_VARS + +/*********************************************************************** + * Dispatch vertices to hardware through MMIO * + ***********************************************************************/ + +/* The ARGB write of the last vertex of the primitive fires the 3d engine, so + * save it until the end. + */ +#define SIS_MMIO_WRITE_VERTEX(_v, i, lastvert) \ +do { \ + GLuint __color, __i = 0; \ + MMIO(REG_3D_TSXa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSYa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSZa+(i)*0x30, _v->ui[__i++]); \ + if (SIS_STATES & VERT_W) \ + MMIO(REG_3D_TSWGa+(i)*0x30, _v->ui[__i++]); \ + __color = _v->ui[__i++]; \ + if (SIS_STATES & VERT_SPEC) \ + MMIO(REG_3D_TSFSa+(i)*0x30, _v->ui[__i++]); \ + if (SIS_STATES & VERT_UV0) { \ + MMIO(REG_3D_TSUAa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSVAa+(i)*0x30, _v->ui[__i++]); \ + } \ + if (SIS_STATES & VERT_UV1) { \ + MMIO(REG_3D_TSUBa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSVBa+(i)*0x30, _v->ui[__i++]); \ + } \ + if (lastvert || (SIS_STATES & VERT_SMOOTH)) \ + MMIO(REG_3D_TSARGBa+(i)*0x30, __color); \ +} while (0) + +#define MMIO_VERT_REG_COUNT 10 + +#define VERT_SMOOTH 0x01 +#define VERT_W 0x02 +#define VERT_SPEC 0x04 +#define VERT_UV0 0x08 +#define VERT_UV1 0x10 + +typedef void (*mmio_draw_func)(sisContextPtr smesa, char *verts); +static mmio_draw_func sis_tri_func_mmio[32]; +static mmio_draw_func sis_line_func_mmio[32]; +static mmio_draw_func sis_point_func_mmio[32]; + +#define SIS_STATES (0) +#define TAG(x) x##_none +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH) +#define TAG(x) x##_g +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W) +#define TAG(x) x##_w +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W) +#define TAG(x) x##_gw +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC) +#define TAG(x) x##_s +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC) +#define TAG(x) x##_gs +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC) +#define TAG(x) x##_ws +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC) +#define TAG(x) x##_gws +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV0) +#define TAG(x) x##_t0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_UV0) +#define TAG(x) x##_gt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV0) +#define TAG(x) x##_wt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0) +#define TAG(x) x##_gwt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV0) +#define TAG(x) x##_st0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_gst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_wst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_gwst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV1) +#define TAG(x) x##_t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_UV1) +#define TAG(x) x##_gt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV1) +#define TAG(x) x##_wt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV1) +#define TAG(x) x##_gwt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV1) +#define TAG(x) x##_st1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_gst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_wst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_gwst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV0 | VERT_UV1) +#define TAG(x) x##_t0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_wt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gwt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_st0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gst0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_wst0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gwst0t1 +#include "sis_tritmp.h" + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_tri( smesa, a, b, c ); \ + else \ + sis_triangle( smesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + smesa->draw_tri( smesa, a, b, d ); \ + smesa->draw_tri( smesa, b, c, d ); \ + } else \ + sis_quad( smesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_line( smesa, v0, v1 ); \ + else \ + sis_line( smesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_point( smesa, v0 ); \ + else \ + sis_point( smesa, v0 ); \ +} while (0) + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define SIS_OFFSET_BIT 0x01 +#define SIS_TWOSIDE_BIT 0x02 +#define SIS_UNFILLED_BIT 0x04 +#define SIS_FALLBACK_BIT 0x08 +#define SIS_MAX_TRIFUNC 0x10 + + +static struct { + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[SIS_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & SIS_FALLBACK_BIT) +#define DO_OFFSET (IND & SIS_OFFSET_BIT) +#define DO_UNFILLED (IND & SIS_UNFILLED_BIT) +#define DO_TWOSIDE (IND & SIS_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 sisVertex +#define TAB rast_tab + +#define DEPTH_SCALE smesa->depth_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) (smesa->verts + (e * smesa->vertex_size * sizeof(int))) + +#define VERT_SET_RGBA( v, c ) \ +do { \ + sis_color_t *color = (sis_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( v0, c ) \ +do { \ + if (havespec) { \ + UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \ + } \ +} while (0) +#define VERT_COPY_SPEC( v0, v1 ) \ +do { \ + if (havespec) { \ + v0->v.specular.red = v1->v.specular.red; \ + v0->v.specular.green = v1->v.specular.green; \ + v0->v.specular.blue = v1->v.specular.blue; \ + } \ +} 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 (havespec) spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx] + +#define LOCAL_VARS(n) \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (smesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (smesa->vertex_size == 4 ? 0 : 1); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (smesa->hw_primitive != hw_prim[x]) \ + sisRasterPrimitive( ctx, hw_prim[x] ) +#define RENDER_PRIMITIVE smesa->render_primitive +#define IND SIS_FALLBACK_BIT +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT|SIS_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_UNFILLED_BIT|SIS_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_UNFILLED_BIT|SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT|SIS_OFFSET_BIT|SIS_UNFILLED_BIT| \ + SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#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(); +} + + + +/*********************************************************************** + * 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 +sis_fallback_tri( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1, + sisVertex *v2 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[3]; + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + _swsetup_Translate( ctx, v2, &v[2] ); + sisSpanRenderStart( ctx ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); +} + + +static void +sis_fallback_line( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[2]; + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + sisSpanRenderStart( ctx ); + _swrast_Line( ctx, &v[0], &v[1] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); +} + + +static void +sis_fallback_point( sisContextPtr smesa, + sisVertex *v0 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[1]; + _swsetup_Translate( ctx, v0, &v[0] ); + sisSpanRenderStart( ctx ); + _swrast_Point( ctx, &v[0] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (sisVertex *)(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) sisRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + const GLuint vertsize = smesa->vertex_size; \ + const char *vertptr = (char *)smesa->verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) (x) +#define TAG(x) sis_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) sis_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH) +#define TRI_FALLBACK (DD_TRI_STIPPLE|DD_TRI_SMOOTH) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) +#define _SIS_NEW_RENDER_STATE (ANY_RASTER_FLAGS | ANY_FALLBACK_FLAGS) + +static void sisChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) { + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= SIS_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= SIS_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= SIS_UNFILLED_BIT; + } + + smesa->draw_point = sis_point; + smesa->draw_line = sis_line; + smesa->draw_tri = sis_triangle; + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) { + if (flags & POINT_FALLBACK) + smesa->draw_point = sis_fallback_point; + if (flags & LINE_FALLBACK) + smesa->draw_line = sis_fallback_line; + if (flags & TRI_FALLBACK) + smesa->draw_tri = sis_fallback_tri; + index |= SIS_FALLBACK_BIT; + } + } + + if (index != smesa->RenderIndex) { + smesa->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = 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 = sis_render_tab_verts; + tnl->Driver.Render.PrimTabElts = sis_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = sis_fast_clipped_poly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + } +} + +/**********************************************************************/ +/* Multipass rendering for front buffering */ +/**********************************************************************/ +static GLboolean multipass_cliprect( GLcontext *ctx, GLuint pass ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + + if (pass >= smesa->driDrawable->numClipRects) { + return GL_FALSE; + } else { + GLint x1, y1, x2, y2; + + x1 = smesa->driDrawable->pClipRects[pass].x1 - smesa->driDrawable->x; + y1 = smesa->driDrawable->pClipRects[pass].y1 - smesa->driDrawable->y; + x2 = smesa->driDrawable->pClipRects[pass].x2 - smesa->driDrawable->x; + y2 = smesa->driDrawable->pClipRects[pass].y2 - smesa->driDrawable->y; + + if (ctx->Scissor.Enabled) { + GLint scisy1 = Y_FLIP(ctx->Scissor.Y + ctx->Scissor.Height - 1); + GLint scisy2 = Y_FLIP(ctx->Scissor.Y); + + if (ctx->Scissor.X > x1) + x1 = ctx->Scissor.X; + if (scisy1 > y1) + y1 = scisy1; + if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2) + x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; + if (scisy2 < y2) + y2 = scisy2; + } + + MMIO(REG_3D_ClipTopBottom, y1 << 13 | y2); + MMIO(REG_3D_ClipLeftRight, x1 << 13 | x2); + /* Mark that we clobbered these registers */ + smesa->GlobalFlag |= GFLAG_CLIPPING; + return GL_TRUE; + } +} + + + +/**********************************************************************/ +/* Validate state at pipeline start */ +/**********************************************************************/ + +static void sisRunPipeline( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + + if (!smesa->Fallback && smesa->NewGLState) { + if (smesa->NewGLState & _NEW_TEXTURE) { + SIS_FIREVERTICES(smesa); + sisUpdateTextureState(ctx); + } + + if (smesa->NewGLState & _SIS_NEW_RENDER_STATE) + sisChooseRenderState( ctx ); + + smesa->NewGLState = 0; + } + + _tnl_run_pipeline( ctx ); + + /* XXX: If we put flushing in sis_state.c and friends, we can avoid this. + * Is it worth it? + */ + SIS_FIREVERTICES(smesa); +} + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + +/* This is called when Mesa switches between rendering triangle + * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc), + * and lines, points and bitmaps. + */ + +static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + if (smesa->hw_primitive != hwprim) { + SIS_FIREVERTICES(smesa); + smesa->hw_primitive = hwprim; + smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode); + smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand | + MASK_SetFirePosition | MASK_ShadingMode); + smesa->AGPParseSet |= hw_prim_agp_type[hwprim]; + smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim]; + if (ctx->Light.ShadeModel == GL_FLAT) { + smesa->AGPParseSet |= hw_prim_agp_shade[hwprim]; + smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim]; + } else { + smesa->AGPParseSet |= MASK_PsShadingSmooth; + smesa->dwPrimitiveSet |= SHADE_GOURAUD; + } + } +} + +static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + smesa->render_primitive = prim; + + if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + sisRasterPrimitive( ctx, hw_prim[prim] ); +} + +#define EMIT_ATTR( ATTR, STYLE) \ +do { \ + smesa->vertex_attrs[smesa->vertex_attr_count].attrib = (ATTR); \ + smesa->vertex_attrs[smesa->vertex_attr_count].format = (STYLE); \ + smesa->vertex_attr_count++; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + smesa->vertex_attrs[smesa->vertex_attr_count].attrib = 0; \ + smesa->vertex_attrs[smesa->vertex_attr_count].format = EMIT_PAD; \ + smesa->vertex_attrs[smesa->vertex_attr_count].offset = (N); \ + smesa->vertex_attr_count++; \ +} while (0) + +#define SIS_TCL_STATE_BITS \ + (_TNL_BITS_TEX_ANY | _TNL_BIT_COLOR1 | _TNL_BIT_FOG) + +static void sisRenderStart( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint index = tnl->render_inputs; + GLuint AGPParseSet = smesa->AGPParseSet; + GLboolean tex_fallback = GL_FALSE; + + if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT && + smesa->driDrawable->numClipRects != 0) + { + multipass_cliprect(ctx, 0); + if (smesa->driDrawable->numClipRects > 1) + tnl->Driver.Render.Multipass = multipass_cliprect; + else + tnl->Driver.Render.Multipass = NULL; + } else { + tnl->Driver.Render.Multipass = NULL; + } + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + smesa->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to build up a + * hardware vertex. + */ + + AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat); + AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE; + if (index & _TNL_BITS_TEX_ANY) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT); + AGPParseSet |= SiS_PS_HAS_W; + } else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT); + } + + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA); + + if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) { + AGPParseSet |= SiS_PS_HAS_SPECULAR; + + if (index & _TNL_BIT_COLOR1) { + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR); + } else { + EMIT_PAD(3); + } + + if (index & _TNL_BIT_FOG) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F); + else + EMIT_PAD(1); + } + + /* projective textures are not supported by the hardware */ + if (index & _TNL_BIT_TEX(0)) { + if (VB->TexCoordPtr[0]->size > 2) + tex_fallback = GL_TRUE; + EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F); + AGPParseSet |= SiS_PS_HAS_UV0; + } + if (index & _TNL_BIT_TEX(1)) { + if (VB->TexCoordPtr[1]->size > 2) + tex_fallback = GL_TRUE; + EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F); + AGPParseSet |= SiS_PS_HAS_UV1; + } + FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback); + + if (smesa->last_tcl_state != index) { + smesa->AGPParseSet = AGPParseSet; + + smesa->vertex_size = _tnl_install_attrs( ctx, smesa->vertex_attrs, + smesa->vertex_attr_count, smesa->hw_viewport, 0 ); + + smesa->vertex_size >>= 2; + smesa->AGPParseSet |= smesa->vertex_size << 28; + } +} + +static void sisRenderFinish( GLcontext *ctx ) +{ +} + +/**********************************************************************/ +/* AGP/PCI vertex submission */ +/**********************************************************************/ + +void +sisFlushPrimsLocked(sisContextPtr smesa) +{ + if (smesa->vb_cur == smesa->vb_last) + return; + + sisUpdateHWState(smesa->glCtx); + + if (smesa->using_agp) { + mWait3DCmdQueue(8); + mEndPrimitive(); + MMIO(REG_3D_AGPCmBase, (smesa->vb_last - smesa->vb) + + smesa->vb_agp_offset); + MMIO(REG_3D_AGPTtDwNum, ((smesa->vb_cur - smesa->vb_last) / 4) | + 0x50000000); + MMIO(REG_3D_ParsingSet, smesa->AGPParseSet); + MMIO(REG_3D_AGPCmFire, (GLint)(-1)); + mEndPrimitive(); + } else { + int mmio_index = 0, incr = 0; + void (*sis_emit_func)(sisContextPtr smesa, char *verts) = NULL; + + if (smesa->AGPParseSet & MASK_PsShadingSmooth) + mmio_index |= VERT_SMOOTH; + if (smesa->AGPParseSet & SiS_PS_HAS_SPECULAR) + mmio_index |= VERT_SPEC; + if (smesa->AGPParseSet & SiS_PS_HAS_W) + mmio_index |= VERT_W; + if (smesa->AGPParseSet & SiS_PS_HAS_UV0) + mmio_index |= VERT_UV0; + if (smesa->AGPParseSet & SiS_PS_HAS_UV1) + mmio_index |= VERT_UV1; + + switch (smesa->AGPParseSet & MASK_PsDataType) { + case MASK_PsPointList: + incr = smesa->vertex_size * 4; + sis_emit_func = sis_point_func_mmio[mmio_index]; + break; + case MASK_PsLineList: + incr = smesa->vertex_size * 4 * 2; + sis_emit_func = sis_line_func_mmio[mmio_index]; + break; + case MASK_PsTriangleList: + incr = smesa->vertex_size * 4 * 3; + sis_emit_func = sis_tri_func_mmio[mmio_index]; + break; + } + + mWait3DCmdQueue(1); + MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet); + while (smesa->vb_last < smesa->vb_cur) { + sis_emit_func(smesa, smesa->vb_last); + smesa->vb_last += incr; + } + mWait3DCmdQueue(1); + mEndPrimitive(); + + /* With PCI, we can just start writing to the start of the VB again. */ + smesa->vb_cur = smesa->vb; + } + smesa->vb_last = smesa->vb_cur; +} + +void sisFlushPrims(sisContextPtr smesa) +{ + LOCK_HARDWARE(); + sisFlushPrimsLocked(smesa); + UNLOCK_HARDWARE(); +} + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLuint oldfallback = smesa->Fallback; + + if (mode) { + smesa->Fallback |= bit; + if (oldfallback == 0) { + SIS_FIREVERTICES(smesa); + _swsetup_Wakeup( ctx ); + smesa->RenderIndex = ~0; + } + } + else { + smesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = sisRenderStart; + tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive; + tnl->Driver.Render.Finish = sisRenderFinish; + + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + _tnl_install_attrs( ctx, + smesa->vertex_attrs, + smesa->vertex_attr_count, + smesa->hw_viewport, 0 ); + + smesa->NewGLState |= _SIS_NEW_RENDER_STATE; + } + } +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void sisInitTriFuncs( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + + sis_vert_init_none(); + sis_vert_init_g(); + sis_vert_init_w(); + sis_vert_init_gw(); + sis_vert_init_s(); + sis_vert_init_gs(); + sis_vert_init_ws(); + sis_vert_init_gws(); + sis_vert_init_t0(); + sis_vert_init_gt0(); + sis_vert_init_wt0(); + sis_vert_init_gwt0(); + sis_vert_init_st0(); + sis_vert_init_gst0(); + sis_vert_init_wst0(); + sis_vert_init_gwst0(); + sis_vert_init_t1(); + sis_vert_init_gt1(); + sis_vert_init_wt1(); + sis_vert_init_gwt1(); + sis_vert_init_st1(); + sis_vert_init_gst1(); + sis_vert_init_wst1(); + sis_vert_init_gwst1(); + sis_vert_init_t0t1(); + sis_vert_init_gt0t1(); + sis_vert_init_wt0t1(); + sis_vert_init_gwt0t1(); + sis_vert_init_st0t1(); + sis_vert_init_gst0t1(); + sis_vert_init_wst0t1(); + sis_vert_init_gwst0t1(); + } + + if (driQueryOptionb(&smesa->optionCache, "fallback_force")) + sisFallback(ctx, SIS_FALLBACK_FORCE, 1); + else + sisFallback(ctx, SIS_FALLBACK_FORCE, 0); + + smesa->RenderIndex = ~0; + smesa->NewGLState |= _SIS_NEW_RENDER_STATE; + + tnl->Driver.RunPipeline = sisRunPipeline; + tnl->Driver.Render.Start = sisRenderStart; + tnl->Driver.Render.Finish = sisRenderFinish; + tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + + 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) ); + + smesa->verts = (char *)tnl->clipspace.vertex_buf; +} |