diff options
author | Alan Hourihane <alanh@tungstengraphics.com> | 2004-02-02 10:06:16 +0000 |
---|---|---|
committer | Alan Hourihane <alanh@tungstengraphics.com> | 2004-02-02 10:06:16 +0000 |
commit | e3365ef739876dff793b71d45888ec9f7b47837f (patch) | |
tree | 393a61586c4160427a2924225688dc490c188db4 | |
parent | 0f518a56b4423980b9257cfb3a4314b65633004f (diff) |
pull in fixes from the mesa_6_0_branch
-rw-r--r-- | docs/RELNOTES-6.0.1 | 50 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd.c | 58 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_dmatmp.h | 1093 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_dmatmp2.h | 935 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_rendertmp.h | 434 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_triemit.h | 157 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_tritmp.h | 743 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_unfilled.h | 212 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_vb.c | 344 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_vbtmp.h | 679 | ||||
-rw-r--r-- | src/mesa/drivers/common/t_dd_vertex.h | 78 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i830/i830_vb.c | 574 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i830/i830_vb.h | 64 | ||||
-rw-r--r-- | src/mesa/main/buffers.c | 18 | ||||
-rw-r--r-- | src/mesa/main/dlist.c | 35 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_api.c | 22 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_fog.c | 2 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_light.c | 2 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_normals.c | 1 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_points.c | 6 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_texgen.c | 2 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_texmat.c | 2 |
22 files changed, 5456 insertions, 55 deletions
diff --git a/docs/RELNOTES-6.0.1 b/docs/RELNOTES-6.0.1 new file mode 100644 index 0000000000..0ac8867639 --- /dev/null +++ b/docs/RELNOTES-6.0.1 @@ -0,0 +1,50 @@ + + Mesa 6.0.1 release notes + + Month day, 2003 + + + +Introduction +------------ + +Mesa uses an even/odd version number scheme like the Linux kernel. +Even-numbered versions (such as 6.0.x) designate stable releases. +Odd-numbered versions (such as 6.1.x) designate new developmental releases. + +Mesa 6.0.1 just fixes bugs found since the 6.0 release. See the VERSIONS +file for details. + + + +Device Drivers +-------------- + +Mesa advertises itself as supporting OpenGL 1.2, 1.3, 1.4 or 1.5 +depending on the device driver's capabilities. For example, if the +driver enables all the ARB extensions which are part of OpenGL 1.5 +then glGetString(GL_VERSION) will return "1.5". Otherwise, it'll +return "1.4" or the next lower version that implements all required +functionality. + +A number of Mesa's software drivers haven't been actively maintained for +some time. We rely on volunteers to maintain many of the drivers. +Here's the current status of all included drivers: + +Driver Status +---------------------- --------------------- +XMesa (Xlib) implements OpenGL 1.5 +OSMesa (off-screen) implements OpenGL 1.5 +FX (3dfx Voodoo1/2) implements OpenGL 1.3 +SVGA implements OpenGL 1.3 +Wind River UGL implements OpenGL 1.3 +Windows/Win32 implements OpenGL 1.5 +DJGPP implements OpenGL 1.5 +GGI implements OpenGL 1.3 +BeOS implements OpenGL 1.5 +Allegro needs updating +D3D needs updating + + +---------------------------------------------------------------------- +$Id: RELNOTES-6.0.1,v 1.1.4.1 2004/02/02 10:06:16 alanh Exp $ diff --git a/src/mesa/drivers/common/t_dd.c b/src/mesa/drivers/common/t_dd.c new file mode 100644 index 0000000000..731da5c320 --- /dev/null +++ b/src/mesa/drivers/common/t_dd.c @@ -0,0 +1,58 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *i810verts = (GLubyte *)imesa->verts; + GLuint shift = imesa->vertex_stride_shift; + i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); + i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); + dst->ui[4] = src->ui[4]; + dst->ui[5] = src->ui[5]; +} + +static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *i810verts = (GLubyte *)imesa->verts; + GLuint shift = imesa->vertex_stride_shift; + i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); + i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); + dst->ui[4] = src->ui[4]; +} + +static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *i810verts = (GLubyte *)imesa->verts; + GLuint shift = imesa->vertex_stride_shift; + i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); + i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); + dst->ui[3] = src->ui[3]; +} diff --git a/src/mesa/drivers/common/t_dd_dmatmp.h b/src/mesa/drivers/common/t_dd_dmatmp.h new file mode 100644 index 0000000000..10ff1df5f0 --- /dev/null +++ b/src/mesa/drivers/common/t_dd_dmatmp.h @@ -0,0 +1,1093 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +/* Template for render stages which build and emit vertices directly + * to fixed-size dma buffers. Useful for rendering strips and other + * native primitives where clipping and per-vertex tweaks such as + * those in t_dd_tritmp.h are not required. + * + * Produces code for both inline triangles and indexed triangles. + * Where various primitive types are unaccelerated by hardware, the + * code attempts to fallback to other primitive types (quadstrips to + * tristrips, lineloops to linestrips), or to indexed vertices. + * Ultimately, a FALLBACK() macro is invoked if there is no way to + * render the primitive natively. + */ + +#if !defined(HAVE_TRIANGLES) +#error "must have at least triangles to use render template" +#endif + +#if !HAVE_ELTS +#define ELTS_VARS +#define ALLOC_ELTS( nr ) +#define EMIT_ELT( offset, elt ) +#define EMIT_TWO_ELTS( offset, elt0, elt1 ) +#define INCR_ELTS( nr ) +#define ELT_INIT(prim) +#define GET_CURRENT_VB_MAX_ELTS() 0 +#define GET_SUBSEQUENT_VB_MAX_ELTS() 0 +#define ALLOC_ELTS_NEW_PRIMITIVE(nr) +#define RELEASE_ELT_VERTS() +#define EMIT_INDEXED_VERTS( ctx, start, count ) +#endif + +#ifndef EMIT_TWO_ELTS +#define EMIT_TWO_ELTS( offset, elt0, elt1 ) \ +do { \ + EMIT_ELT( offset, elt0 ); \ + EMIT_ELT( offset+1, elt1 ); \ +} while (0) +#endif + +#ifndef FINISH +#define FINISH +#endif + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + + + +static GLboolean TAG(emit_elt_verts)( GLcontext *ctx, + GLuint start, GLuint count ) +{ + if (HAVE_ELTS) { + LOCAL_VARS; + GLuint nr = count - start; + + if ( nr >= GET_SUBSEQUENT_VB_MAX_VERTS() ) /* assumes same packing for + * indexed and regualar verts + */ + return GL_FALSE; + + NEW_PRIMITIVE(); /* finish last prim */ + EMIT_INDEXED_VERTS( ctx, start, count ); + return GL_TRUE; + } else { + return GL_FALSE; + } +} + +#if (HAVE_ELTS) +static void TAG(emit_elts)( GLcontext *ctx, GLuint *elts, GLuint nr ) +{ + GLint i; + LOCAL_VARS; + ELTS_VARS; + + ALLOC_ELTS( nr ); + + for ( i = 0 ; i < nr ; i+=2, elts += 2 ) { + EMIT_TWO_ELTS( 0, elts[0], elts[1] ); + INCR_ELTS( 2 ); + } +} +#endif + + +/*********************************************************************** + * Render non-indexed primitives. + ***********************************************************************/ + + + +static void TAG(render_points_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POINTS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + INIT( GL_POINTS ); + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_lines_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINES) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + INIT( GL_LINES ); + + /* Emit whole number of lines in total and in each buffer: + */ + count -= (count-start) & 1; + currentsz -= currentsz & 1; + dmasz -= dmasz & 1; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + NEW_PRIMITIVE(); /* always a new primitive */ + INIT( GL_LINE_STRIP ); + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_loop_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + GLuint j, nr; + + NEW_PRIMITIVE(); + INIT( GL_LINE_STRIP ); + + if (flags & PRIM_BEGIN) + j = start; + else + j = start + 1; + + /* Ensure last vertex won't wrap buffers: + */ + currentsz--; + dmasz--; + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + if (j + 1 < count) { + for ( ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + if (start < count - 1 && (flags & PRIM_END)) + EMIT_VERTS( ctx, start, 1 ); + } + else if (start + 1 < count && (flags & PRIM_END)) { + EMIT_VERTS( ctx, start+1, 1 ); + EMIT_VERTS( ctx, start, 1 ); + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_triangles_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3; + int currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3; + GLuint j, nr; + + INIT(GL_TRIANGLES); + + /* Emit whole number of tris in total. dmasz is already a multiple + * of 3. + */ + count -= (count-start)%3; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + FINISH; +} + + + +static void TAG(render_tri_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz; + + INIT(GL_TRIANGLE_STRIP); + NEW_PRIMITIVE(); + + currentsz = GET_CURRENT_VB_MAX_VERTS(); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + /* From here on emit even numbers of tris when wrapping over buffers: + */ + dmasz -= (dmasz & 1); + currentsz -= (currentsz & 1); + + for (j = start ; j + 2 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_tri_fan_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_FANS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + + NEW_PRIMITIVE(); + INIT(GL_TRIANGLE_FAN); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + EMIT_VERTS( ctx, start, 1 ); + EMIT_VERTS( ctx, j, nr - 1 ); + currentsz = dmasz; + } + + FINISH; + + } + else { + /* Could write code to emit these as indexed vertices (for the + * g400, for instance). + */ + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_poly_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POLYGONS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + + NEW_PRIMITIVE(); + INIT(GL_POLYGON); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + EMIT_VERTS( ctx, start, 1 ); + EMIT_VERTS( ctx, j, nr - 1 ); + currentsz = dmasz; + } + + FINISH; + + } + else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) { + TAG(render_tri_fan_verts)( ctx, start, count, flags ); + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_quad_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j, nr; + + if (HAVE_QUAD_STRIPS) { + LOCAL_VARS; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz; + + INIT(GL_QUAD_STRIP); + NEW_PRIMITIVE(); + + currentsz = GET_CURRENT_VB_MAX_VERTS(); + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + dmasz -= (dmasz & 2); + currentsz -= (currentsz & 2); + + for (j = start ; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else if (HAVE_TRI_STRIPS && (ctx->_TriangleCaps & DD_FLATSHADE)) { + if (TAG(emit_elt_verts)( ctx, start, count )) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + /* Simulate flat-shaded quadstrips using indexed vertices: + */ + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLES ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + count -= (count-start) & 1; + currentsz -= currentsz & 1; + + if (currentsz < 12) + currentsz = dmasz; + + currentsz = currentsz/6*2; + dmasz = dmasz/6*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + if (nr >= 4) { + GLint quads = (nr/2)-1; + GLint i; + ELTS_VARS; + + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); + + for ( i = j-start ; i < j-start+quads*2 ; i+=2 ) { + EMIT_TWO_ELTS( 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( 2, (i+2), (i+1) ); + EMIT_TWO_ELTS( 4, (i+3), (i+2) ); + INCR_ELTS( 6 ); + } + + NEW_PRIMITIVE(); + } + currentsz = dmasz; + } + + RELEASE_ELT_VERTS(); + } + else { + /* Vertices won't fit in a single buffer or elts not available, + * VERT_FALLBACK. + */ + VERT_FALLBACK( ctx, start, count, flags ); + } + } + else if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); + int currentsz = GET_CURRENT_VB_MAX_VERTS(); + + /* Emit smooth-shaded quadstrips as tristrips: + */ + NEW_PRIMITIVE(); + INIT( GL_TRIANGLE_STRIP ); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + currentsz -= currentsz & 1; + count -= (count-start) & 1; + + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + + FINISH; + + } else { + VERT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_quads_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_QUADS) { + LOCAL_VARS; + int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/4) * 4; + int currentsz = (GET_CURRENT_VB_MAX_VERTS()/4) * 4; + GLuint j, nr; + + INIT(GL_QUADS); + + /* Emit whole number of quads in total. dmasz is already a multiple + * of 4. + */ + count -= (count-start)%4; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr) { + nr = MIN2( currentsz, count - j ); + EMIT_VERTS( ctx, j, nr ); + currentsz = dmasz; + } + FINISH; + } else if (TAG(emit_elt_verts)( ctx, start, count )) { + /* Hardware doesn't have a quad primitive type -- try to + * simulate it using indexed vertices and the triangle + * primitive: + */ + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLES ); + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 3; + count -= (count-start) & 3; + currentsz -= currentsz & 3; + + /* Adjust for rendering as triangles: + */ + currentsz = currentsz/6*4; + dmasz = dmasz/6*4; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + if (nr >= 4) { + GLint quads = nr/4; + GLint i; + ELTS_VARS; + + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); + + for ( i = j-start ; i < j-start+quads*4 ; i+=4 ) { + EMIT_TWO_ELTS( 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( 2, (i+3), (i+1) ); + EMIT_TWO_ELTS( 4, (i+2), (i+3) ); + INCR_ELTS( 6 ); + } + + NEW_PRIMITIVE(); + } + currentsz = dmasz; + } + + RELEASE_ELT_VERTS(); + } + else { + /* Vertices won't fit in a single buffer, fallback. + */ + VERT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_noop)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ +} + + + + +static render_func TAG(render_tab_verts)[GL_POLYGON+2] = +{ + TAG(render_points_verts), + TAG(render_lines_verts), + TAG(render_line_loop_verts), + TAG(render_line_strip_verts), + TAG(render_triangles_verts), + TAG(render_tri_strip_verts), + TAG(render_tri_fan_verts), + TAG(render_quads_verts), + TAG(render_quad_strip_verts), + TAG(render_poly_verts), + TAG(render_noop), +}; + + +/**************************************************************************** + * Render elts using hardware indexed verts * + ****************************************************************************/ + +#if (HAVE_ELTS) +static void TAG(render_points_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POINTS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + ELT_INIT( GL_POINTS ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + + +static void TAG(render_lines_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINES) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + ELT_INIT( GL_LINES ); + + /* Emit whole number of lines in total and in each buffer: + */ + count -= (count-start) & 1; + currentsz -= currentsz & 1; + dmasz -= dmasz & 1; + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + NEW_PRIMITIVE(); /* always a new primitive */ + ELT_INIT( GL_LINE_STRIP ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + /* TODO: Try to emit as indexed lines. + */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_line_loop_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_LINE_STRIPS) { + LOCAL_VARS; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + + NEW_PRIMITIVE(); + ELT_INIT( GL_LINE_STRIP ); + + if (flags & PRIM_BEGIN) + j = start; + else + j = start + 1; + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + /* Ensure last vertex doesn't wrap: + */ + currentsz--; + dmasz--; + + for ( ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j ); +/* NEW_PRIMITIVE(); */ + TAG(emit_elts)( ctx, elts+j, nr ); + currentsz = dmasz; + } + + if (flags & PRIM_END) + TAG(emit_elts)( ctx, elts+start, 1 ); + + NEW_PRIMITIVE(); + } else { + /* TODO: Try to emit as indexed lines */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +/* For verts, we still eliminate the copy from main memory to dma + * buffers. For elts, this is probably no better (worse?) than the + * standard path. + */ +static void TAG(render_triangles_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3; + int currentsz; + GLuint j, nr; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLES ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of tris in total. dmasz is already a multiple + * of 3. + */ + count -= (count-start)%3; + currentsz -= currentsz%3; + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j < count; j += nr) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } +} + + + +static void TAG(render_tri_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + GLuint j, nr; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLE_STRIP ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + /* Keep the same winding over multiple buffers: + */ + dmasz -= (dmasz & 1); + currentsz -= (currentsz & 1); + + for (j = start ; j + 2 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + /* TODO: try to emit as indexed triangles */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_tri_fan_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_TRI_FANS) { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLE_FAN ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + TAG(emit_elts)( ctx, elts+start, 1 ); + TAG(emit_elts)( ctx, elts+j, nr - 1 ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + /* TODO: try to emit as indexed triangles */ + ELT_FALLBACK( ctx, start, count, flags ); + } +} + + +static void TAG(render_poly_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_POLYGONS && 0) { + } else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j, nr; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + + NEW_PRIMITIVE(); + ELT_INIT( GL_TRIANGLE_FAN ); + + currentsz = GET_CURRENT_VB_MAX_ELTS(); + if (currentsz < 8) { + NEW_BUFFER(); + currentsz = dmasz; + } + + for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { + nr = MIN2( currentsz, count - j + 1 ); + TAG(emit_elts)( ctx, elts+start, 1 ); + TAG(emit_elts)( ctx, elts+j, nr - 1 ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } else { + ELT_FALLBACK( ctx, start, count, flags ); + } +} + +static void TAG(render_quad_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_QUAD_STRIPS && 0) { + } + else if (HAVE_TRI_STRIPS) { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + NEW_PRIMITIVE(); + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + count -= (count-start) & 1; + currentsz -= currentsz & 1; + + if (currentsz < 12) + currentsz = dmasz; + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + ELT_INIT( GL_TRIANGLES ); + + currentsz = currentsz/6*2; + dmasz = dmasz/6*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + + if (nr >= 4) + { + GLint i; + GLint quads = (nr/2)-1; + ELTS_VARS; + + + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); + + for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) { + EMIT_TWO_ELTS( 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( 2, elts[2], elts[1] ); + EMIT_TWO_ELTS( 4, elts[3], elts[2] ); + INCR_ELTS( 6 ); + } + + NEW_PRIMITIVE(); + } + + currentsz = dmasz; + } + } + else { + ELT_INIT( GL_TRIANGLE_STRIP ); + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + TAG(emit_elts)( ctx, elts+j, nr ); + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } + } +} + + +static void TAG(render_quads_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (HAVE_QUADS && 0) { + } else { + LOCAL_VARS; + GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; + int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); + int currentsz; + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES ); + currentsz = GET_CURRENT_VB_MAX_ELTS(); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 3; + count -= (count-start) & 3; + currentsz -= currentsz & 3; + + /* Adjust for rendering as triangles: + */ + currentsz = currentsz/6*4; + dmasz = dmasz/6*4; + + if (currentsz < 8) + currentsz = dmasz; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( currentsz, count - j ); + + if (nr >= 4) + { + GLint quads = nr/4; + GLint i; + ELTS_VARS; + NEW_PRIMITIVE(); + ALLOC_ELTS_NEW_PRIMITIVE( quads * 6 ); + + for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) { + EMIT_TWO_ELTS( 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( 2, elts[3], elts[1] ); + EMIT_TWO_ELTS( 4, elts[2], elts[3] ); + INCR_ELTS( 6 ); + } + } + + NEW_PRIMITIVE(); + currentsz = dmasz; + } + } +} + + + +static render_func TAG(render_tab_elts)[GL_POLYGON+2] = +{ + TAG(render_points_elts), + TAG(render_lines_elts), + TAG(render_line_loop_elts), + TAG(render_line_strip_elts), + TAG(render_triangles_elts), + TAG(render_tri_strip_elts), + TAG(render_tri_fan_elts), + TAG(render_quads_elts), + TAG(render_quad_strip_elts), + TAG(render_poly_elts), + TAG(render_noop), +}; +#endif diff --git a/src/mesa/drivers/common/t_dd_dmatmp2.h b/src/mesa/drivers/common/t_dd_dmatmp2.h new file mode 100644 index 0000000000..dd0286b453 --- /dev/null +++ b/src/mesa/drivers/common/t_dd_dmatmp2.h @@ -0,0 +1,935 @@ + +/* + * Mesa 3-D graphics library + * Version: 4.0.3 + * + * Copyright (C) 1999-2002 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +/* Template for render stages which build and emit vertices directly + * to fixed-size dma buffers. Useful for rendering strips and other + * native primitives where clipping and per-vertex tweaks such as + * those in t_dd_tritmp.h are not required. + * + */ + +#if !HAVE_TRIANGLES || !HAVE_POINTS || !HAVE_LINES +#error "must have points, lines & triangles to use render template" +#endif + +#if !HAVE_TRI_STRIPS || !HAVE_TRI_FANS +#error "must have tri strip and fans to use render template" +#endif + +#if !HAVE_LINE_STRIPS +#error "must have line strips to use render template" +#endif + +#if !HAVE_POLYGONS +#error "must have polygons to use render template" +#endif + +#if !HAVE_ELTS +#error "must have elts to use render template" +#endif + + +#ifndef EMIT_TWO_ELTS +#define EMIT_TWO_ELTS( dest, offset, elt0, elt1 ) \ +do { \ + (dest)[offset] = (elt0); \ + (dest)[offset+1] = (elt1); \ +} while (0) +#endif + + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + + +static ELT_TYPE *TAG(emit_elts)( GLcontext *ctx, + ELT_TYPE *dest, + GLuint *elts, GLuint nr ) +{ + GLint i; + LOCAL_VARS; + + for ( i = 0 ; i+1 < nr ; i+=2, elts += 2 ) { + EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] ); + dest += 2; + } + if (i < nr) { + EMIT_ELT( dest, 0, elts[0] ); + dest += 1; + } + + return dest; +} + +static ELT_TYPE *TAG(emit_consecutive_elts)( GLcontext *ctx, + ELT_TYPE *dest, + GLuint start, GLuint nr ) +{ + GLint i; + LOCAL_VARS; + + for ( i = 0 ; i+1 < nr ; i+=2, start += 2 ) { + EMIT_TWO_ELTS( dest, 0, start, start+1 ); + dest += 2; + } + if (i < nr) { + EMIT_ELT( dest, 0, start ); + dest += 1; + } + + return dest; +} + +/*********************************************************************** + * Render non-indexed primitives. + ***********************************************************************/ + + + +static void TAG(render_points_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (start < count) { + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + EMIT_PRIM( ctx, GL_POINTS, HW_POINTS, start, count ); + } +} + +static void TAG(render_lines_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + count -= (count-start) & 1; + + if (start+1 >= count) + return; + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) { + RESET_STIPPLE(); + AUTO_STIPPLE( GL_TRUE ); + } + + EMIT_PRIM( ctx, GL_LINES, HW_LINES, start, count ); + + if ((flags & PRIM_END) && ctx->Line.StippleFlag) + AUTO_STIPPLE( GL_FALSE ); +} + + +static void TAG(render_line_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start+1 >= count) + return; + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) + RESET_STIPPLE(); + + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) + { + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_LINES, HW_LINES ); + + /* Emit whole number of lines in each full buffer. + */ + dmasz = dmasz/2; + + + for (j = start; j + 1 < count; j += nr - 1 ) { + ELT_TYPE *dest; + GLint i; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( (nr-1)*2 ); + + for ( i = j ; i+1 < j+nr ; i+=1 ) { + EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) ); + dest += 2; + } + + CLOSE_ELTS(); + } + } + else + EMIT_PRIM( ctx, GL_LINE_STRIP, HW_LINE_STRIP, start, count ); +} + + +static void TAG(render_line_loop_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint j, nr; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (flags & PRIM_BEGIN) { + j = start; + if (ctx->Line.StippleFlag) + RESET_STIPPLE( ); + } + else + j = start + 1; + + if (flags & PRIM_END) { + + if (start+1 >= count) + return; + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) { + int dmasz = GET_MAX_HW_ELTS(); + + ELT_INIT( GL_LINES, HW_LINES ); + + /* Emit whole number of lines in each full buffer. + */ + dmasz = dmasz/2; + + /* Ensure last vertex doesn't wrap: + */ + dmasz--; + + for (; j + 1 < count; ) { + GLint i; + ELT_TYPE *dest; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr*2 ); /* allocs room for 1 more line */ + + for ( i = 0 ; i < nr - 1 ; i+=1 ) { + EMIT_TWO_ELTS( dest, 0, (j+i), (j+i+1) ); + dest += 2; + } + + j += nr - 1; + + /* Emit 1 more line into space alloced above */ + if (j + 1 >= count) { + EMIT_TWO_ELTS( dest, 0, (j), (start) ); + dest += 2; + } + + CLOSE_ELTS(); + } + } + else + { + int dmasz = GET_MAX_HW_ELTS() - 1; + + ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); + + for ( ; j + 1 < count; ) { + nr = MIN2( dmasz, count - j ); + if (j + nr < count) { + ELT_TYPE *dest = ALLOC_ELTS( nr ); + dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr ); + j += nr - 1; + CLOSE_ELTS(); + } + else if (nr) { + ELT_TYPE *dest = ALLOC_ELTS( nr + 1 ); + dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr ); + dest = TAG(emit_consecutive_elts)( ctx, dest, start, 1 ); + j += nr; + CLOSE_ELTS(); + } + } + } + } else { + TAG(render_line_strip_verts)( ctx, j, count, flags ); + } +} + + +static void TAG(render_triangles_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + count -= (count-start)%3; + + if (start+2 >= count) { + return; + } + + /* need a PREFER_DISCRETE_ELT_PRIM here too.. + */ + EMIT_PRIM( ctx, GL_TRIANGLES, HW_TRIANGLES, start, count ); +} + + + +static void TAG(render_tri_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start + 2 >= count) + return; + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES )) + { + int dmasz = GET_MAX_HW_ELTS(); + int parity = 0; + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Emit even number of tris in each full buffer. + */ + dmasz = dmasz/3; + dmasz -= dmasz & 1; + + for (j = start; j + 2 < count; j += nr - 2 ) { + ELT_TYPE *dest; + GLint i; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( (nr-2)*3 ); + + for ( i = j ; i+2 < j+nr ; i++, parity^=1 ) { + EMIT_ELT( dest, 0, (i+0+parity) ); + EMIT_ELT( dest, 1, (i+1-parity) ); + EMIT_ELT( dest, 2, (i+2) ); + dest += 3; + } + + CLOSE_ELTS(); + } + } + else if (HAVE_TRI_STRIP_1) + EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_1, start, count ); + else { + /* Emit the first triangle with elts, then the rest as a regular strip. + * TODO: Make this unlikely in t_imm_api.c + */ + ELT_TYPE *dest; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + dest = ALLOC_ELTS( 3 ); + EMIT_ELT( dest, 0, (start+1) ); + EMIT_ELT( dest, 1, (start+0) ); + EMIT_ELT( dest, 2, (start+2) ); + dest += 3; + CLOSE_ELTS(); + + start++; + if (start + 2 >= count) + return; + + EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, + count ); + } +} + +static void TAG(render_tri_fan_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start+2 >= count) + return; + + if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES )) + { + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + dmasz = dmasz/3; + + for (j = start + 1; j + 1 < count; j += nr - 1 ) { + ELT_TYPE *dest; + GLint i; + + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( (nr-1)*3 ); + + for ( i = j ; i+1 < j+nr ; i++ ) { + EMIT_ELT( dest, 0, (start) ); + EMIT_ELT( dest, 1, (i) ); + EMIT_ELT( dest, 2, (i+1) ); + dest += 3; + } + + CLOSE_ELTS(); + } + } + else { + EMIT_PRIM( ctx, GL_TRIANGLE_FAN, HW_TRIANGLE_FAN, start, count ); + } +} + + +static void TAG(render_poly_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (start+2 >= count) + return; + + EMIT_PRIM( ctx, GL_POLYGON, HW_POLYGON, start, count ); +} + +static void TAG(render_quad_strip_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + count -= (count-start) & 1; + + if (start+3 >= count) + return; + + if (HAVE_QUAD_STRIPS) { + EMIT_PRIM( ctx, GL_QUAD_STRIP, HW_QUAD_STRIP, start, count ); + } + else if (ctx->_TriangleCaps & DD_FLATSHADE) { + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz = (dmasz/6)*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + ELT_TYPE *dest; + GLint quads, i; + + nr = MIN2( dmasz, count - j ); + quads = (nr/2)-1; + dest = ALLOC_ELTS( quads*6 ); + + for ( i = j ; i < j+quads*2 ; i+=2 ) { + EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( dest, 2, (i+2), (i+1) ); + EMIT_TWO_ELTS( dest, 4, (i+3), (i+2) ); + dest += 6; + } + + CLOSE_ELTS(); + } + } + else { + EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count ); + } +} + + +static void TAG(render_quads_verts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + count -= (count-start)%4; + + if (start+3 >= count) + return; + + if (HAVE_QUADS) { + EMIT_PRIM( ctx, HW_QUADS, GL_QUADS, start, count ); + } + else { + /* Hardware doesn't have a quad primitive type -- simulate it + * using indexed vertices and the triangle primitive: + */ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Adjust for rendering as triangles: + */ + dmasz = (dmasz/6)*4; + + for (j = start; j < count; j += nr ) { + ELT_TYPE *dest; + GLint quads, i; + + nr = MIN2( dmasz, count - j ); + quads = nr/4; + dest = ALLOC_ELTS( quads*6 ); + + for ( i = j ; i < j+quads*4 ; i+=4 ) { + EMIT_TWO_ELTS( dest, 0, (i+0), (i+1) ); + EMIT_TWO_ELTS( dest, 2, (i+3), (i+1) ); + EMIT_TWO_ELTS( dest, 4, (i+2), (i+3) ); + dest += 6; + } + + CLOSE_ELTS(); + } + } +} + +static void TAG(render_noop)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ +} + + + + +static render_func TAG(render_tab_verts)[GL_POLYGON+2] = +{ + TAG(render_points_verts), + TAG(render_lines_verts), + TAG(render_line_loop_verts), + TAG(render_line_strip_verts), + TAG(render_triangles_verts), + TAG(render_tri_strip_verts), + TAG(render_tri_fan_verts), + TAG(render_quads_verts), + TAG(render_quad_strip_verts), + TAG(render_poly_verts), + TAG(render_noop), +}; + + +/**************************************************************************** + * Render elts using hardware indexed verts * + ****************************************************************************/ + +static void TAG(render_points_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + ELT_INIT( GL_POINTS, HW_POINTS ); + + for (j = start; j < count; j += nr ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + + + +static void TAG(render_lines_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + if (start+1 >= count) + return; + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) { + RESET_STIPPLE(); + AUTO_STIPPLE( GL_TRUE ); + } + + ELT_INIT( GL_LINES, HW_LINES ); + + /* Emit whole number of lines in total and in each buffer: + */ + count -= (count-start) & 1; + dmasz -= dmasz & 1; + + for (j = start; j < count; j += nr ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } + + if ((flags & PRIM_END) && ctx->Line.StippleFlag) + AUTO_STIPPLE( GL_FALSE ); +} + + +static void TAG(render_line_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + if (start+1 >= count) + return; + + ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) + RESET_STIPPLE(); + + for (j = start; j + 1 < count; j += nr - 1 ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + + +static void TAG(render_line_loop_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + int dmasz = GET_MAX_HW_ELTS(); + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + if (flags & PRIM_BEGIN) + j = start; + else + j = start + 1; + + + if (flags & PRIM_END) { + if (start+1 >= count) + return; + } + else { + if (j+1 >= count) + return; + } + + ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); + + if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) + RESET_STIPPLE(); + + + /* Ensure last vertex doesn't wrap: + */ + dmasz--; + + for ( ; j + 1 < count; ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr+1 ); /* Reserve possible space for last elt */ + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + j += nr - 1; + if (j + 1 >= count && (flags & PRIM_END)) { + dest = TAG(emit_elts)( ctx, dest, elts+start, 1 ); + } + CLOSE_ELTS(); + } +} + + +static void TAG(render_triangles_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS()/3*3; + GLuint j, nr; + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + + /* Emit whole number of tris in total. dmasz is already a multiple + * of 3. + */ + count -= (count-start)%3; + + for (j = start; j < count; j += nr) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + + + +static void TAG(render_tri_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint j, nr; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS(); + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 ); + + /* Keep the same winding over multiple buffers: + */ + dmasz -= (dmasz & 1); + + for (j = start ; j + 2 < count; j += nr - 2 ) { + nr = MIN2( dmasz, count - j ); + + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } +} + +static void TAG(render_tri_fan_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + int dmasz = GET_MAX_HW_ELTS(); + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_TRIANGLE_FAN, HW_TRIANGLE_FAN ); + + for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { + nr = MIN2( dmasz, count - j + 1 ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+start, 1 ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 ); + CLOSE_ELTS(); + } +} + + +static void TAG(render_poly_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + GLuint j, nr; + int dmasz = GET_MAX_HW_ELTS(); + ELT_TYPE *dest; + + if (start+2 >= count) + return; + + ELT_INIT( GL_POLYGON, HW_POLYGON ); + + for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { + nr = MIN2( dmasz, count - j + 1 ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+start, 1 ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 ); + CLOSE_ELTS(); + } +} + +static void TAG(render_quad_strip_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (start+3 >= count) + return; + + if (HAVE_QUAD_STRIPS && 0) { + } + else { + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + ELT_TYPE *dest; + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 1; + count -= (count-start) & 1; + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + dmasz = dmasz/6*2; + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( dmasz, count - j ); + + if (nr >= 4) + { + GLint quads = (nr/2)-1; + ELT_TYPE *dest = ALLOC_ELTS( quads*6 ); + GLint i; + + for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) { + EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( dest, 2, elts[2], elts[1] ); + EMIT_TWO_ELTS( dest, 4, elts[3], elts[2] ); + dest += 6; + } + + CLOSE_ELTS(); + } + } + } + else { + ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 ); + + for (j = start; j + 3 < count; j += nr - 2 ) { + nr = MIN2( dmasz, count - j ); + dest = ALLOC_ELTS( nr ); + dest = TAG(emit_elts)( ctx, dest, elts+j, nr ); + CLOSE_ELTS(); + } + } + } +} + + +static void TAG(render_quads_elts)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + if (start+3 >= count) + return; + + if (HAVE_QUADS && 0) { + } else { + LOCAL_VARS; + GLuint *elts = GET_MESA_ELTS(); + int dmasz = GET_MAX_HW_ELTS(); + GLuint j, nr; + + ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); + + /* Emit whole number of quads in total, and in each buffer. + */ + dmasz -= dmasz & 3; + count -= (count-start) & 3; + + /* Adjust for rendering as triangles: + */ + dmasz = dmasz/6*4; + + for (j = start; j + 3 < count; j += nr ) { + nr = MIN2( dmasz, count - j ); + + { + GLint quads = nr/4; + ELT_TYPE *dest = ALLOC_ELTS( quads * 6 ); + GLint i; + + for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) { + EMIT_TWO_ELTS( dest, 0, elts[0], elts[1] ); + EMIT_TWO_ELTS( dest, 2, elts[3], elts[1] ); + EMIT_TWO_ELTS( dest, 4, elts[2], elts[3] ); + dest += 6; + } + + CLOSE_ELTS(); + } + } + } +} + + + +static render_func TAG(render_tab_elts)[GL_POLYGON+2] = +{ + TAG(render_points_elts), + TAG(render_lines_elts), + TAG(render_line_loop_elts), + TAG(render_line_strip_elts), + TAG(render_triangles_elts), + TAG(render_tri_strip_elts), + TAG(render_tri_fan_elts), + TAG(render_quads_elts), + TAG(render_quad_strip_elts), + TAG(render_poly_elts), + TAG(render_noop), +}; diff --git a/src/mesa/drivers/common/t_dd_rendertmp.h b/src/mesa/drivers/common/t_dd_rendertmp.h new file mode 100644 index 0000000000..b9f030195d --- /dev/null +++ b/src/mesa/drivers/common/t_dd_rendertmp.h @@ -0,0 +1,434 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +#ifndef POSTFIX +#define POSTFIX +#endif + +#ifndef INIT +#define INIT(x) +#endif + +#ifndef NEED_EDGEFLAG_SETUP +#define NEED_EDGEFLAG_SETUP 0 +#define EDGEFLAG_GET(a) 0 +#define EDGEFLAG_SET(a,b) (void)b +#endif + +#ifndef RESET_STIPPLE +#define RESET_STIPPLE +#endif + +#ifndef RESET_OCCLUSION +#define RESET_OCCLUSION +#endif + +#ifndef TEST_PRIM_END +#define TEST_PRIM_END(flags) (flags & PRIM_END) +#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN) +#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY) +#endif + +#ifndef ELT +#define ELT(x) x +#endif + +#ifndef RENDER_TAB_QUALIFIER +#define RENDER_TAB_QUALIFIER static +#endif + +static void TAG(render_points)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_POINTS); + RENDER_POINTS( start, count ); + POSTFIX; +} + +static void TAG(render_lines)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_LINES); + for (j=start+1; j<count; j+=2 ) { + RENDER_LINE( ELT(j-1), ELT(j) ); + RESET_STIPPLE; + } + POSTFIX; +} + + +static void TAG(render_line_strip)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_LINE_STRIP); + + for (j=start+1; j<count; j++ ) + RENDER_LINE( ELT(j-1), ELT(j) ); + + if (TEST_PRIM_END(flags)) + RESET_STIPPLE; + + POSTFIX; +} + + +static void TAG(render_line_loop)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint i; + LOCAL_VARS; + + (void) flags; + + RESET_OCCLUSION; + INIT(GL_LINE_LOOP); + + if (start+1 < count) { + if (TEST_PRIM_BEGIN(flags)) { + RENDER_LINE( ELT(start), ELT(start+1) ); + } + + for ( i = start+2 ; i < count ; i++) { + RENDER_LINE( ELT(i-1), ELT(i) ); + } + + if ( TEST_PRIM_END(flags)) { + RENDER_LINE( ELT(count-1), ELT(start) ); + RESET_STIPPLE; + } + } + + POSTFIX; +} + + +static void TAG(render_triangles)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + INIT(GL_TRIANGLES); + if (NEED_EDGEFLAG_SETUP) { + for (j=start+2; j<count; j+=3) { + /* Leave the edgeflags as supplied by the user. + */ + RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); + RESET_STIPPLE; + } + } else { + for (j=start+2; j<count; j+=3) { + RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); + } + } + POSTFIX; +} + + + +static void TAG(render_tri_strip)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + GLuint parity = 0; + LOCAL_VARS; + + INIT(GL_TRIANGLE_STRIP); + if (NEED_EDGEFLAG_SETUP) { + for (j=start+2;j<count;j++,parity^=1) { + GLuint ej2 = ELT(j-2+parity); + GLuint ej1 = ELT(j-1-parity); + GLuint ej = ELT(j); + GLboolean ef2 = EDGEFLAG_GET( ej2 ); + GLboolean ef1 = EDGEFLAG_GET( ej1 ); + GLboolean ef = EDGEFLAG_GET( ej ); + EDGEFLAG_SET( ej2, GL_TRUE ); + EDGEFLAG_SET( ej1, GL_TRUE ); + EDGEFLAG_SET( ej, GL_TRUE ); + RENDER_TRI( ej2, ej1, ej ); + EDGEFLAG_SET( ej2, ef2 ); + EDGEFLAG_SET( ej1, ef1 ); + EDGEFLAG_SET( ej, ef ); + RESET_STIPPLE; + } + } else { + for (j=start+2; j<count ; j++, parity^=1) { + RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) ); + } + } + POSTFIX; +} + + +static void TAG(render_tri_fan)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + INIT(GL_TRIANGLE_FAN); + if (NEED_EDGEFLAG_SETUP) { + for (j=start+2;j<count;j++) { + /* For trifans, all edges are boundary. + */ + GLuint ejs = ELT(start); + GLuint ej1 = ELT(j-1); + GLuint ej = ELT(j); + GLboolean efs = EDGEFLAG_GET( ejs ); + GLboolean ef1 = EDGEFLAG_GET( ej1 ); + GLboolean ef = EDGEFLAG_GET( ej ); + EDGEFLAG_SET( ejs, GL_TRUE ); + EDGEFLAG_SET( ej1, GL_TRUE ); + EDGEFLAG_SET( ej, GL_TRUE ); + RENDER_TRI( ejs, ej1, ej); + EDGEFLAG_SET( ejs, efs ); + EDGEFLAG_SET( ej1, ef1 ); + EDGEFLAG_SET( ej, ef ); + RESET_STIPPLE; + } + } else { + for (j=start+2;j<count;j++) { + RENDER_TRI( ELT(start), ELT(j-1), ELT(j) ); + } + } + + POSTFIX; +} + + +static void TAG(render_poly)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j = start+2; + LOCAL_VARS; + (void) flags; + + INIT(GL_POLYGON); + if (NEED_EDGEFLAG_SETUP) { + GLboolean efstart = EDGEFLAG_GET( ELT(start) ); + GLboolean efcount = EDGEFLAG_GET( ELT(count-1) ); + + /* If the primitive does not begin here, the first edge + * is non-boundary. + */ + if (!TEST_PRIM_BEGIN(flags)) + EDGEFLAG_SET( ELT(start), GL_FALSE ); + + /* If the primitive does not end here, the final edge is + * non-boundary. + */ + if (!TEST_PRIM_END(flags)) + EDGEFLAG_SET( ELT(count-1), GL_FALSE ); + + /* Draw the first triangles (possibly zero) + */ + if (j<count-1) { + GLboolean ef = EDGEFLAG_GET( ELT(j) ); + EDGEFLAG_SET( ELT(j), GL_FALSE ); + RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); + EDGEFLAG_SET( ELT(j), ef ); + j++; + + /* Don't render the first edge again: + */ + EDGEFLAG_SET( ELT(start), GL_FALSE ); + + for (;j<count-1;j++) { + GLboolean efj = EDGEFLAG_GET( ELT(j) ); + EDGEFLAG_SET( ELT(j), GL_FALSE ); + RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); + EDGEFLAG_SET( ELT(j), efj ); + } + } + + /* Draw the last or only triangle + */ + if (j < count) + RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); + + /* Restore the first and last edgeflags: + */ + EDGEFLAG_SET( ELT(count-1), efcount ); + EDGEFLAG_SET( ELT(start), efstart ); + + if (TEST_PRIM_END(flags)) { + RESET_STIPPLE; + } + } + else { + for (j=start+2;j<count;j++) { + RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); + } + } + POSTFIX; +} + +static void TAG(render_quads)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + INIT(GL_QUADS); + if (NEED_EDGEFLAG_SETUP) { + for (j=start+3; j<count; j+=4) { + /* Use user-specified edgeflags for quads. + */ + RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); + RESET_STIPPLE; + } + } else { + for (j=start+3; j<count; j+=4) { + RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); + } + } + POSTFIX; +} + +static void TAG(render_quad_strip)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + INIT(GL_QUAD_STRIP); + if (NEED_EDGEFLAG_SETUP) { + for (j=start+3;j<count;j+=2) { + /* All edges are boundary. Set edgeflags to 1, draw the + * quad, and restore them to the original values. + */ + GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) ); + GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) ); + GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) ); + GLboolean ef = EDGEFLAG_GET( ELT(j) ); + EDGEFLAG_SET( ELT(j-3), GL_TRUE ); + EDGEFLAG_SET( ELT(j-2), GL_TRUE ); + EDGEFLAG_SET( ELT(j-1), GL_TRUE ); + EDGEFLAG_SET( ELT(j), GL_TRUE ); + RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); + EDGEFLAG_SET( ELT(j-3), ef3 ); + EDGEFLAG_SET( ELT(j-2), ef2 ); + EDGEFLAG_SET( ELT(j-1), ef1 ); + EDGEFLAG_SET( ELT(j), ef ); + RESET_STIPPLE; + } + } else { + for (j=start+3;j<count;j+=2) { + RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); + } + } + POSTFIX; +} + +static void TAG(render_noop)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + (void)(ctx && start && count && flags); +} + +RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = +{ + TAG(render_points), + TAG(render_lines), + TAG(render_line_loop), + TAG(render_line_strip), + TAG(render_triangles), + TAG(render_tri_strip), + TAG(render_tri_fan), + TAG(render_quads), + TAG(render_quad_strip), + TAG(render_poly), + TAG(render_noop), +}; + + + +#ifndef PRESERVE_VB_DEFS +#undef RENDER_TRI +#undef RENDER_QUAD +#undef RENDER_LINE +#undef RENDER_POINTS +#undef LOCAL_VARS +#undef INIT +#undef POSTFIX +#undef RESET_STIPPLE +#undef DBG +#undef ELT +#undef RENDER_TAB_QUALIFIER +#endif + +#ifndef PRESERVE_TAG +#undef TAG +#endif + +#undef PRESERVE_VB_DEFS +#undef PRESERVE_TAG diff --git a/src/mesa/drivers/common/t_dd_triemit.h b/src/mesa/drivers/common/t_dd_triemit.h new file mode 100644 index 0000000000..2f5bcee7ec --- /dev/null +++ b/src/mesa/drivers/common/t_dd_triemit.h @@ -0,0 +1,157 @@ +#ifndef DO_DEBUG_VERTS +#define DO_DEBUG_VERTS 0 +#endif + +#ifndef PRINT_VERTEX +#define PRINT_VERTEX(x) +#endif + +#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 + + + +#if HAVE_QUADS +static __inline void TAG(quad)( CTX_ARG, + VERTEX *v0, + VERTEX *v1, + VERTEX *v2, + VERTEX *v3 ) +{ + GLuint vertsize = GET_VERTEX_DWORDS(); + GLuint *vb = (GLuint *)ALLOC_VERTS( 4, vertsize); + GLuint j; + + if (DO_DEBUG_VERTS) { + fprintf(stderr, "%s\n", __FUNCTION__); + PRINT_VERTEX(v0); + PRINT_VERTEX(v1); + PRINT_VERTEX(v2); + PRINT_VERTEX(v3); + } + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); + COPY_DWORDS( j, vb, vertsize, v3 ); +} +#else +static __inline void TAG(quad)( CTX_ARG, + VERTEX *v0, + VERTEX *v1, + VERTEX *v2, + VERTEX *v3 ) +{ + GLuint vertsize = GET_VERTEX_DWORDS(); + GLuint *vb = (GLuint *)ALLOC_VERTS( 6, vertsize); + GLuint j; + + if (DO_DEBUG_VERTS) { + fprintf(stderr, "%s\n", __FUNCTION__); + PRINT_VERTEX(v0); + PRINT_VERTEX(v1); + PRINT_VERTEX(v2); + PRINT_VERTEX(v3); + } + + 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 ); +} +#endif + + +static __inline void TAG(triangle)( CTX_ARG, + VERTEX *v0, + VERTEX *v1, + VERTEX *v2 ) +{ + GLuint vertsize = GET_VERTEX_DWORDS(); + GLuint *vb = (GLuint *)ALLOC_VERTS( 3, vertsize); + GLuint j; + + if (DO_DEBUG_VERTS) { + fprintf(stderr, "%s\n", __FUNCTION__); + PRINT_VERTEX(v0); + PRINT_VERTEX(v1); + PRINT_VERTEX(v2); + } + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); +} + + +#if HAVE_LINES +static __inline void TAG(line)( CTX_ARG, + VERTEX *v0, + VERTEX *v1 ) +{ + GLuint vertsize = GET_VERTEX_DWORDS(); + GLuint *vb = (GLuint *)ALLOC_VERTS( 2, vertsize); + GLuint j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); +} +#endif + +#if HAVE_POINTS +static __inline void TAG(point)( CTX_ARG, + VERTEX *v0 ) +{ + GLuint vertsize = GET_VERTEX_DWORDS(); + GLuint *vb = (GLuint *)ALLOC_VERTS( 1, vertsize); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); +} +#endif + + +static void TAG(fast_clipped_poly)( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + LOCAL_VARS + GLuint vertsize = GET_VERTEX_DWORDS(); + GLuint *vb = (GLuint *)ALLOC_VERTS( (n-2) * 3, vertsize ); + const GLuint *start = (const GLuint *)VERT(elts[0]); + int i,j; + + if (DO_DEBUG_VERTS) { + fprintf(stderr, "%s\n", __FUNCTION__); + PRINT_VERTEX(VERT(elts[0])); + PRINT_VERTEX(VERT(elts[1])); + } + + for (i = 2 ; i < n ; i++) { + if (DO_DEBUG_VERTS) { + PRINT_VERTEX(VERT(elts[i])); + } + + COPY_DWORDS( j, vb, vertsize, VERT(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, VERT(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, start ); + } +} + diff --git a/src/mesa/drivers/common/t_dd_tritmp.h b/src/mesa/drivers/common/t_dd_tritmp.h new file mode 100644 index 0000000000..b26347b77e --- /dev/null +++ b/src/mesa/drivers/common/t_dd_tritmp.h @@ -0,0 +1,743 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +/* Template for building functions to plug into the driver interface + * of t_vb_render.c: + * ctx->Driver.QuadFunc + * ctx->Driver.TriangleFunc + * ctx->Driver.LineFunc + * ctx->Driver.PointsFunc + * + * DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles, + * and restore vertices afterwards. + * DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore + * vertices after rendering. + * DO_FLAT: For hardware without native flatshading, copy provoking colors + * into the other vertices. Restore after rendering. + * DO_UNFILLED: Decompose triangles to lines and points where appropriate. + * + * HAVE_RGBA: Vertices have rgba values (otherwise index values). + * HAVE_SPEC: Vertices have secondary rgba values. + * + * VERT_X(v): Alias for vertex x value. + * VERT_Y(v): Alias for vertex y value. + * VERT_Z(v): Alias for vertex z value. + * DEPTH_SCALE: Scale for offset. + * + * VERTEX: Hardware vertex type. + * GET_VERTEX(n): Retreive vertex with index n. + * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw. + * + * VERT_SET_RGBA: Assign vertex rgba from VB color. + * VERT_COPY_RGBA: Copy vertex rgba another vertex. + * VERT_SAVE_RGBA: Save vertex rgba to a local variable. + * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable. + * --> Similar for IND and SPEC. + * + * LOCAL_VARS(n): (At least) define local vars for save/restore rgba. + * + */ + +#if HAVE_RGBA +#define VERT_SET_IND( v, c ) (void) c +#define VERT_COPY_IND( v0, v1 ) +#define VERT_SAVE_IND( idx ) +#define VERT_RESTORE_IND( idx ) +#if HAVE_BACK_COLORS +#define VERT_SET_RGBA( v, c ) +#endif +#else +#define VERT_SET_RGBA( v, c ) (void) c +#define VERT_COPY_RGBA( v0, v1 ) +#define VERT_SAVE_RGBA( idx ) +#define VERT_RESTORE_RGBA( idx ) +#if HAVE_BACK_COLORS +#define VERT_SET_IND( v, c ) +#endif +#endif + +#if !HAVE_SPEC +#define VERT_SET_SPEC( v, c ) (void) c +#define VERT_COPY_SPEC( v0, v1 ) +#define VERT_SAVE_SPEC( idx ) +#define VERT_RESTORE_SPEC( idx ) +#if HAVE_BACK_COLORS +#define VERT_COPY_SPEC1( v ) +#endif +#else +#if HAVE_BACK_COLORS +#define VERT_SET_SPEC( v, c ) +#endif +#endif + +#if !HAVE_BACK_COLORS +#define VERT_COPY_SPEC1( v ) +#define VERT_COPY_IND1( v ) +#define VERT_COPY_RGBA1( v ) +#endif + +#ifndef INSANE_VERTICES +#define VERT_SET_Z(v,val) VERT_Z(v) = val +#define VERT_Z_ADD(v,val) VERT_Z(v) += val +#endif + +#if DO_TRI +static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + VERTEX *v[3]; + GLfloat offset; + GLfloat z[3]; + GLenum mode = GL_FILL; + GLuint facing; + LOCAL_VARS(3); + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + + if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) + { + GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]); + GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]); + GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]); + GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]); + GLfloat cc = ex*fy - ey*fx; + + if (DO_TWOSIDE || DO_UNFILLED) + { + facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit; + + if (DO_UNFILLED) { + if (facing) { + mode = ctx->Polygon.BackMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_FRONT) { + return; + } + } else { + mode = ctx->Polygon.FrontMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_BACK) { + return; + } + } + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + if (HAVE_BACK_COLORS) { + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_COPY_RGBA1( v[0] ); + VERT_COPY_RGBA1( v[1] ); + } + VERT_SAVE_RGBA( 2 ); + VERT_COPY_RGBA1( v[2] ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_COPY_SPEC1( v[0] ); + VERT_COPY_SPEC1( v[1] ); + } + VERT_SAVE_SPEC( 2 ); + VERT_COPY_SPEC1( v[2] ); + } + } + else { + GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data; + ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat)); + (void) vbcolor; + + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SET_RGBA( v[0], vbcolor[e0] ); + VERT_SET_RGBA( v[1], vbcolor[e1] ); + } + VERT_SAVE_RGBA( 2 ); + VERT_SET_RGBA( v[2], vbcolor[e2] ); + + if (HAVE_SPEC && VB->SecondaryColorPtr[1]) { + GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data; + + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SET_SPEC( v[0], vbspec[e0] ); + VERT_SET_SPEC( v[1], vbspec[e1] ); + } + VERT_SAVE_SPEC( 2 ); + VERT_SET_SPEC( v[2], vbspec[e2] ); + } + } + } + else { + GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data; + if (!DO_FLAT) { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_SET_IND( v[0], vbindex[e0] ); + VERT_SET_IND( v[1], vbindex[e1] ); + } + VERT_SAVE_IND( 2 ); + VERT_SET_IND( v[2], vbindex[e2] ); + } + } + } + + + if (DO_OFFSET) + { + offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; + z[0] = VERT_Z(v[0]); + z[1] = VERT_Z(v[1]); + z[2] = VERT_Z(v[2]); + if (cc * cc > 1e-16) { + GLfloat ic = 1.0 / cc; + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + offset *= ctx->MRD; + } + } + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_COPY_RGBA( v[0], v[2] ); + VERT_COPY_RGBA( v[1], v[2] ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_COPY_SPEC( v[0], v[2] ); + VERT_COPY_SPEC( v[1], v[2] ); + } + } + else { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_COPY_IND( v[0], v[2] ); + VERT_COPY_IND( v[1], v[2] ); + } + } + + if (mode == GL_POINT) { + if (DO_OFFSET && ctx->Polygon.OffsetPoint) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + } + UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 ); + } else if (mode == GL_LINE) { + if (DO_OFFSET && ctx->Polygon.OffsetLine) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + } + UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 ); + } else { + if (DO_OFFSET && ctx->Polygon.OffsetFill) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + } + if (DO_UNFILLED) + RASTERIZE( GL_TRIANGLES ); + TRI( v[0], v[1], v[2] ); + } + + if (DO_OFFSET) + { + VERT_SET_Z(v[0], z[0]); + VERT_SET_Z(v[1], z[1]); + VERT_SET_Z(v[2], z[2]); + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + if (!DO_FLAT) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + } + VERT_RESTORE_RGBA( 2 ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + } + VERT_RESTORE_SPEC( 2 ); + } + } + else { + if (!DO_FLAT) { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + } + VERT_RESTORE_IND( 2 ); + } + } + + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + } + } + else { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + } + } +} +#endif + +#if DO_QUAD +#if DO_FULL_QUAD +static void TAG(quad)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, GLuint e3 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + VERTEX *v[4]; + GLfloat offset; + GLfloat z[4]; + GLenum mode = GL_FILL; + GLuint facing; + LOCAL_VARS(4); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + v[3] = (VERTEX *)GET_VERTEX(e3); + + if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) + { + GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]); + GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]); + GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]); + GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]); + GLfloat cc = ex*fy - ey*fx; + + if (DO_TWOSIDE || DO_UNFILLED) + { + facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit; + + if (DO_UNFILLED) { + if (facing) { + mode = ctx->Polygon.BackMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_FRONT) { + return; + } + } else { + mode = ctx->Polygon.FrontMode; + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode != GL_BACK) { + return; + } + } + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data; + (void)vbcolor; + + if (HAVE_BACK_COLORS) { + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SAVE_RGBA( 2 ); + VERT_COPY_RGBA1( v[0] ); + VERT_COPY_RGBA1( v[1] ); + VERT_COPY_RGBA1( v[2] ); + } + VERT_SAVE_RGBA( 3 ); + VERT_COPY_RGBA1( v[3] ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SAVE_SPEC( 2 ); + VERT_COPY_SPEC1( v[0] ); + VERT_COPY_SPEC1( v[1] ); + VERT_COPY_SPEC1( v[2] ); + } + VERT_SAVE_SPEC( 3 ); + VERT_COPY_SPEC1( v[3] ); + } + } + else { + if (!DO_FLAT) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SAVE_RGBA( 2 ); + VERT_SET_RGBA( v[0], vbcolor[e0] ); + VERT_SET_RGBA( v[1], vbcolor[e1] ); + VERT_SET_RGBA( v[2], vbcolor[e2] ); + } + VERT_SAVE_RGBA( 3 ); + VERT_SET_RGBA( v[3], vbcolor[e3] ); + + if (HAVE_SPEC && VB->SecondaryColorPtr[1]) { + GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data; + ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat)); + + if (!DO_FLAT) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SAVE_SPEC( 2 ); + VERT_SET_SPEC( v[0], vbspec[e0] ); + VERT_SET_SPEC( v[1], vbspec[e1] ); + VERT_SET_SPEC( v[2], vbspec[e2] ); + } + VERT_SAVE_SPEC( 3 ); + VERT_SET_SPEC( v[3], vbspec[e3] ); + } + } + } + else { + GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data; + if (!DO_FLAT) { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_SAVE_IND( 2 ); + VERT_SET_IND( v[0], vbindex[e0] ); + VERT_SET_IND( v[1], vbindex[e1] ); + VERT_SET_IND( v[2], vbindex[e2] ); + } + VERT_SAVE_IND( 3 ); + VERT_SET_IND( v[3], vbindex[e3] ); + } + } + } + + + if (DO_OFFSET) + { + offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; + z[0] = VERT_Z(v[0]); + z[1] = VERT_Z(v[1]); + z[2] = VERT_Z(v[2]); + z[3] = VERT_Z(v[3]); + if (cc * cc > 1e-16) { + GLfloat ez = z[2] - z[0]; + GLfloat fz = z[3] - z[1]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + offset *= ctx->MRD; + } + } + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA( 0 ); + VERT_SAVE_RGBA( 1 ); + VERT_SAVE_RGBA( 2 ); + VERT_COPY_RGBA( v[0], v[3] ); + VERT_COPY_RGBA( v[1], v[3] ); + VERT_COPY_RGBA( v[2], v[3] ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_SAVE_SPEC( 0 ); + VERT_SAVE_SPEC( 1 ); + VERT_SAVE_SPEC( 2 ); + VERT_COPY_SPEC( v[0], v[3] ); + VERT_COPY_SPEC( v[1], v[3] ); + VERT_COPY_SPEC( v[2], v[3] ); + } + } + else { + VERT_SAVE_IND( 0 ); + VERT_SAVE_IND( 1 ); + VERT_SAVE_IND( 2 ); + VERT_COPY_IND( v[0], v[3] ); + VERT_COPY_IND( v[1], v[3] ); + VERT_COPY_IND( v[2], v[3] ); + } + } + + if (mode == GL_POINT) { + if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + VERT_Z_ADD(v[3], offset); + } + UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 ); + } else if (mode == GL_LINE) { + if (DO_OFFSET && ctx->Polygon.OffsetLine) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + VERT_Z_ADD(v[3], offset); + } + UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 ); + } else { + if (DO_OFFSET && ctx->Polygon.OffsetFill) { + VERT_Z_ADD(v[0], offset); + VERT_Z_ADD(v[1], offset); + VERT_Z_ADD(v[2], offset); + VERT_Z_ADD(v[3], offset); + } + RASTERIZE( GL_TRIANGLES ); + QUAD( (v[0]), (v[1]), (v[2]), (v[3]) ); + } + + if (DO_OFFSET) + { + VERT_SET_Z(v[0], z[0]); + VERT_SET_Z(v[1], z[1]); + VERT_SET_Z(v[2], z[2]); + VERT_SET_Z(v[3], z[3]); + } + + if (DO_TWOSIDE && facing == 1) + { + if (HAVE_RGBA) { + if (!DO_FLAT) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + VERT_RESTORE_RGBA( 2 ); + } + VERT_RESTORE_RGBA( 3 ); + if (HAVE_SPEC) { + if (!DO_FLAT) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + VERT_RESTORE_SPEC( 2 ); + } + VERT_RESTORE_SPEC( 3 ); + } + } + else { + if (!DO_FLAT) { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + VERT_RESTORE_IND( 2 ); + } + VERT_RESTORE_IND( 3 ); + } + } + + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA( 0 ); + VERT_RESTORE_RGBA( 1 ); + VERT_RESTORE_RGBA( 2 ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_RESTORE_SPEC( 0 ); + VERT_RESTORE_SPEC( 1 ); + VERT_RESTORE_SPEC( 2 ); + } + } + else { + VERT_RESTORE_IND( 0 ); + VERT_RESTORE_IND( 1 ); + VERT_RESTORE_IND( 2 ); + } + } +} +#else +static void TAG(quad)( GLcontext *ctx, GLuint e0, + GLuint e1, GLuint e2, GLuint e3 ) +{ + if (DO_UNFILLED) { + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte ef1 = VB->EdgeFlag[e1]; + GLubyte ef3 = VB->EdgeFlag[e3]; + VB->EdgeFlag[e1] = 0; + TAG(triangle)( ctx, e0, e1, e3 ); + VB->EdgeFlag[e1] = ef1; + VB->EdgeFlag[e3] = 0; + TAG(triangle)( ctx, e1, e2, e3 ); + VB->EdgeFlag[e3] = ef3; + } else { + TAG(triangle)( ctx, e0, e1, e3 ); + TAG(triangle)( ctx, e1, e2, e3 ); + } +} +#endif +#endif + +#if DO_LINE +static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + VERTEX *v[2]; + LOCAL_VARS(2); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA( 0 ); + VERT_COPY_RGBA( v[0], v[1] ); + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_SAVE_SPEC( 0 ); + VERT_COPY_SPEC( v[0], v[1] ); + } + } + else { + VERT_SAVE_IND( 0 ); + VERT_COPY_IND( v[0], v[1] ); + } + } + + LINE( v[0], v[1] ); + + if (DO_FLAT) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA( 0 ); + + if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { + VERT_RESTORE_SPEC( 0 ); + } + } + else { + VERT_RESTORE_IND( 0 ); + } + } +} +#endif + +#if DO_POINTS +static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; + int i; + LOCAL_VARS(1); + + if (VB->Elts == 0) { + for ( i = first ; i < last ; i++ ) { + if ( VB->ClipMask[i] == 0 ) { + VERTEX *v = (VERTEX *)GET_VERTEX(i); + POINT( v ); + } + } + } else { + for ( i = first ; i < last ; i++ ) { + GLuint e = VB->Elts[i]; + if ( VB->ClipMask[e] == 0 ) { + VERTEX *v = (VERTEX *)GET_VERTEX(e); + POINT( v ); + } + } + } +} +#endif + +static void TAG(init)( void ) +{ +#if DO_QUAD + TAB[IND].quad = TAG(quad); +#endif +#if DO_TRI + TAB[IND].triangle = TAG(triangle); +#endif +#if DO_LINE + TAB[IND].line = TAG(line); +#endif +#if DO_POINTS + TAB[IND].points = TAG(points); +#endif +} + +#undef IND +#undef TAG + +#if HAVE_RGBA +#undef VERT_SET_IND +#undef VERT_COPY_IND +#undef VERT_SAVE_IND +#undef VERT_RESTORE_IND +#if HAVE_BACK_COLORS +#undef VERT_SET_RGBA +#endif +#else +#undef VERT_SET_RGBA +#undef VERT_COPY_RGBA +#undef VERT_SAVE_RGBA +#undef VERT_RESTORE_RGBA +#if HAVE_BACK_COLORS +#undef VERT_SET_IND +#endif +#endif + +#if !HAVE_SPEC +#undef VERT_SET_SPEC +#undef VERT_COPY_SPEC +#undef VERT_SAVE_SPEC +#undef VERT_RESTORE_SPEC +#if HAVE_BACK_COLORS +#undef VERT_COPY_SPEC1 +#endif +#else +#if HAVE_BACK_COLORS +#undef VERT_SET_SPEC +#endif +#endif + +#if !HAVE_BACK_COLORS +#undef VERT_COPY_SPEC1 +#undef VERT_COPY_IND1 +#undef VERT_COPY_RGBA1 +#endif + +#ifndef INSANE_VERTICES +#undef VERT_SET_Z +#undef VERT_Z_ADD +#endif diff --git a/src/mesa/drivers/common/t_dd_unfilled.h b/src/mesa/drivers/common/t_dd_unfilled.h new file mode 100644 index 0000000000..46415ea5f6 --- /dev/null +++ b/src/mesa/drivers/common/t_dd_unfilled.h @@ -0,0 +1,212 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#if HAVE_RGBA +#define VERT_SET_IND( v, c ) +#define VERT_COPY_IND( v0, v1 ) +#define VERT_SAVE_IND( idx ) +#define VERT_RESTORE_IND( idx ) +#endif + +#if !HAVE_SPEC +#define VERT_SET_SPEC( v, c ) +#define VERT_COPY_SPEC( v0, v1 ) +#define VERT_SAVE_SPEC( idx ) +#define VERT_RESTORE_SPEC( idx ) +#endif + +static void TAG(unfilled_tri)( GLcontext *ctx, + GLenum mode, + GLuint e0, GLuint e1, GLuint e2 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ef = VB->EdgeFlag; + VERTEX *v[3]; + LOCAL_VARS(3); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA(0); + VERT_SAVE_RGBA(1); + VERT_COPY_RGBA(v[0], v[2]); + VERT_COPY_RGBA(v[1], v[2]); + + if (HAVE_SPEC) { + VERT_SAVE_SPEC(0); + VERT_SAVE_SPEC(1); + VERT_COPY_SPEC(v[0], v[2]); + VERT_COPY_SPEC(v[1], v[2]); + } + } else { + VERT_SAVE_IND(0); + VERT_SAVE_IND(1); + VERT_COPY_IND(v[0], v[2]); + VERT_COPY_IND(v[1], v[2]); + } + } + +/* fprintf(stderr, "%s %s %d %d %d\n", __FUNCTION__, */ +/* _mesa_lookup_enum_by_nr( mode ), */ +/* ef[e0], ef[e1], ef[e2]); */ + + if (mode == GL_POINT) { + RASTERIZE(GL_POINTS); + if (ef[e0]) POINT( v[0] ); + if (ef[e1]) POINT( v[1] ); + if (ef[e2]) POINT( v[2] ); + } + else { + RASTERIZE(GL_LINES); + if (RENDER_PRIMITIVE == GL_POLYGON) { + if (ef[e2]) LINE( v[2], v[0] ); + if (ef[e0]) LINE( v[0], v[1] ); + if (ef[e1]) LINE( v[1], v[2] ); + } + else { + if (ef[e0]) LINE( v[0], v[1] ); + if (ef[e1]) LINE( v[1], v[2] ); + if (ef[e2]) LINE( v[2], v[0] ); + } + } + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA(0); + VERT_RESTORE_RGBA(1); + + if (HAVE_SPEC) { + VERT_RESTORE_SPEC(0); + VERT_RESTORE_SPEC(1); + } + } else { + VERT_RESTORE_IND(0); + VERT_RESTORE_IND(1); + } + } +} + + +static void TAG(unfilled_quad)( GLcontext *ctx, + GLenum mode, + GLuint e0, GLuint e1, + GLuint e2, GLuint e3 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ef = VB->EdgeFlag; + VERTEX *v[4]; + LOCAL_VARS(4); + + v[0] = (VERTEX *)GET_VERTEX(e0); + v[1] = (VERTEX *)GET_VERTEX(e1); + v[2] = (VERTEX *)GET_VERTEX(e2); + v[3] = (VERTEX *)GET_VERTEX(e3); + + /* Hardware flatshading breaks down here. If the hardware doesn't + * support flatshading, this will already have been done: + */ + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_SAVE_RGBA(0); + VERT_SAVE_RGBA(1); + VERT_SAVE_RGBA(2); + VERT_COPY_RGBA(v[0], v[3]); + VERT_COPY_RGBA(v[1], v[3]); + VERT_COPY_RGBA(v[2], v[3]); + + if (HAVE_SPEC) { + VERT_SAVE_SPEC(0); + VERT_SAVE_SPEC(1); + VERT_SAVE_SPEC(2); + VERT_COPY_SPEC(v[0], v[3]); + VERT_COPY_SPEC(v[1], v[3]); + VERT_COPY_SPEC(v[2], v[3]); + } + } else { + VERT_SAVE_IND(0); + VERT_SAVE_IND(1); + VERT_SAVE_IND(2); + VERT_COPY_IND(v[0], v[3]); + VERT_COPY_IND(v[1], v[3]); + VERT_COPY_IND(v[2], v[3]); + } + } + + if (mode == GL_POINT) { + RASTERIZE(GL_POINTS); + if (ef[e0]) POINT( v[0] ); + if (ef[e1]) POINT( v[1] ); + if (ef[e2]) POINT( v[2] ); + if (ef[e3]) POINT( v[3] ); + } + else { + RASTERIZE(GL_LINES); + if (ef[e0]) LINE( v[0], v[1] ); + if (ef[e1]) LINE( v[1], v[2] ); + if (ef[e2]) LINE( v[2], v[3] ); + if (ef[e3]) LINE( v[3], v[0] ); + } + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { + if (HAVE_RGBA) { + VERT_RESTORE_RGBA(0); + VERT_RESTORE_RGBA(1); + VERT_RESTORE_RGBA(2); + + if (HAVE_SPEC) { + VERT_RESTORE_SPEC(0); + VERT_RESTORE_SPEC(1); + VERT_RESTORE_SPEC(2); + } + } else { + VERT_RESTORE_IND(0); + VERT_RESTORE_IND(1); + VERT_RESTORE_IND(2); + } + } +} + + +#if HAVE_RGBA +#undef VERT_SET_IND +#undef VERT_COPY_IND +#undef VERT_SAVE_IND +#undef VERT_RESTORE_IND +#endif + +#if !HAVE_SPEC +#undef VERT_SET_SPEC +#undef VERT_COPY_SPEC +#undef VERT_SAVE_SPEC +#undef VERT_RESTORE_SPEC +#endif + +#undef TAG diff --git a/src/mesa/drivers/common/t_dd_vb.c b/src/mesa/drivers/common/t_dd_vb.c new file mode 100644 index 0000000000..380b0424b4 --- /dev/null +++ b/src/mesa/drivers/common/t_dd_vb.c @@ -0,0 +1,344 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ +#include "math/m_translate.h" + +#if (HAVE_HW_VIEWPORT) +#define UNVIEWPORT_VARS +#define UNVIEWPORT_X(x) x +#define UNVIEWPORT_Y(x) x +#define UNVIEWPORT_Z(x) x +#endif + +#ifndef LOCALVARS +#define LOCALVARS +#endif + +#ifndef CHECK_HW_DIVIDE +#define CHECK_HW_DIVIDE 1 +#endif + +/* These don't need to be duplicated, but there's currently nowhere + * really convenient to put them. Need to build some actual .o files in + * this directory? + */ +static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + LOCALVARS + GLubyte *verts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + GLuint *dst = (GLuint *)(verts + (edst << shift)); + GLuint *src = (GLuint *)(verts + (esrc << shift)); + dst[4] = src[4]; + dst[5] = src[5]; +} + +static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + LOCALVARS + GLubyte *verts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + GLuint *dst = (GLuint *)(verts + (edst << shift)); + GLuint *src = (GLuint *)(verts + (esrc << shift)); + dst[4] = src[4]; +} + +static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + LOCALVARS + GLubyte *verts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + GLuint *dst = (GLuint *)(verts + (edst << shift)); + GLuint *src = (GLuint *)(verts + (esrc << shift)); + dst[3] = src[3]; +} + + +void TAG(translate_vertex)(GLcontext *ctx, + const VERTEX *src, + SWvertex *dst) +{ + LOCALVARS + GLuint format = GET_VERTEX_FORMAT(); + GLfloat *s = ctx->Viewport._WindowMap.m; + UNVIEWPORT_VARS; + + if (format == TINY_VERTEX_FORMAT) { + if (HAVE_HW_VIEWPORT) { + dst->win[0] = s[0] * src->v.x + s[12]; + dst->win[1] = s[5] * src->v.y + s[13]; + dst->win[2] = s[10] * src->v.z + s[14]; + dst->win[3] = 1.0; + } else { + dst->win[0] = UNVIEWPORT_X( src->v.x ); + dst->win[1] = UNVIEWPORT_Y( src->v.y ); + dst->win[2] = UNVIEWPORT_Z( src->v.z ); + dst->win[3] = 1.0; + } + + dst->color[0] = src->tv.color.red; + dst->color[1] = src->tv.color.green; + dst->color[2] = src->tv.color.blue; + dst->color[3] = src->tv.color.alpha; + } + else { + if (HAVE_HW_VIEWPORT) { + if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { + GLfloat oow = 1.0 / src->v.w; + dst->win[0] = s[0] * src->v.x * oow + s[12]; + dst->win[1] = s[5] * src->v.y * oow + s[13]; + dst->win[2] = s[10] * src->v.z * oow + s[14]; + dst->win[3] = oow; + } else { + dst->win[0] = s[0] * src->v.x + s[12]; + dst->win[1] = s[5] * src->v.y + s[13]; + dst->win[2] = s[10] * src->v.z + s[14]; + dst->win[3] = src->v.w; + } + } else { + dst->win[0] = UNVIEWPORT_X( src->v.x ); + dst->win[1] = UNVIEWPORT_Y( src->v.y ); + dst->win[2] = UNVIEWPORT_Z( src->v.z ); + dst->win[3] = src->v.w; + } + + dst->color[0] = src->v.color.red; + dst->color[1] = src->v.color.green; + dst->color[2] = src->v.color.blue; + dst->color[3] = src->v.color.alpha; + + dst->specular[0] = src->v.specular.red; + dst->specular[1] = src->v.specular.green; + dst->specular[2] = src->v.specular.blue; + + dst->fog = src->v.specular.alpha/255.0; + + if (HAVE_PTEX_VERTICES && + ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) || + (format == PROJ_TEX1_VERTEX_FORMAT))) { + + dst->texcoord[0][0] = src->pv.u0; + dst->texcoord[0][1] = src->pv.v0; + dst->texcoord[0][3] = src->pv.q0; + + dst->texcoord[1][0] = src->pv.u1; + dst->texcoord[1][1] = src->pv.v1; + dst->texcoord[1][3] = src->pv.q1; + + if (HAVE_TEX2_VERTICES) { + dst->texcoord[2][0] = src->pv.u2; + dst->texcoord[2][1] = src->pv.v2; + dst->texcoord[2][3] = src->pv.q2; + } + + if (HAVE_TEX3_VERTICES) { + dst->texcoord[3][0] = src->pv.u3; + dst->texcoord[3][1] = src->pv.v3; + dst->texcoord[3][3] = src->pv.q3; + } + } + else { + dst->texcoord[0][0] = src->v.u0; + dst->texcoord[0][1] = src->v.v0; + dst->texcoord[0][3] = 1.0; + + dst->texcoord[1][0] = src->v.u1; + dst->texcoord[1][1] = src->v.v1; + dst->texcoord[1][3] = 1.0; + + if (HAVE_TEX2_VERTICES) { + dst->texcoord[2][0] = src->v.u2; + dst->texcoord[2][1] = src->v.v2; + dst->texcoord[2][3] = 1.0; + } + + if (HAVE_TEX3_VERTICES) { + dst->texcoord[3][0] = src->v.u3; + dst->texcoord[3][1] = src->v.v3; + dst->texcoord[3][3] = 1.0; + } + } + } + + dst->pointSize = ctx->Point._Size; +} + + + +void TAG(print_vertex)( GLcontext *ctx, const VERTEX *v ) +{ + LOCALVARS + GLuint format = GET_VERTEX_FORMAT(); + + fprintf(stderr, "(%x) ", format); + + switch (format) { +#if HAVE_TINY_VERTICES + case TINY_VERTEX_FORMAT: + fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n", + v->v.x, v->v.y, v->v.z, + v->tv.color.red, + v->tv.color.green, + v->tv.color.blue, + v->tv.color.alpha); + break; +#endif +#if HAVE_NOTEX_VERTICES + case NOTEX_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->v.specular.red, + v->v.specular.green, + v->v.specular.blue, + v->v.specular.alpha); + break; +#endif +#if HAVE_TEX0_VERTICES + case TEX0_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->v.u0, + v->v.v0); + break; +#endif +#if HAVE_TEX1_VERTICES + case TEX1_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->v.u0, + v->v.v0, + v->v.u1, + v->v.u2); + break; +#endif +#if HAVE_PTEX_VERTICES + case PROJ_TEX1_VERTEX_FORMAT: + fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n", + v->v.x, v->v.y, v->v.z, v->v.w, + v->v.color.red, + v->v.color.green, + v->v.color.blue, + v->v.color.alpha, + v->pv.u0, + v->pv.v0, + v->pv.q0, + v->pv.u1, + v->pv.v1, + v->pv.q1); + break; +#endif + default: + fprintf(stderr, "???\n"); + break; + } + + fprintf(stderr, "\n"); +} + + + +/* Interpolate the elements of the VB not included in typical hardware + * vertices. + * + * NOTE: All these arrays are guarenteed by tnl to be writeable and + * have good stride. + */ +#ifndef INTERP_QUALIFIER +#define INTERP_QUALIFIER static +#endif + +#define GET_COLOR(ptr, idx) ((ptr)->data[idx]) + + +INTERP_QUALIFIER void TAG(interp_extras)( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat)); + + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); + } + } + + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + + INTERP_VERTEX(ctx, t, dst, out, in, force_boundary); +} + +INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx, + GLuint dst, GLuint src ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); + + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } + + COPY_PV_VERTEX(ctx, dst, src); +} + + +#undef INTERP_QUALIFIER +#undef GET_COLOR + +#undef IND +#undef TAG diff --git a/src/mesa/drivers/common/t_dd_vbtmp.h b/src/mesa/drivers/common/t_dd_vbtmp.h new file mode 100644 index 0000000000..14b4a28651 --- /dev/null +++ b/src/mesa/drivers/common/t_dd_vbtmp.h @@ -0,0 +1,679 @@ + +/* + * Mesa 3-D graphics library + * Version: 5.0.1 + * + * Copyright (C) 1999-2003 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +/* Unlike the other templates here, this assumes quite a bit about the + * underlying hardware. Specifically it assumes a d3d-like vertex + * format, with a layout more or less constrained to look like the + * following: + * + * union { + * struct { + * float x, y, z, w; + * struct { char r, g, b, a; } color; + * struct { char r, g, b, fog; } spec; + * float u0, v0; + * float u1, v1; + * float u2, v2; + * float u3, v3; + * } v; + * struct { + * float x, y, z, w; + * struct { char r, g, b, a; } color; + * struct { char r, g, b, fog; } spec; + * float u0, v0, q0; + * float u1, v1, q1; + * float u2, v2, q2; + * float u3, v3, q3; + * } pv; + * struct { + * float x, y, z; + * struct { char r, g, b, a; } color; + * } tv; + * float f[16]; + * unsigned int ui[16]; + * unsigned char ub4[4][16]; + * } + * + + * VERTEX: hw vertex type as above + * VERTEX_COLOR: hw color struct type in VERTEX + * + * DO_XYZW: Emit xyz and maybe w coordinates. + * DO_RGBA: Emit color. + * DO_SPEC: Emit specular color. + * DO_FOG: Emit fog coordinate in specular alpha. + * DO_TEX0: Emit tex0 u,v coordinates. + * DO_TEX1: Emit tex1 u,v coordinates. + * DO_TEX2: Emit tex2 u,v coordinates. + * DO_TEX3: Emit tex3 u,v coordinates. + * DO_PTEX: Emit tex0,1,2,3 q coordinates where possible. + * + * HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra). + * + * HAVE_HW_VIEWPORT: Hardware performs viewport transform. + * HAVE_HW_DIVIDE: Hardware performs perspective divide. + * + * HAVE_TINY_VERTICES: Hardware understands v.tv format. + * HAVE_PTEX_VERTICES: Hardware understands v.pv format. + * HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0. + * + * Additionally, this template assumes it is emitting *transformed* + * vertices; the modifications to emit untransformed vertices (ie. to + * t&l hardware) are probably too great to cooexist with the code + * already in this file. + * + * NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if + * only TEX0 is enabled, in order to maintain a vertex size which is + * an exact number of quadwords. + */ + +#if (HAVE_HW_VIEWPORT) +#define VIEWPORT_X(dst,x) dst = x +#define VIEWPORT_Y(dst,y) dst = y +#define VIEWPORT_Z(dst,z) dst = z +#else +#define VIEWPORT_X(dst,x) dst = s[0] * x + s[12] +#define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13] +#define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14] +#endif + +#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES) +#error "can't cope with this combination" +#endif + +#ifndef LOCALVARS +#define LOCALVARS +#endif + +#ifndef CHECK_HW_DIVIDE +#define CHECK_HW_DIVIDE 1 +#endif + +#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES) + +static void TAG(emit)( GLcontext *ctx, + GLuint start, GLuint end, + void *dest, + GLuint stride ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4]; + GLfloat (*tc2)[4], (*tc3)[4]; + GLfloat (*col)[4], (*spec)[4]; + GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride; + GLuint tc2_stride, tc3_stride; + GLuint tc0_size, tc1_size; + GLuint tc2_size, tc3_size; + GLfloat (*coord)[4]; + GLuint coord_stride; + VERTEX *v = (VERTEX *)dest; + const GLfloat *s = GET_VIEWPORT_MAT(); + const GLubyte *mask = VB->ClipMask; + int i; + +/* fprintf(stderr, "%s(big) importable %d %d..%d\n", */ +/* __FUNCTION__, VB->importable_data, start, end); */ + + if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { + (void) s; + coord = VB->ClipPtr->data; + coord_stride = VB->ClipPtr->stride; + } + else { + coord = VB->NdcPtr->data; + coord_stride = VB->NdcPtr->stride; + } + + if (DO_TEX3) { + const GLuint t3 = GET_TEXSOURCE(3); + tc3 = VB->TexCoordPtr[t3]->data; + tc3_stride = VB->TexCoordPtr[t3]->stride; + if (DO_PTEX) + tc3_size = VB->TexCoordPtr[t3]->size; + } + + if (DO_TEX2) { + const GLuint t2 = GET_TEXSOURCE(2); + tc2 = VB->TexCoordPtr[t2]->data; + tc2_stride = VB->TexCoordPtr[t2]->stride; + if (DO_PTEX) + tc2_size = VB->TexCoordPtr[t2]->size; + } + + if (DO_TEX1) { + const GLuint t1 = GET_TEXSOURCE(1); + tc1 = VB->TexCoordPtr[t1]->data; + tc1_stride = VB->TexCoordPtr[t1]->stride; + if (DO_PTEX) + tc1_size = VB->TexCoordPtr[t1]->size; + } + + if (DO_TEX0) { + const GLuint t0 = GET_TEXSOURCE(0); + tc0_stride = VB->TexCoordPtr[t0]->stride; + tc0 = VB->TexCoordPtr[t0]->data; + if (DO_PTEX) + tc0_size = VB->TexCoordPtr[t0]->size; + } + + if (DO_RGBA) { + col_stride = VB->ColorPtr[0]->stride; + col = VB->ColorPtr[0]->data; + } + + if (DO_SPEC) { + if (VB->SecondaryColorPtr[0]) { + spec_stride = VB->SecondaryColorPtr[0]->stride; + spec = VB->SecondaryColorPtr[0]->data; + } else { + spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; + spec_stride = 0; + } + } + + if (DO_FOG) { + if (VB->FogCoordPtr) { + fog = VB->FogCoordPtr->data; + fog_stride = VB->FogCoordPtr->stride; + } + else { + static GLfloat tmp[4] = {0, 0, 0, 0}; + fog = &tmp; + fog_stride = 0; + } + } + + /* May have nonstandard strides: + */ + if (start) { + STRIDE_4F(coord, start * coord_stride); + if (DO_TEX0) + STRIDE_4F(tc0, start * tc0_stride); + if (DO_TEX1) + STRIDE_4F(tc1, start * tc1_stride); + if (DO_TEX2) + STRIDE_4F(tc2, start * tc2_stride); + if (DO_TEX3) + STRIDE_4F(tc3, start * tc3_stride); + if (DO_RGBA) + STRIDE_4F(col, start * col_stride); + if (DO_SPEC) + STRIDE_4F(spec, start * spec_stride); + if (DO_FOG) + STRIDE_4F(fog, start * fog_stride); + } + + for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) { + if (DO_XYZW) { + if (HAVE_HW_VIEWPORT || mask[i] == 0) { + VIEWPORT_X(v->v.x, coord[0][0]); + VIEWPORT_Y(v->v.y, coord[0][1]); + VIEWPORT_Z(v->v.z, coord[0][2]); + v->v.w = coord[0][3]; + } + STRIDE_4F(coord, coord_stride); + } + if (DO_RGBA) { + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]); + STRIDE_4F(col, col_stride); + } + if (DO_SPEC) { + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]); + STRIDE_4F(spec, spec_stride); + } + if (DO_FOG) { + UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]); + STRIDE_4F(fog, fog_stride); + } + if (DO_TEX0) { + v->v.u0 = tc0[0][0]; + v->v.v0 = tc0[0][1]; + if (DO_PTEX) { + if (HAVE_PTEX_VERTICES) { + if (tc0_size == 4) + v->pv.q0 = tc0[0][3]; + else + v->pv.q0 = 1.0; + } + else if (tc0_size == 4) { + float rhw = 1.0 / tc0[0][3]; + v->v.w *= tc0[0][3]; + v->v.u0 *= rhw; + v->v.v0 *= rhw; + } + } + STRIDE_4F(tc0, tc0_stride); + } + if (DO_TEX1) { + if (DO_PTEX) { + v->pv.u1 = tc1[0][0]; + v->pv.v1 = tc1[0][1]; + if (tc1_size == 4) + v->pv.q1 = tc1[0][3]; + else + v->pv.q1 = 1.0; + } + else { + v->v.u1 = tc1[0][0]; + v->v.v1 = tc1[0][1]; + } + STRIDE_4F(tc1, tc1_stride); + } + else if (DO_PTEX) { + *(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */ + } + if (DO_TEX2) { + if (DO_PTEX) { + v->pv.u2 = tc2[0][0]; + v->pv.v2 = tc2[0][1]; + if (tc2_size == 4) + v->pv.q2 = tc2[0][3]; + else + v->pv.q2 = 1.0; + } + else { + v->v.u2 = tc2[0][0]; + v->v.v2 = tc2[0][1]; + } + STRIDE_4F(tc2, tc2_stride); + } + if (DO_TEX3) { + if (DO_PTEX) { + v->pv.u3 = tc3[0][0]; + v->pv.v3 = tc3[0][1]; + if (tc3_size == 4) + v->pv.q3 = tc3[0][3]; + else + v->pv.q3 = 1.0; + } + else { + v->v.u3 = tc3[0][0]; + v->v.v3 = tc3[0][1]; + } + STRIDE_4F(tc3, tc3_stride); + } + } + +} +#else + +#if HAVE_HW_DIVIDE +#error "cannot use tiny vertices with hw perspective divide" +#endif + +static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, + void *dest, GLuint stride ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLfloat (*col)[4]; + GLuint col_stride; + GLfloat (*coord)[4] = VB->NdcPtr->data; + GLuint coord_stride = VB->NdcPtr->stride; + GLfloat *v = (GLfloat *)dest; + const GLubyte *mask = VB->ClipMask; + const GLfloat *s = GET_VIEWPORT_MAT(); + int i; + + (void) s; + + ASSERT(stride == 4); + + col = VB->ColorPtr[0]->data; + col_stride = VB->ColorPtr[0]->stride; + +/* fprintf(stderr, "%s(small) importable %x\n", */ +/* __FUNCTION__, VB->importable_data); */ + + /* Pack what's left into a 4-dword vertex. Color is in a different + * place, and there is no 'w' coordinate. + */ + if (start) { + STRIDE_4F(coord, start * coord_stride); + STRIDE_4F(col, start * col_stride); + } + + for (i=start; i < end; i++, v+=4) { + if (DO_XYZW) { + if (HAVE_HW_VIEWPORT || mask[i] == 0) { + VIEWPORT_X(v[0], coord[0][0]); + VIEWPORT_Y(v[1], coord[0][1]); + VIEWPORT_Z(v[2], coord[0][2]); + } + STRIDE_4F( coord, coord_stride ); + } + if (DO_RGBA) { + VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3]; + UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]); + UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]); + UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]); + STRIDE_4F( col, col_stride ); + } +/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */ +/* i, v[0], v[1], v[2], *(int *)&v[3]); */ + } +} + +#endif /* emit */ + +#if (DO_XYZW) && (DO_RGBA) + + +#if (HAVE_PTEX_VERTICES) +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* Force 'missing' texcoords to something valid. + */ + if (DO_TEX3 && VB->TexCoordPtr[2] == 0) + VB->TexCoordPtr[2] = VB->TexCoordPtr[3]; + + if (DO_TEX2 && VB->TexCoordPtr[1] == 0) + VB->TexCoordPtr[1] = VB->TexCoordPtr[2]; + + if (DO_TEX1 && VB->TexCoordPtr[0] == 0) + VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; + + if (DO_PTEX) + return GL_TRUE; + + if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) || + (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) || + (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) || + (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4)) + return GL_FALSE; + + return GL_TRUE; +} +#else +static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* Force 'missing' texcoords to something valid. + */ + if (DO_TEX3 && VB->TexCoordPtr[2] == 0) + VB->TexCoordPtr[2] = VB->TexCoordPtr[3]; + + if (DO_TEX2 && VB->TexCoordPtr[1] == 0) + VB->TexCoordPtr[1] = VB->TexCoordPtr[2]; + + if (DO_TEX1 && VB->TexCoordPtr[0] == 0) + VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; + + if (DO_PTEX) + return GL_TRUE; + + /* No hardware support for projective texture. Can fake it for + * TEX0 only. + */ + if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) || + (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) || + (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) { + PTEX_FALLBACK(); + return GL_FALSE; + } + + if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) { + if (DO_TEX1 || DO_TEX2 || DO_TEX3) { + PTEX_FALLBACK(); + } + return GL_FALSE; + } + + return GL_TRUE; +} +#endif /* ptex */ + + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + LOCALVARS + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ddverts = GET_VERTEX_STORE(); + GLuint shift = GET_VERTEX_STRIDE_SHIFT(); + const GLfloat *dstclip = VB->ClipPtr->data[edst]; + GLfloat w; + const GLfloat *s = GET_VIEWPORT_MAT(); + + VERTEX *dst = (VERTEX *)(ddverts + (edst << shift)); + VERTEX *in = (VERTEX *)(ddverts + (ein << shift)); + VERTEX *out = (VERTEX *)(ddverts + (eout << shift)); + + (void)s; + + if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { + VIEWPORT_X( dst->v.x, dstclip[0] ); + VIEWPORT_Y( dst->v.y, dstclip[1] ); + VIEWPORT_Z( dst->v.z, dstclip[2] ); + w = dstclip[3]; + } + else { + w = 1.0 / dstclip[3]; + VIEWPORT_X( dst->v.x, dstclip[0] * w ); + VIEWPORT_Y( dst->v.y, dstclip[1] * w ); + VIEWPORT_Z( dst->v.z, dstclip[2] * w ); + } + + if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) || + DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 || + DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) { + + dst->v.w = w; + + INTERP_UB( t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0] ); + INTERP_UB( t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1] ); + INTERP_UB( t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2] ); + INTERP_UB( t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3] ); + + if (DO_SPEC) { + INTERP_UB( t, dst->v.specular.red, out->v.specular.red, in->v.specular.red ); + INTERP_UB( t, dst->v.specular.green, out->v.specular.green, in->v.specular.green ); + INTERP_UB( t, dst->v.specular.blue, out->v.specular.blue, in->v.specular.blue ); + } + if (DO_FOG) { + INTERP_UB( t, dst->v.specular.alpha, out->v.specular.alpha, in->v.specular.alpha ); + } + if (DO_TEX0) { + if (DO_PTEX) { + if (HAVE_PTEX_VERTICES) { + INTERP_F( t, dst->pv.u0, out->pv.u0, in->pv.u0 ); + INTERP_F( t, dst->pv.v0, out->pv.v0, in->pv.v0 ); + INTERP_F( t, dst->pv.q0, out->pv.q0, in->pv.q0 ); + } else { + GLfloat wout = VB->NdcPtr->data[eout][3]; + GLfloat win = VB->NdcPtr->data[ein][3]; + GLfloat qout = out->pv.w / wout; + GLfloat qin = in->pv.w / win; + GLfloat qdst, rqdst; + + ASSERT( !HAVE_HW_DIVIDE ); + + INTERP_F( t, dst->v.u0, out->v.u0 * qout, in->v.u0 * qin ); + INTERP_F( t, dst->v.v0, out->v.v0 * qout, in->v.v0 * qin ); + INTERP_F( t, qdst, qout, qin ); + + rqdst = 1.0 / qdst; + dst->v.u0 *= rqdst; + dst->v.v0 *= rqdst; + dst->v.w *= rqdst; + } + } + else { + INTERP_F( t, dst->v.u0, out->v.u0, in->v.u0 ); + INTERP_F( t, dst->v.v0, out->v.v0, in->v.v0 ); + } + } + if (DO_TEX1) { + if (DO_PTEX) { + INTERP_F( t, dst->pv.u1, out->pv.u1, in->pv.u1 ); + INTERP_F( t, dst->pv.v1, out->pv.v1, in->pv.v1 ); + INTERP_F( t, dst->pv.q1, out->pv.q1, in->pv.q1 ); + } else { + INTERP_F( t, dst->v.u1, out->v.u1, in->v.u1 ); + INTERP_F( t, dst->v.v1, out->v.v1, in->v.v1 ); + } + } + else if (DO_PTEX) { + dst->pv.q1 = 0.0; /* must be a valid float on radeon */ + } + if (DO_TEX2) { + if (DO_PTEX) { + INTERP_F( t, dst->pv.u2, out->pv.u2, in->pv.u2 ); + INTERP_F( t, dst->pv.v2, out->pv.v2, in->pv.v2 ); + INTERP_F( t, dst->pv.q2, out->pv.q2, in->pv.q2 ); + } else { + INTERP_F( t, dst->v.u2, out->v.u2, in->v.u2 ); + INTERP_F( t, dst->v.v2, out->v.v2, in->v.v2 ); + } + } + if (DO_TEX3) { + if (DO_PTEX) { + INTERP_F( t, dst->pv.u3, out->pv.u3, in->pv.u3 ); + INTERP_F( t, dst->pv.v3, out->pv.v3, in->pv.v3 ); + INTERP_F( t, dst->pv.q3, out->pv.q3, in->pv.q3 ); + } else { + INTERP_F( t, dst->v.u3, out->v.u3, in->v.u3 ); + INTERP_F( t, dst->v.v3, out->v.v3, in->v.v3 ); + } + } + } else { + /* 4-dword vertex. Color is in v[3] and there is no oow coordinate. + */ + INTERP_UB( t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0] ); + INTERP_UB( t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1] ); + INTERP_UB( t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2] ); + INTERP_UB( t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3] ); + } +} + +#endif /* rgba && xyzw */ + + +static void TAG(init)( void ) +{ + setup_tab[IND].emit = TAG(emit); + +#if (DO_XYZW && DO_RGBA) + setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); + setup_tab[IND].interp = TAG(interp); +#endif + + if (DO_SPEC) + setup_tab[IND].copy_pv = copy_pv_rgba4_spec5; + else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 || + DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) + setup_tab[IND].copy_pv = copy_pv_rgba4; + else + setup_tab[IND].copy_pv = copy_pv_rgba3; + + if (DO_TEX3) { + if (DO_PTEX) { + ASSERT(HAVE_PTEX_VERTICES); + setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 18; + setup_tab[IND].vertex_stride_shift = 7; + } + else { + setup_tab[IND].vertex_format = TEX3_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 14; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (DO_TEX2) { + if (DO_PTEX) { + ASSERT(HAVE_PTEX_VERTICES); + setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 18; + setup_tab[IND].vertex_stride_shift = 7; + } + else { + setup_tab[IND].vertex_format = TEX2_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (DO_TEX1) { + if (DO_PTEX) { + ASSERT(HAVE_PTEX_VERTICES); + setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } + else { + setup_tab[IND].vertex_format = TEX1_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 10; + setup_tab[IND].vertex_stride_shift = 6; + } + } + else if (DO_TEX0) { + if (DO_PTEX && HAVE_PTEX_VERTICES) { + setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 12; + setup_tab[IND].vertex_stride_shift = 6; + } else { + setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 8; + setup_tab[IND].vertex_stride_shift = 5; + } + } + else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) { + setup_tab[IND].vertex_format = TINY_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 4; + setup_tab[IND].vertex_stride_shift = 4; + } else if (HAVE_NOTEX_VERTICES) { + setup_tab[IND].vertex_format = NOTEX_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 6; + setup_tab[IND].vertex_stride_shift = 5; + } else { + setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT; + setup_tab[IND].vertex_size = 8; + setup_tab[IND].vertex_stride_shift = 5; + } + + assert(setup_tab[IND].vertex_size * 4 <= + 1 << setup_tab[IND].vertex_stride_shift); +} + + +#undef IND +#undef TAG diff --git a/src/mesa/drivers/common/t_dd_vertex.h b/src/mesa/drivers/common/t_dd_vertex.h new file mode 100644 index 0000000000..d45dd09fbd --- /dev/null +++ b/src/mesa/drivers/common/t_dd_vertex.h @@ -0,0 +1,78 @@ + +/* + * Mesa 3-D graphics library + * Version: 4.0.3 + * + * Copyright (C) 1999-2002 Brian Paul 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +typedef struct { + GLfloat x, y, z, w; +} TAG(_coord_t); + +#ifdef COLOR_IS_RGBA +typedef struct { +#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN + GLubyte alpha, blue, green, red; +#else + GLubyte red, green, blue, alpha; +#endif +} TAG(_color_t); +#else +typedef struct { +#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN + GLubyte alpha, red, green, blue; +#else + GLubyte blue, green, red, alpha; +#endif +} TAG(_color_t); +#endif + +typedef union { + struct { + GLfloat x, y, z, w; + TAG(_color_t) color; + TAG(_color_t) specular; + GLfloat u0, v0; + GLfloat u1, v1; + GLfloat u2, v2; + GLfloat u3, v3; + } v; + struct { + GLfloat x, y, z, w; + TAG(_color_t) color; + TAG(_color_t) specular; + GLfloat u0, v0, q0; + GLfloat u1, v1, q1; + GLfloat u2, v2, q2; + GLfloat u3, v3, q3; + } pv; + struct { + GLfloat x, y, z; + TAG(_color_t) color; + } tv; + GLfloat f[24]; + GLuint ui[24]; + GLubyte ub4[24][4]; +} TAG(Vertex), *TAG(VertexPtr); + diff --git a/src/mesa/drivers/dri/i830/i830_vb.c b/src/mesa/drivers/dri/i830/i830_vb.c new file mode 100644 index 0000000000..c83cb47835 --- /dev/null +++ b/src/mesa/drivers/dri/i830/i830_vb.c @@ -0,0 +1,574 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. + * + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.c,v 1.5 2002/12/10 01:26:54 dawes Exp $ */ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_vb.h" +#include "i830_ioctl.h" +#include "i830_tris.h" +#include "i830_state.h" + +#define I830_TEX1_BIT 0x1 +#define I830_TEX0_BIT 0x2 +#define I830_RGBA_BIT 0x4 +#define I830_SPEC_BIT 0x8 +#define I830_FOG_BIT 0x10 +#define I830_XYZW_BIT 0x20 +#define I830_PTEX_BIT 0x40 +#define I830_MAX_SETUP 0x80 + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); + interp_func interp; + copy_pv_func copy_pv; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_size; + GLuint vertex_format; +} setup_tab[I830_MAX_SETUP]; + +#define TINY_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_XYZ) + +#define NOTEX_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX0_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(1) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX1_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(2) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + + +/* I'm cheating here hardcore : if bit 31 is set I know to emit + * a vf2 state == TEXCOORDFMT_3D. We never mix 2d/3d texcoords, + * so this solution works for now. + */ + +#define PROJ_TEX1_VERTEX_FORMAT ((1<<31) | \ + STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(2) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +/* Might want to do these later */ +#define TEX2_VERTEX_FORMAT 0 +#define TEX3_VERTEX_FORMAT 0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & I830_XYZW_BIT) +#define DO_RGBA (IND & I830_RGBA_BIT) +#define DO_SPEC (IND & I830_SPEC_BIT) +#define DO_FOG (IND & I830_FOG_BIT) +#define DO_TEX0 (IND & I830_TEX0_BIT) +#define DO_TEX1 (IND & I830_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & I830_PTEX_BIT) + +#define VERTEX i830Vertex +#define VERTEX_COLOR i830_color_t +#define GET_VIEWPORT_MAT() I830_CONTEXT(ctx)->ViewportMatrix.m +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() I830_CONTEXT(ctx)->vertex_format +#define GET_VERTEX_STORE() ((GLubyte *)I830_CONTEXT(ctx)->verts) +#define GET_VERTEX_SIZE() I830_CONTEXT(ctx)->vertex_size * sizeof(int) +#define INVALIDATE_STORED_VERTICES() + +#define HAVE_HW_VIEWPORT 0 +#define HAVE_HW_DIVIDE 0 +#define HAVE_RGBA_COLOR 0 +#define HAVE_TINY_VERTICES 1 +#define HAVE_NOTEX_VERTICES 1 +#define HAVE_TEX0_VERTICES 1 +#define HAVE_TEX1_VERTICES 1 +#define HAVE_TEX2_VERTICES 0 +#define HAVE_TEX3_VERTICES 0 +#define HAVE_PTEX_VERTICES 1 + +#define UNVIEWPORT_VARS GLfloat h = I830_CONTEXT(ctx)->driDrawable->h +#define UNVIEWPORT_X(x) x - SUBPIXEL_X +#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y +#define UNVIEWPORT_Z(z) z * (float)I830_CONTEXT(ctx)->ClearDepth + +#define PTEX_FALLBACK() FALLBACK(I830_CONTEXT(ctx), I830_FALLBACK_TEXTURE, 1) + +#define INTERP_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].copy_pv + + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) i830_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\ + I830_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX0_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_FOG_BIT|I830_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT) +#define TAG(x) x##_gfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +/* Add functions for proj texturing for t0 and t1 */ +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT|\ + I830_PTEX_BIT) +#define TAG(x) x##_wgpt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgspt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\ + I830_TEX1_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgfpt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\ + I830_TEX1_BIT|I830_TEX0_BIT|I830_PTEX_BIT) +#define TAG(x) x##_wgfspt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + + +static void init_setup_tab( void ) +{ + init_wg(); + init_wgs(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgst0(); + init_wgst0t1(); + init_wgspt0(); + init_wgf(); + init_wgfs(); + init_wgft0(); + init_wgft0t1(); + init_wgfpt0(); + init_wgfst0(); + init_wgfst0t1(); + init_wgfspt0(); + init_t0(); + init_t0t1(); + init_f(); + init_ft0(); + init_ft0t1(); + init_g(); + init_gs(); + init_gt0(); + init_gt0t1(); + init_gst0(); + init_gst0t1(); + init_gf(); + init_gfs(); + init_gft0(); + init_gft0t1(); + init_gfst0(); + init_gfst0t1(); + /* Add proj texturing on t1 */ + init_wgpt0t1(); + init_wgspt0t1(); + init_wgfpt0t1(); + init_wgfspt0t1(); +} + + + +void i830PrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & I830_XYZW_BIT) ? " xyzw," : "", + (flags & I830_RGBA_BIT) ? " rgba," : "", + (flags & I830_SPEC_BIT) ? " spec," : "", + (flags & I830_FOG_BIT) ? " fog," : "", + (flags & I830_TEX0_BIT) ? " tex-0," : "", + (flags & I830_TEX1_BIT) ? " tex-1," : "", + (flags & I830_PTEX_BIT) ? " ptex," : ""); +} + +void i830CheckTexSizes( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT( ctx ); + + if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) { + int ind = imesa->SetupIndex |= I830_PTEX_BIT; + + if(setup_tab[ind].vertex_format != imesa->vertex_format) { + int vfmt = setup_tab[ind].vertex_format; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt; + + if (vfmt & (1<<31)) { + /* Proj texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D)); + i830UpdateTexUnitProj( ctx, 0, GL_TRUE ); + i830UpdateTexUnitProj( ctx, 1, GL_TRUE ); + + } else { + /* Normal texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)); + i830UpdateTexUnitProj( ctx, 0, GL_FALSE ); + i830UpdateTexUnitProj( ctx, 1, GL_FALSE ); + } + imesa->vertex_format = vfmt; + imesa->vertex_size = setup_tab[ind].vertex_size; + } + + if (!imesa->Fallback && + !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp; + tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv; + } + } +} + +void i830BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint stride = imesa->vertex_size * sizeof(int); + GLubyte *v = ((GLubyte *) imesa->verts + (start * stride)); + + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + newinputs |= imesa->SetupNewInputs; + imesa->SetupNewInputs = 0; + + if (!newinputs) + return; + + if (newinputs & VERT_BIT_POS) { + setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; + + if (newinputs & VERT_BIT_COLOR0) + ind |= I830_RGBA_BIT; + + if (newinputs & VERT_BIT_COLOR1) + ind |= I830_SPEC_BIT; + + if (newinputs & VERT_BIT_TEX0) + ind |= I830_TEX0_BIT; + + if (newinputs & VERT_BIT_TEX1) + ind |= I830_TEX1_BIT; + + if (newinputs & VERT_BIT_FOG) + ind |= I830_FOG_BIT; + +#if 0 + if (imesa->SetupIndex & I830_PTEX_BIT) + ind = ~0; +#endif + + ind &= imesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } + } +} + +void i830ChooseVertexState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint ind = I830_XYZW_BIT|I830_RGBA_BIT; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= I830_SPEC_BIT; + + if (ctx->Fog.Enabled) + ind |= I830_FOG_BIT; + + if (ctx->Texture._EnabledUnits & 0x2) + /* unit 1 enabled */ + ind |= I830_TEX1_BIT|I830_TEX0_BIT; + else if (ctx->Texture._EnabledUnits & 0x1) + /* unit 0 enabled */ + ind |= I830_TEX0_BIT; + + imesa->SetupIndex = ind; + + if (I830_DEBUG & (DEBUG_VERTS|DEBUG_STATE)) + i830PrintSetupFlags( __FUNCTION__, ind ); + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = i830_interp_extras; + tnl->Driver.Render.CopyPV = i830_copy_pv_extras; + } else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } + + if (setup_tab[ind].vertex_format != imesa->vertex_format) { + int vfmt = setup_tab[ind].vertex_format; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt; + + if (vfmt & (1<<31)) { + /* Proj texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D)); + i830UpdateTexUnitProj( ctx, 0, GL_TRUE ); + i830UpdateTexUnitProj( ctx, 1, GL_TRUE ); + } else { + /* Normal texturing */ + imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD | + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)); + i830UpdateTexUnitProj( ctx, 0, GL_FALSE ); + i830UpdateTexUnitProj( ctx, 1, GL_FALSE ); + } + imesa->vertex_format = vfmt; + imesa->vertex_size = setup_tab[ind].vertex_size; + } +} + + + +void *i830_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count, + void *dest) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint stride = imesa->vertex_size * 4; + setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, stride ); + return (void *)((char *)dest + stride * (count - start)); +} + + + +void i830InitVB( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + + imesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32); + + { + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } + } +} + + +void i830FreeVB( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + if (imesa->verts) { + ALIGN_FREE(imesa->verts); + imesa->verts = 0; + } +} diff --git a/src/mesa/drivers/dri/i830/i830_vb.h b/src/mesa/drivers/dri/i830/i830_vb.h new file mode 100644 index 0000000000..570778ab6b --- /dev/null +++ b/src/mesa/drivers/dri/i830/i830_vb.h @@ -0,0 +1,64 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. + * + * Adapted for use in the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.h,v 1.1 2002/09/09 19:18:49 dawes Exp $ */ + +#ifndef I830VB_INC +#define I830VB_INC + +#include "mtypes.h" +#include "swrast/swrast.h" + +#define _I830_NEW_VERTEX (_NEW_TEXTURE | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _NEW_FOG) + + +extern void i830ChooseVertexState( GLcontext *ctx ); +extern void i830CheckTexSizes( GLcontext *ctx ); +extern void i830BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ); + + +extern void *i830_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count, + void *dest ); + +extern void i830_translate_vertex( GLcontext *ctx, + const i830Vertex *src, + SWvertex *dst ); + +extern void i830InitVB( GLcontext *ctx ); +extern void i830FreeVB( GLcontext *ctx ); + +extern void i830_print_vertex( GLcontext *ctx, const i830Vertex *v ); +extern void i830PrintSetupFlags(char *msg, GLuint flags ); + +#endif diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 519bfb34b9..30fa433280 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.0.1 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2004 Brian Paul 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"), @@ -124,7 +124,7 @@ _mesa_Clear( GLbitfield mask ) GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT)) { /* invalid bit set */ - _mesa_error( ctx, GL_INVALID_VALUE, "glClear(mask)"); + _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); return; } @@ -198,7 +198,7 @@ _mesa_DrawBuffer( GLenum mode ) break; case GL_BACK: if (!ctx->Visual.doubleBufferMode) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_BACK)"); return; } if (ctx->Visual.stereoMode) @@ -213,7 +213,7 @@ _mesa_DrawBuffer( GLenum mode ) #if _HAVE_FULL_GL case GL_RIGHT: if (!ctx->Visual.stereoMode) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_RIGHT)"); return;} if (ctx->Visual.doubleBufferMode) ctx->Color._DrawDestMask = FRONT_RIGHT_BIT | BACK_RIGHT_BIT; @@ -222,28 +222,28 @@ _mesa_DrawBuffer( GLenum mode ) break; case GL_FRONT_RIGHT: if (!ctx->Visual.stereoMode) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_FRONT_RIGHT)"); return; } ctx->Color._DrawDestMask = FRONT_RIGHT_BIT; break; case GL_BACK_RIGHT: if (!ctx->Visual.stereoMode || !ctx->Visual.doubleBufferMode) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_BACK_RIGHT)"); return; } ctx->Color._DrawDestMask = BACK_RIGHT_BIT; break; case GL_BACK_LEFT: if (!ctx->Visual.doubleBufferMode) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_BACK_LEFT)"); return; } ctx->Color._DrawDestMask = BACK_LEFT_BIT; break; case GL_FRONT_AND_BACK: if (!ctx->Visual.doubleBufferMode) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_FRONT_AND_BACK)"); return; } if (ctx->Visual.stereoMode) diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 539e654184..fbce676d63 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -170,7 +170,6 @@ typedef enum { OPCODE_BITMAP, OPCODE_BLEND_COLOR, OPCODE_BLEND_EQUATION, - OPCODE_BLEND_EQUATION_SEPARATE, OPCODE_BLEND_FUNC_SEPARATE, OPCODE_CALL_LIST, OPCODE_CALL_LIST_OFFSET, @@ -629,7 +628,6 @@ void _mesa_init_lists( void ) InstSize[OPCODE_BITMAP] = 8; InstSize[OPCODE_BLEND_COLOR] = 5; InstSize[OPCODE_BLEND_EQUATION] = 2; - InstSize[OPCODE_BLEND_EQUATION_SEPARATE] = 3; InstSize[OPCODE_BLEND_FUNC_SEPARATE] = 5; InstSize[OPCODE_CALL_LIST] = 2; InstSize[OPCODE_CALL_LIST_OFFSET] = 3; @@ -958,23 +956,6 @@ static void GLAPIENTRY save_BlendEquation( GLenum mode ) } -static void GLAPIENTRY save_BlendEquationSeparateEXT( GLenum modeRGB, - GLenum modeA ) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2 ); - if (n) { - n[1].e = modeRGB; - n[2].e = modeA; - } - if (ctx->ExecuteFlag) { - (*ctx->Exec->BlendEquationSeparateEXT)( modeRGB, modeA ); - } -} - - static void GLAPIENTRY save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { @@ -4128,7 +4109,7 @@ save_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value) /* * GL_NV_vertex_program */ -#if FEATURE_NV_vertex_program +#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program static void GLAPIENTRY save_BindProgramNV(GLenum target, GLuint id) { @@ -4144,7 +4125,9 @@ save_BindProgramNV(GLenum target, GLuint id) (*ctx->Exec->BindProgramNV)( target, id ); } } +#endif /* FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program */ +#if FEATURE_NV_vertex_program static void GLAPIENTRY save_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params) { @@ -5285,9 +5268,6 @@ execute_list( GLcontext *ctx, GLuint list ) case OPCODE_BLEND_EQUATION: (*ctx->Exec->BlendEquation)( n[1].e ); break; - case OPCODE_BLEND_EQUATION_SEPARATE: - (*ctx->Exec->BlendEquationSeparateEXT)( n[1].e, n[2].e ); - break; case OPCODE_BLEND_FUNC_SEPARATE: (*ctx->Exec->BlendFuncSeparateEXT)(n[1].e, n[2].e, n[3].e, n[4].e); break; @@ -5874,10 +5854,12 @@ execute_list( GLcontext *ctx, GLuint list ) case OPCODE_WINDOW_POS_ARB: /* GL_ARB_window_pos */ (*ctx->Exec->WindowPos3fMESA)( n[1].f, n[2].f, n[3].f ); break; -#if FEATURE_NV_vertex_program +#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program case OPCODE_BIND_PROGRAM_NV: /* GL_NV_vertex_program */ (*ctx->Exec->BindProgramNV)( n[1].e, n[2].ui ); break; +#endif +#if FEATURE_NV_vertex_program case OPCODE_EXECUTE_PROGRAM_NV: { GLfloat v[4]; @@ -7448,7 +7430,7 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ) table->EnableVertexAttribArrayARB = _mesa_EnableVertexAttribArrayARB; table->DisableVertexAttribArrayARB = _mesa_DisableVertexAttribArrayARB; table->ProgramStringARB = save_ProgramStringARB; - table->BindProgramNV = _mesa_BindProgram; + table->BindProgramNV = save_BindProgramNV; table->DeleteProgramsNV = _mesa_DeletePrograms; table->GenProgramsNV = _mesa_GenPrograms; table->IsProgramNV = _mesa_IsProgram; @@ -7487,9 +7469,6 @@ _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ) table->MapBufferARB = _mesa_MapBufferARB; table->UnmapBufferARB = _mesa_UnmapBufferARB; #endif - - /* 299. GL_EXT_blend_equation_separate */ - table->BlendEquationSeparateEXT = save_BlendEquationSeparateEXT; } diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c index 9bf884e047..b6d083d7a1 100644 --- a/src/mesa/tnl/t_save_api.c +++ b/src/mesa/tnl/t_save_api.c @@ -1280,11 +1280,11 @@ static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfl { GET_CURRENT_CONTEXT(ctx); _save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK ); - glVertex2f( x1, y1 ); - glVertex2f( x2, y1 ); - glVertex2f( x2, y2 ); - glVertex2f( x1, y2 ); - glEnd(); + _glapi_Dispatch->Vertex2f( x1, y1 ); + _glapi_Dispatch->Vertex2f( x2, y1 ); + _glapi_Dispatch->Vertex2f( x2, y2 ); + _glapi_Dispatch->Vertex2f( x1, y2 ); + _glapi_Dispatch->End(); } @@ -1298,8 +1298,8 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co _save_NotifyBegin( ctx, mode | PRIM_WEAK ); for (i = start ; i < count ; i++) - glArrayElement( i ); - glEnd(); + _glapi_Dispatch->ArrayElement( i ); + _glapi_Dispatch->End(); } @@ -1317,22 +1317,22 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum switch (type) { case GL_UNSIGNED_BYTE: for (i = 0 ; i < count ; i++) - glArrayElement( ((GLubyte *)indices)[i] ); + _glapi_Dispatch->ArrayElement( ((GLubyte *)indices)[i] ); break; case GL_UNSIGNED_SHORT: for (i = 0 ; i < count ; i++) - glArrayElement( ((GLushort *)indices)[i] ); + _glapi_Dispatch->ArrayElement( ((GLushort *)indices)[i] ); break; case GL_UNSIGNED_INT: for (i = 0 ; i < count ; i++) - glArrayElement( ((GLuint *)indices)[i] ); + _glapi_Dispatch->ArrayElement( ((GLuint *)indices)[i] ); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); break; } - glEnd(); + _glapi_Dispatch->End(); } static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c index 2ad41f5bbd..bbbf54baac 100644 --- a/src/mesa/tnl/t_vb_fog.c +++ b/src/mesa/tnl/t_vb_fog.c @@ -241,7 +241,7 @@ static void free_fog_data( struct tnl_pipeline_stage *stage ) const struct tnl_pipeline_stage _tnl_fog_coordinate_stage = { "build fog coordinates", /* name */ - _NEW_FOG, /* check_state */ + _NEW_FOG|_NEW_PROGRAM, /* check_state */ _NEW_FOG, /* run_state */ GL_FALSE, /* active? */ 0, /* inputs */ diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c index 3ca25395da..1d260fafb2 100644 --- a/src/mesa/tnl/t_vb_light.c +++ b/src/mesa/tnl/t_vb_light.c @@ -352,7 +352,7 @@ static void dtr( struct tnl_pipeline_stage *stage ) const struct tnl_pipeline_stage _tnl_lighting_stage = { "lighting", /* name */ - _NEW_LIGHT, /* recheck */ + _NEW_LIGHT|_NEW_PROGRAM, /* recheck */ _NEW_LIGHT|_NEW_MODELVIEW, /* recalc -- modelview dependency * otherwise not captured by inputs * (which may be _TNL_BIT_POS) */ diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c index 2908f1aee0..2247313653 100644 --- a/src/mesa/tnl/t_vb_normals.c +++ b/src/mesa/tnl/t_vb_normals.c @@ -179,6 +179,7 @@ static void free_normal_data( struct tnl_pipeline_stage *stage ) #define _TNL_NEW_NORMAL_TRANSFORM (_NEW_MODELVIEW| \ _NEW_TRANSFORM| \ + _NEW_PROGRAM| \ _MESA_NEW_NEED_NORMALS| \ _MESA_NEW_NEED_EYE_COORDS) diff --git a/src/mesa/tnl/t_vb_points.c b/src/mesa/tnl/t_vb_points.c index 9ef98fab22..1990886479 100644 --- a/src/mesa/tnl/t_vb_points.c +++ b/src/mesa/tnl/t_vb_points.c @@ -111,10 +111,10 @@ static void free_point_data( struct tnl_pipeline_stage *stage ) const struct tnl_pipeline_stage _tnl_point_attenuation_stage = { "point size attenuation", /* name */ - _NEW_POINT, /* build_state_change */ - _NEW_POINT, /* run_state_change */ + _NEW_POINT|_NEW_PROGRAM, /* check_state */ + _NEW_POINT, /* run_state */ GL_FALSE, /* active */ - _TNL_BIT_POS, /* inputs */ + _TNL_BIT_POS, /* inputs */ _TNL_BIT_POS, /* outputs */ 0, /* changed_inputs (temporary value) */ NULL, /* stage private data */ diff --git a/src/mesa/tnl/t_vb_texgen.c b/src/mesa/tnl/t_vb_texgen.c index 68ee089c09..64d569a019 100644 --- a/src/mesa/tnl/t_vb_texgen.c +++ b/src/mesa/tnl/t_vb_texgen.c @@ -678,7 +678,7 @@ static void free_texgen_data( struct tnl_pipeline_stage *stage ) const struct tnl_pipeline_stage _tnl_texgen_stage = { "texgen", /* name */ - _NEW_TEXTURE, /* when to call check() */ + _NEW_TEXTURE|_NEW_PROGRAM, /* when to call check() */ _NEW_TEXTURE, /* when to invalidate stored data */ GL_FALSE, /* active? */ 0, /* inputs */ diff --git a/src/mesa/tnl/t_vb_texmat.c b/src/mesa/tnl/t_vb_texmat.c index 363a76a487..221dd58280 100644 --- a/src/mesa/tnl/t_vb_texmat.c +++ b/src/mesa/tnl/t_vb_texmat.c @@ -137,7 +137,7 @@ static void free_texmat_data( struct tnl_pipeline_stage *stage ) const struct tnl_pipeline_stage _tnl_texture_transform_stage = { "texture transform", /* name */ - _NEW_TEXTURE|_NEW_TEXTURE_MATRIX, /* check_state */ + _NEW_TEXTURE|_NEW_TEXTURE_MATRIX|_NEW_PROGRAM, /* check_state */ _NEW_TEXTURE|_NEW_TEXTURE_MATRIX, /* run_state */ GL_FALSE, /* active? */ 0, /* inputs */ |