--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "imports.h"
+#include "macros.h"
+
+#include "sp_context.h"
+#include "sp_prim.h"
+
+struct clipper {
+ struct prim_stage stage;
+
+ GLuint active_user_planes;
+};
+
+/* This is a bit confusing:
+ */
+static INLINE struct clipper *clipper_stage( struct prim_stage *stage )
+{
+ return (struct clipper *)stage;
+}
+
+
+#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
+
+
+/* All attributes are float[4], so this is easy:
+ */
+static void interp_attr( GLfloat *fdst,
+ GLfloat t,
+ const GLfloat *fin,
+ const GLfloat *fout )
+{
+ fdst[0] = LINTERP( t, fout[0], fin[0] );
+ fdst[1] = LINTERP( t, fout[1], fin[1] );
+ fdst[2] = LINTERP( t, fout[2], fin[2] );
+ fdst[3] = LINTERP( t, fout[3], fin[3] );
+}
+
+
+
+
+/* Interpolate between two vertices to produce a third.
+ */
+static void interp( struct clipper *clip,
+ struct vertex_header *dst,
+ GLfloat t,
+ const struct vertex_header *out,
+ const struct vertex_header *in )
+{
+ const GLuint nr_attrs = clip->stage.softpipe->nr_attrs;
+ GLuint j;
+
+ /* Vertex header.
+ */
+ {
+ dst->clipmask = 0;
+ dst->edgeflag = 0;
+ dst->pad = 0;
+ }
+
+ /* Clip coordinates: interpolate normally
+ */
+ {
+ interp_attr(dst->clip, t, in->clip, out->clip);
+ }
+
+ /* Do the projective divide and insert window coordinates:
+ */
+ {
+ const GLfloat *pos = dst->clip;
+ const GLfloat *scale = clip->stage.softpipe->viewport.scale;
+ const GLfloat *trans = clip->stage.softpipe->viewport.translate;
+ GLfloat oow;
+
+ oow = 1.0 / pos[3];
+
+ dst->data[0][0] = pos[0] * oow * scale[0] + trans[0];
+ dst->data[0][1] = pos[1] * oow * scale[1] + trans[1];
+ dst->data[0][2] = pos[2] * oow * scale[2] + trans[2];
+ dst->data[0][3] = oow;
+ }
+
+
+ /* Other attributes
+ */
+ for (j = 1; j < nr_attrs-1; j++) {
+ interp_attr(dst->data[j], t, in->data[j], out->data[j]);
+ }
+}
+
+
+#define CLIP_USER_BIT 0x40
+#define CLIP_CULL_BIT 0x80
+
+
+static INLINE GLfloat dot4( const GLfloat *a,
+ const GLfloat *b )
+{
+ GLfloat result = (a[0]*b[0] +
+ a[1]*b[1] +
+ a[2]*b[2] +
+ a[3]*b[3]);
+
+ return result;
+}
+
+
+#if 0
+static INLINE void do_tri( struct prim_stage *next,
+ struct prim_header *header )
+{
+ GLuint i;
+ for (i = 0; i < 3; i++) {
+ GLfloat *ndc = header->v[i]->data[0];
+ _mesa_printf("ndc %f %f %f\n", ndc[0], ndc[1], ndc[2]);
+ assert(ndc[0] >= -1 && ndc[0] <= 641);
+ assert(ndc[1] >= 30 && ndc[1] <= 481);
+ }
+ _mesa_printf("\n");
+ next->tri(next, header);
+}
+#endif
+
+
+static void emit_poly( struct prim_stage *stage,
+ struct vertex_header **inlist,
+ GLuint n )
+{
+ struct prim_header header;
+ GLuint i;
+
+ for (i = 2; i < n; i++) {
+ header.v[0] = inlist[0];
+ header.v[1] = inlist[i-1];
+ header.v[2] = inlist[i];
+
+ {
+ GLuint tmp0 = header.v[0]->edgeflag;
+ GLuint tmp2 = header.v[2]->edgeflag;
+
+ if (i != 2) header.v[0]->edgeflag = 0;
+ if (i != n-1) header.v[2]->edgeflag = 0;
+
+ stage->next->tri( stage->next, &header );
+
+ header.v[0]->edgeflag = tmp0;
+ header.v[2]->edgeflag = tmp2;
+ }
+ }
+}
+
+
+#if 0
+static void emit_poly( struct prim_stage *stage )
+{
+ GLuint i;
+
+ for (i = 2; i < n; i++) {
+ header->v[0] = inlist[0];
+ header->v[1] = inlist[i-1];
+ header->v[2] = inlist[i];
+
+ stage->next->tri( stage->next, header );
+ }
+}
+#endif
+
+
+/* Clip a triangle against the viewport and user clip planes.
+ */
+static void
+do_clip_tri( struct prim_stage *stage,
+ struct prim_header *header,
+ GLuint clipmask )
+{
+ struct clipper *clipper = clipper_stage( stage );
+ struct vertex_header *a[MAX_CLIPPED_VERTICES];
+ struct vertex_header *b[MAX_CLIPPED_VERTICES];
+ struct vertex_header **inlist = a;
+ struct vertex_header **outlist = b;
+ GLuint tmpnr = 0;
+ GLuint n = 3;
+ GLuint i;
+
+ inlist[0] = header->v[0];
+ inlist[1] = header->v[1];
+ inlist[2] = header->v[2];
+
+ /* XXX: Note stupid hack to deal with tnl's 8-bit clipmask. Remove
+ * this once we correctly use 16bit masks for userclip planes.
+ */
+ clipmask &= ~CLIP_CULL_BIT;
+ if (clipmask & CLIP_USER_BIT) {
+ clipmask &= ~CLIP_USER_BIT;
+ clipmask |= clipper->active_user_planes;
+ }
+
+ while (clipmask && n >= 3) {
+ GLuint plane_idx = ffs(clipmask)-1;
+ const GLfloat *plane = clipper->stage.softpipe->plane[plane_idx];
+ struct vertex_header *vert_prev = inlist[0];
+ GLfloat dp_prev = dot4( vert_prev->clip, plane );
+ GLuint outcount = 0;
+
+ clipmask &= ~(1<<plane_idx);
+
+ inlist[n] = inlist[0]; /* prevent rotation of vertices */
+
+ for (i = 1; i <= n; i++) {
+ struct vertex_header *vert = inlist[i];
+
+ GLfloat dp = dot4( vert->clip, plane );
+
+ if (!IS_NEGATIVE(dp_prev)) {
+ outlist[outcount++] = vert_prev;
+ }
+
+ if (DIFFERENT_SIGNS(dp, dp_prev)) {
+ struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++];
+ outlist[outcount++] = new_vert;
+
+ if (IS_NEGATIVE(dp)) {
+ /* Going out of bounds. Avoid division by zero as we
+ * know dp != dp_prev from DIFFERENT_SIGNS, above.
+ */
+ GLfloat t = dp / (dp - dp_prev);
+ interp( clipper, new_vert, t, vert, vert_prev );
+
+ /* Force edgeflag true in this case:
+ */
+ new_vert->edgeflag = 1;
+ } else {
+ /* Coming back in.
+ */
+ GLfloat t = dp_prev / (dp_prev - dp);
+ interp( clipper, new_vert, t, vert_prev, vert );
+
+ /* Copy starting vert's edgeflag:
+ */
+ new_vert->edgeflag = vert_prev->edgeflag;
+ }
+ }
+
+ vert_prev = vert;
+ dp_prev = dp;
+ }
+
+ {
+ struct vertex_header **tmp = inlist;
+ inlist = outlist;
+ outlist = tmp;
+ n = outcount;
+ }
+ }
+
+ /* Emit the polygon as triangles to the setup stage:
+ */
+ if (n >= 3)
+ emit_poly( stage, inlist, n );
+}
+
+
+/* Clip a line against the viewport and user clip planes.
+ */
+static void
+do_clip_line( struct prim_stage *stage,
+ struct prim_header *header,
+ GLuint clipmask )
+{
+ struct clipper *clipper = clipper_stage( stage );
+ struct vertex_header *v0 = header->v[0];
+ struct vertex_header *v1 = header->v[1];
+ const GLfloat *pos0 = v0->clip;
+ const GLfloat *pos1 = v1->clip;
+ GLfloat t0 = 0;
+ GLfloat t1 = 0;
+
+ /* XXX: Note stupid hack to deal with tnl's 8-bit clipmask. Remove
+ * this once we correctly use 16bit masks for userclip planes.
+ */
+ clipmask &= ~CLIP_CULL_BIT;
+ if (clipmask & CLIP_USER_BIT) {
+ clipmask &= ~CLIP_USER_BIT;
+ clipmask |= clipper->active_user_planes;
+ }
+
+ while (clipmask) {
+ GLuint plane_idx = ffs(clipmask)-1;
+ const GLfloat *plane = clipper->stage.softpipe->plane[plane_idx];
+
+ clipmask &= ~(1<<plane_idx);
+
+ const GLfloat dp0 = dot4( pos0, plane );
+ const GLfloat dp1 = dot4( pos1, plane );
+
+ if (dp1 < 0) {
+ GLfloat t = dp1 / (dp1 - dp0);
+ if (t > t1) t1 = t;
+ }
+
+ if (dp0 < 0) {
+ GLfloat t = dp0 / (dp0 - dp1);
+ if (t > t0) t0 = t;
+ }
+
+ if (t0 + t1 >= 1.0)
+ return; /* discard */
+ }
+
+ if (v0->clipmask) {
+ interp( clipper, stage->tmp[0], t0, v0, v1 );
+ header->v[0] = stage->tmp[0];
+ }
+
+ if (v1->clipmask) {
+ interp( clipper, stage->tmp[1], t1, v1, v0 );
+ header->v[1] = stage->tmp[1];
+ }
+
+ stage->next->line( stage->next, header );
+}
+
+
+
+static void clip_begin( struct prim_stage *stage )
+{
+ struct clipper *clipper = clipper_stage(stage);
+ GLuint nr = stage->softpipe->nr_planes;
+
+ /* Hacky bitmask to use when we hit CLIP_USER_BIT:
+ */
+ clipper->active_user_planes = ((1<<nr)-1) & ~((1<<6)-1);
+
+ stage->next->begin( stage->next );
+}
+
+static void
+clip_point( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ if (header->v[0]->clipmask == 0)
+ stage->next->point( stage->next, header );
+}
+
+
+static void
+clip_line( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ GLuint clipmask = (header->v[0]->clipmask |
+ header->v[1]->clipmask);
+
+ if (clipmask == 0) {
+ stage->next->line( stage->next, header );
+ }
+ else if ((header->v[0]->clipmask &
+ header->v[1]->clipmask) == 0) {
+ do_clip_line(stage, header, clipmask);
+ }
+}
+
+
+static void
+clip_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ GLuint clipmask = (header->v[0]->clipmask |
+ header->v[1]->clipmask |
+ header->v[2]->clipmask);
+
+ if (clipmask == 0) {
+ stage->next->tri( stage->next, header );
+ }
+ else if ((header->v[0]->clipmask &
+ header->v[1]->clipmask &
+ header->v[2]->clipmask) == 0) {
+ do_clip_tri(stage, header, clipmask);
+ }
+}
+
+static void clip_end( struct prim_stage *stage )
+{
+ stage->next->end( stage->next );
+}
+
+
+struct prim_stage *prim_clip( struct softpipe_context *softpipe )
+{
+ struct clipper *clipper = CALLOC_STRUCT(clipper);
+
+ prim_alloc_tmps( &clipper->stage, MAX_CLIPPED_VERTICES );
+
+ clipper->stage.softpipe = softpipe;
+ clipper->stage.begin = clip_begin;
+ clipper->stage.point = clip_point;
+ clipper->stage.line = clip_line;
+ clipper->stage.tri = clip_tri;
+ clipper->stage.end = clip_end;
+
+ return &clipper->stage;
+}
--- /dev/null
+
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef G_DRAW_H
+#define G_DRAW_H
+
+#include "glheader.h"
+#include "pipe/p_state.h"
+
+
+struct draw_context;
+
+struct draw_context *draw_create( struct softpipe_context *softpipe );
+
+void draw_destroy( struct draw_context *draw );
+
+void draw_set_viewport( struct draw_context *draw,
+ const GLfloat *scale,
+ const GLfloat *translate );
+
+void draw_set_vertex_attributes( struct draw_context *draw,
+ const GLuint *attrs,
+ GLuint nr_attrs );
+
+void draw_vb(struct draw_context *draw,
+ struct vertex_buffer *VB );
+
+#endif
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_prim.h"
+
+
+
+struct cull_stage {
+ struct prim_stage stage;
+ GLuint mode;
+};
+
+
+
+static INLINE struct cull_stage *cull_stage( struct prim_stage *stage )
+{
+ return (struct cull_stage *)stage;
+}
+
+
+static void cull_begin( struct prim_stage *stage )
+{
+ struct cull_stage *cull = cull_stage(stage);
+
+ cull->mode = stage->softpipe->setup.cull_mode;
+
+ stage->next->begin( stage->next );
+}
+
+
+static void cull_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ /* Window coords: */
+ GLfloat *v0 = (GLfloat *)&(header->v[0]->data[0]);
+ GLfloat *v1 = (GLfloat *)&(header->v[1]->data[0]);
+ GLfloat *v2 = (GLfloat *)&(header->v[2]->data[0]);
+
+ GLfloat ex = v0[0] - v2[0];
+ GLfloat ey = v0[1] - v2[1];
+ GLfloat fx = v1[0] - v2[0];
+ GLfloat fy = v1[1] - v2[1];
+
+ header->det = ex * fy - ey * fx;
+
+ _mesa_printf("%s %f\n", __FUNCTION__, header->det );
+
+ if (header->det != 0) {
+ GLuint mode = (header->det < 0) ? PIPE_WINDING_CW : PIPE_WINDING_CCW;
+
+ if ((mode & cull_stage(stage)->mode) == 0)
+ stage->next->tri( stage->next, header );
+ }
+}
+
+
+static void cull_line( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->line( stage->next, header );
+}
+
+
+static void cull_point( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->point( stage->next, header );
+}
+
+static void cull_end( struct prim_stage *stage )
+{
+ stage->next->end( stage->next );
+}
+
+struct prim_stage *prim_cull( struct softpipe_context *softpipe )
+{
+ struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
+
+ prim_alloc_tmps( &cull->stage, 0 );
+
+ cull->stage.softpipe = softpipe;
+ cull->stage.next = NULL;
+ cull->stage.begin = cull_begin;
+ cull->stage.point = cull_point;
+ cull->stage.line = cull_line;
+ cull->stage.tri = cull_tri;
+ cull->stage.end = cull_end;
+
+ return &cull->stage;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+
+#include "vf/vf.h"
+
+#include "sp_context.h"
+#include "sp_prim.h"
+
+
+struct flatshade_stage {
+ struct prim_stage stage;
+
+ const GLuint *lookup;
+};
+
+
+
+static INLINE struct flatshade_stage *flatshade_stage( struct prim_stage *stage )
+{
+ return (struct flatshade_stage *)stage;
+}
+
+
+static void flatshade_begin( struct prim_stage *stage )
+{
+ stage->next->begin( stage->next );
+}
+
+
+
+static INLINE void copy_attr( GLuint attr,
+ struct vertex_header *dst,
+ const struct vertex_header *src )
+{
+ if (attr) {
+ memcpy( dst->data[attr],
+ src->data[attr],
+ sizeof(src->data[0]) );
+ }
+}
+
+static void copy_colors( struct prim_stage *stage,
+ struct vertex_header *dst,
+ const struct vertex_header *src )
+{
+ struct flatshade_stage *flatshade = flatshade_stage(stage);
+ const GLuint *lookup = flatshade->lookup;
+
+ copy_attr( lookup[VF_ATTRIB_COLOR0], dst, src );
+ copy_attr( lookup[VF_ATTRIB_COLOR1], dst, src );
+ copy_attr( lookup[VF_ATTRIB_BFC0], dst, src );
+ copy_attr( lookup[VF_ATTRIB_BFC1], dst, src );
+}
+
+
+
+/* Flatshade tri. Required for clipping and when unfilled tris are
+ * active, otherwise handled by hardware.
+ */
+static void flatshade_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct prim_header tmp;
+
+ tmp.det = header->det;
+ tmp.v[0] = dup_vert(stage, header->v[0], 0);
+ tmp.v[1] = dup_vert(stage, header->v[1], 1);
+ tmp.v[2] = header->v[2];
+
+ copy_colors(stage, tmp.v[0], tmp.v[2]);
+ copy_colors(stage, tmp.v[1], tmp.v[2]);
+
+ stage->next->tri( stage->next, &tmp );
+}
+
+
+/* Flatshade line. Required for clipping.
+ */
+static void flatshade_line( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct prim_header tmp;
+
+ tmp.v[0] = dup_vert(stage, header->v[0], 0);
+ tmp.v[1] = header->v[1];
+
+ copy_colors(stage, tmp.v[0], tmp.v[1]);
+
+ stage->next->line( stage->next, &tmp );
+}
+
+
+static void flatshade_point( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->point( stage->next, header );
+}
+
+static void flatshade_end( struct prim_stage *stage )
+{
+ stage->next->end( stage->next );
+}
+
+struct prim_stage *prim_flatshade( struct softpipe_context *softpipe )
+{
+ struct flatshade_stage *flatshade = CALLOC_STRUCT(flatshade_stage);
+
+ prim_alloc_tmps( &flatshade->stage, 2 );
+
+ flatshade->stage.softpipe = softpipe;
+ flatshade->stage.next = NULL;
+ flatshade->stage.begin = flatshade_begin;
+ flatshade->stage.point = flatshade_point;
+ flatshade->stage.line = flatshade_line;
+ flatshade->stage.tri = flatshade_tri;
+ flatshade->stage.end = flatshade_end;
+
+ flatshade->lookup = softpipe->vf_attr_to_slot;
+
+ return &flatshade->stage;
+}
+
+
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+#include "macros.h"
+
+#include "sp_context.h"
+#include "sp_prim.h"
+
+
+
+struct offset_stage {
+ struct prim_stage stage;
+
+ GLuint hw_data_offset;
+
+ GLfloat scale;
+ GLfloat units;
+};
+
+
+
+static INLINE struct offset_stage *offset_stage( struct prim_stage *stage )
+{
+ return (struct offset_stage *)stage;
+}
+
+
+static void offset_begin( struct prim_stage *stage )
+{
+ struct offset_stage *offset = offset_stage(stage);
+
+ offset->units = stage->softpipe->setup.offset_units;
+ offset->scale = stage->softpipe->setup.offset_scale;
+
+ stage->next->begin( stage->next );
+}
+
+
+/* Offset tri. Some hardware can handle this, but not usually when
+ * doing unfilled rendering.
+ */
+static void do_offset_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct offset_stage *offset = offset_stage(stage);
+ GLfloat inv_det = 1.0 / header->det;
+
+ /* Window coords:
+ */
+ GLfloat *v0 = (GLfloat *)&(header->v[0]->data[0]);
+ GLfloat *v1 = (GLfloat *)&(header->v[1]->data[0]);
+ GLfloat *v2 = (GLfloat *)&(header->v[2]->data[0]);
+
+ GLfloat ex = v0[0] - v2[2];
+ GLfloat fx = v1[0] - v2[2];
+ GLfloat ey = v0[1] - v2[2];
+ GLfloat fy = v1[1] - v2[2];
+ GLfloat ez = v0[2] - v2[2];
+ GLfloat fz = v1[2] - v2[2];
+
+ GLfloat a = ey*fz - ez*fy;
+ GLfloat b = ez*fx - ex*fz;
+
+ GLfloat ac = a * inv_det;
+ GLfloat bc = b * inv_det;
+ GLfloat zoffset;
+
+ if ( ac < 0.0f ) ac = -ac;
+ if ( bc < 0.0f ) bc = -bc;
+
+ zoffset = offset->units + MAX2( ac, bc ) * offset->scale;
+
+ v0[2] += zoffset;
+ v1[2] += zoffset;
+ v2[2] += zoffset;
+
+ stage->next->tri( stage->next, header );
+}
+
+
+static void offset_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct prim_header tmp;
+
+ tmp.det = header->det;
+ tmp.v[0] = dup_vert(stage, header->v[0], 0);
+ tmp.v[1] = dup_vert(stage, header->v[1], 1);
+ tmp.v[2] = dup_vert(stage, header->v[2], 2);
+
+ do_offset_tri( stage->next, &tmp );
+}
+
+
+
+static void offset_line( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->line( stage->next, header );
+}
+
+
+static void offset_point( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->point( stage->next, header );
+}
+
+
+static void offset_end( struct prim_stage *stage )
+{
+ stage->next->end( stage->next );
+}
+
+struct prim_stage *prim_offset( struct softpipe_context *softpipe )
+{
+ struct offset_stage *offset = CALLOC_STRUCT(offset_stage);
+
+ prim_alloc_tmps( &offset->stage, 3 );
+
+ offset->stage.softpipe = softpipe;
+ offset->stage.next = NULL;
+ offset->stage.begin = offset_begin;
+ offset->stage.point = offset_point;
+ offset->stage.line = offset_line;
+ offset->stage.tri = offset_tri;
+ offset->stage.end = offset_end;
+
+ return &offset->stage;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef G_PRIM_H
+#define G_PRIM_H
+
+#include "glheader.h"
+#include "sp_headers.h"
+
+struct softpipe_context;
+
+struct prim_stage *prim_setup( struct softpipe_context *context );
+struct prim_stage *prim_unfilled( struct softpipe_context *context );
+struct prim_stage *prim_twoside( struct softpipe_context *context );
+struct prim_stage *prim_offset( struct softpipe_context *context );
+struct prim_stage *prim_clip( struct softpipe_context *context );
+struct prim_stage *prim_flatshade( struct softpipe_context *context );
+struct prim_stage *prim_cull( struct softpipe_context *context );
+
+
+/* Internal structs and helpers for the primitive clip/setup pipeline:
+ */
+struct prim_stage {
+ struct softpipe_context *softpipe;
+
+ struct prim_stage *next;
+
+ struct vertex_header **tmp;
+ GLuint nr_tmps;
+
+ void (*begin)( struct prim_stage * );
+
+ void (*point)( struct prim_stage *,
+ struct prim_header * );
+
+ void (*line)( struct prim_stage *,
+ struct prim_header * );
+
+ void (*tri)( struct prim_stage *,
+ struct prim_header * );
+
+ void (*end)( struct prim_stage * );
+};
+
+
+
+/* Get a writeable copy of a vertex:
+ */
+static INLINE struct vertex_header *
+dup_vert( struct prim_stage *stage,
+ const struct vertex_header *vert,
+ GLuint idx )
+{
+ struct vertex_header *tmp = stage->tmp[idx];
+ memcpy(tmp, vert, stage->softpipe->prim.vertex_size );
+ return tmp;
+}
+
+void prim_free_tmps( struct prim_stage *stage );
+void prim_alloc_tmps( struct prim_stage *stage, GLuint nr );
+
+
+#endif
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+#include "vf/vf.h"
+
+#include "pipe/p_defines.h"
+#include "sp_context.h"
+#include "sp_prim.h"
+
+
+struct twoside_stage {
+ struct prim_stage stage;
+
+ GLfloat facing;
+ const GLuint *lookup;
+};
+
+
+static INLINE struct twoside_stage *twoside_stage( struct prim_stage *stage )
+{
+ return (struct twoside_stage *)stage;
+}
+
+
+static void twoside_begin( struct prim_stage *stage )
+{
+ struct twoside_stage *twoside = twoside_stage(stage);
+
+ twoside->facing = (stage->softpipe->setup.front_winding == PIPE_WINDING_CW) ? -1 : 1;
+
+ stage->next->begin( stage->next );
+}
+
+
+static INLINE void copy_color( GLuint attr_dst,
+ GLuint attr_src,
+ struct vertex_header *v )
+{
+ if (attr_dst && attr_src) {
+ memcpy( v->data[attr_dst],
+ v->data[attr_src],
+ sizeof(v->data[0]) );
+ }
+}
+
+
+static struct vertex_header *copy_bfc( struct twoside_stage *twoside,
+ const struct vertex_header *v,
+ GLuint idx )
+{
+ struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
+
+ copy_color( twoside->lookup[VF_ATTRIB_COLOR0],
+ twoside->lookup[VF_ATTRIB_BFC0],
+ tmp );
+
+ copy_color( twoside->lookup[VF_ATTRIB_COLOR1],
+ twoside->lookup[VF_ATTRIB_BFC1],
+ tmp );
+
+ return tmp;
+}
+
+
+/* Twoside tri:
+ */
+static void twoside_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct twoside_stage *twoside = twoside_stage(stage);
+
+ if (header->det * twoside->facing < 0) {
+ struct prim_header tmp;
+
+ tmp.det = header->det;
+ tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
+ tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
+ tmp.v[2] = copy_bfc(twoside, header->v[2], 2);
+
+ stage->next->tri( stage->next, &tmp );
+ }
+ else {
+ stage->next->tri( stage->next, header );
+ }
+}
+
+
+static void twoside_line( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->line( stage->next, header );
+}
+
+
+static void twoside_point( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->point( stage->next, header );
+}
+
+static void twoside_end( struct prim_stage *stage )
+{
+ stage->next->end( stage->next );
+}
+
+
+
+struct prim_stage *prim_twoside( struct softpipe_context *softpipe )
+{
+ struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage);
+
+ prim_alloc_tmps( &twoside->stage, 3 );
+
+ twoside->stage.softpipe = softpipe;
+ twoside->stage.next = NULL;
+ twoside->stage.begin = twoside_begin;
+ twoside->stage.point = twoside_point;
+ twoside->stage.line = twoside_line;
+ twoside->stage.tri = twoside_tri;
+ twoside->stage.end = twoside_end;
+
+ twoside->lookup = softpipe->vf_attr_to_slot;
+
+ return &twoside->stage;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "imports.h"
+
+#include "sp_context.h"
+#include "sp_prim.h"
+#include "pipe/p_defines.h"
+
+
+struct unfilled_stage {
+ struct prim_stage stage;
+
+ GLuint mode[2];
+};
+
+
+static INLINE struct unfilled_stage *unfilled_stage( struct prim_stage *stage )
+{
+ return (struct unfilled_stage *)stage;
+}
+
+
+static void unfilled_begin( struct prim_stage *stage )
+{
+ struct unfilled_stage *unfilled = unfilled_stage(stage);
+
+ unfilled->mode[0] = stage->softpipe->setup.fill_ccw;
+ unfilled->mode[1] = stage->softpipe->setup.fill_cw;
+
+ stage->next->begin( stage->next );
+}
+
+static void point( struct prim_stage *stage,
+ struct vertex_header *v0 )
+{
+ struct prim_header tmp;
+ tmp.v[0] = v0;
+ stage->next->point( stage->next, &tmp );
+}
+
+static void line( struct prim_stage *stage,
+ struct vertex_header *v0,
+ struct vertex_header *v1 )
+{
+ struct prim_header tmp;
+ tmp.v[0] = v0;
+ tmp.v[1] = v1;
+ stage->next->line( stage->next, &tmp );
+}
+
+
+static void points( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct vertex_header *v0 = header->v[0];
+ struct vertex_header *v1 = header->v[1];
+ struct vertex_header *v2 = header->v[2];
+
+ if (v0->edgeflag) point( stage, v0 );
+ if (v1->edgeflag) point( stage, v1 );
+ if (v2->edgeflag) point( stage, v2 );
+}
+
+static void lines( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct vertex_header *v0 = header->v[0];
+ struct vertex_header *v1 = header->v[1];
+ struct vertex_header *v2 = header->v[2];
+
+ if (v0->edgeflag) line( stage, v0, v1 );
+ if (v1->edgeflag) line( stage, v1, v2 );
+ if (v2->edgeflag) line( stage, v2, v0 );
+}
+
+
+/* Unfilled tri:
+ *
+ * Note edgeflags in the vertex struct is not sufficient as we will
+ * need to manipulate them when decomposing primitives???
+ */
+static void unfilled_tri( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ struct unfilled_stage *unfilled = unfilled_stage(stage);
+ GLuint mode = unfilled->mode[header->det < 0];
+
+ switch (mode) {
+ case PIPE_POLYGON_MODE_FILL:
+ stage->next->tri( stage->next, header );
+ break;
+ case PIPE_POLYGON_MODE_LINE:
+ lines( stage, header );
+ break;
+ case PIPE_POLYGON_MODE_POINT:
+ points( stage, header );
+ break;
+ default:
+ abort();
+ }
+}
+
+static void unfilled_line( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->line( stage->next, header );
+}
+
+
+static void unfilled_point( struct prim_stage *stage,
+ struct prim_header *header )
+{
+ stage->next->point( stage->next, header );
+}
+
+
+static void unfilled_end( struct prim_stage *stage )
+{
+ stage->next->end( stage->next );
+}
+
+struct prim_stage *prim_unfilled( struct softpipe_context *softpipe )
+{
+ struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage);
+
+ prim_alloc_tmps( &unfilled->stage, 0 );
+
+ unfilled->stage.softpipe = softpipe;
+ unfilled->stage.next = NULL;
+ unfilled->stage.tmp = NULL;
+ unfilled->stage.begin = unfilled_begin;
+ unfilled->stage.point = unfilled_point;
+ unfilled->stage.line = unfilled_line;
+ unfilled->stage.tri = unfilled_tri;
+ unfilled->stage.end = unfilled_end;
+
+ return &unfilled->stage;
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "imports.h"
+
+#include "tnl/t_context.h"
+#include "vf/vf.h"
+
+#include "sp_context.h"
+#include "sp_prim.h"
+#include "sp_headers.h"
+#include "sp_draw.h"
+
+/* This file is a temporary set of hooks to allow us to use the tnl/
+ * and vf/ modules until we have replacements in pipe.
+ */
+
+
+struct draw_context
+{
+ struct softpipe_context *softpipe;
+
+ struct vf_attr_map attrs[VF_ATTRIB_MAX];
+ GLuint nr_attrs;
+ GLuint vertex_size;
+ struct vertex_fetch *vf;
+
+ GLubyte *verts;
+ GLuint nr_vertices;
+ GLboolean in_vb;
+
+ GLenum prim;
+
+ /* Helper for tnl:
+ */
+ GLvector4f header;
+};
+
+
+static struct vertex_header *get_vertex( struct draw_context *pipe,
+ GLuint i )
+{
+ return (struct vertex_header *)(pipe->verts + i * pipe->vertex_size);
+}
+
+
+
+static void draw_allocate_vertices( struct draw_context *draw,
+ GLuint nr_vertices )
+{
+ draw->nr_vertices = nr_vertices;
+ draw->verts = MALLOC( nr_vertices * draw->vertex_size );
+
+ draw->softpipe->prim.first->begin( draw->softpipe->prim.first );
+}
+
+static void draw_set_prim( struct draw_context *draw,
+ GLenum prim )
+{
+ draw->prim = prim;
+
+ /* Not done yet - need to force edgeflags to 1 in strip/fan
+ * primitives.
+ */
+#if 0
+ switch (prim) {
+ case GL_TRIANGLES:
+ case GL_POLYGON:
+ case GL_QUADS:
+ case GL_QUAD_STRIP: /* yes, we need this */
+ respect_edgeflags( pipe, GL_TRUE );
+ break;
+
+ default:
+ respect_edgeflags( pipe, GL_FALSE );
+ break;
+ }
+#endif
+}
+
+
+
+static void do_quad( struct prim_stage *first,
+ struct vertex_header *v0,
+ struct vertex_header *v1,
+ struct vertex_header *v2,
+ struct vertex_header *v3 )
+{
+ struct prim_header prim;
+
+ {
+ GLuint tmp = v1->edgeflag;
+ v1->edgeflag = 0;
+
+ prim.v[0] = v0;
+ prim.v[1] = v1;
+ prim.v[2] = v3;
+ first->tri( first, &prim );
+
+ v1->edgeflag = tmp;
+ }
+
+ {
+ GLuint tmp = v3->edgeflag;
+ v3->edgeflag = 0;
+
+ prim.v[0] = v1;
+ prim.v[1] = v2;
+ prim.v[2] = v3;
+ first->tri( first, &prim );
+
+ v3->edgeflag = tmp;
+ }
+}
+
+
+
+
+static void draw_indexed_prim( struct draw_context *draw,
+ const GLuint *elts,
+ GLuint count )
+{
+ struct prim_stage * const first = draw->softpipe->prim.first;
+ struct prim_header prim;
+ GLuint i;
+
+ prim.det = 0; /* valid from cull stage onwards */
+ prim.v[0] = 0;
+ prim.v[1] = 0;
+ prim.v[2] = 0;
+
+ switch (draw->prim) {
+ case GL_POINTS:
+ for (i = 0; i < count; i ++) {
+ prim.v[0] = get_vertex( draw, elts[i] );
+
+ first->point( first, &prim );
+ }
+ break;
+
+ case GL_LINES:
+ for (i = 0; i+1 < count; i += 2) {
+ prim.v[0] = get_vertex( draw, elts[i + 0] );
+ prim.v[1] = get_vertex( draw, elts[i + 1] );
+
+ first->line( first, &prim );
+ }
+ break;
+
+ case GL_LINE_LOOP:
+ if (count >= 2) {
+ for (i = 1; i < count; i++) {
+ prim.v[0] = get_vertex( draw, elts[i-1] );
+ prim.v[1] = get_vertex( draw, elts[i] );
+ first->line( first, &prim );
+ }
+
+ prim.v[0] = get_vertex( draw, elts[count-1] );
+ prim.v[1] = get_vertex( draw, elts[0] );
+ first->line( first, &prim );
+ }
+ break;
+
+ case GL_LINE_STRIP:
+ /* I'm guessing it will be necessary to have something like a
+ * render->reset_line_stipple() method to properly support
+ * splitting strips into primitives like this. Alternately we
+ * could just scan ahead to find individual clipped lines and
+ * otherwise leave the strip intact - that might be better, but
+ * require more complex code here.
+ */
+ if (count >= 2) {
+ prim.v[0] = 0;
+ prim.v[1] = get_vertex( draw, elts[0] );
+
+ for (i = 1; i < count; i++) {
+ prim.v[0] = prim.v[1];
+ prim.v[1] = get_vertex( draw, elts[i] );
+
+ first->line( first, &prim );
+ }
+ }
+ break;
+
+ case GL_TRIANGLES:
+ for (i = 0; i+2 < count; i += 3) {
+ prim.v[0] = get_vertex( draw, elts[i + 0] );
+ prim.v[1] = get_vertex( draw, elts[i + 1] );
+ prim.v[2] = get_vertex( draw, elts[i + 2] );
+
+ first->tri( first, &prim );
+ }
+ break;
+
+ case GL_TRIANGLE_STRIP:
+ for (i = 0; i+2 < count; i++) {
+ if (i & 1) {
+ prim.v[0] = get_vertex( draw, elts[i + 1] );
+ prim.v[1] = get_vertex( draw, elts[i + 0] );
+ prim.v[2] = get_vertex( draw, elts[i + 2] );
+ }
+ else {
+ prim.v[0] = get_vertex( draw, elts[i + 0] );
+ prim.v[1] = get_vertex( draw, elts[i + 1] );
+ prim.v[2] = get_vertex( draw, elts[i + 2] );
+ }
+
+ first->tri( first, &prim );
+ }
+ break;
+
+ case GL_TRIANGLE_FAN:
+ if (count >= 3) {
+ prim.v[0] = get_vertex( draw, elts[0] );
+ prim.v[1] = 0;
+ prim.v[2] = get_vertex( draw, elts[1] );
+
+ for (i = 0; i+2 < count; i++) {
+ prim.v[1] = prim.v[2];
+ prim.v[2] = get_vertex( draw, elts[i+2] );
+
+ first->tri( first, &prim );
+ }
+ }
+ break;
+
+ case GL_QUADS:
+ for (i = 0; i+3 < count; i += 4) {
+ do_quad( first,
+ get_vertex( draw, elts[i + 0] ),
+ get_vertex( draw, elts[i + 1] ),
+ get_vertex( draw, elts[i + 2] ),
+ get_vertex( draw, elts[i + 3] ));
+ }
+ break;
+
+ case GL_QUAD_STRIP:
+ for (i = 0; i+3 < count; i += 2) {
+ do_quad( first,
+ get_vertex( draw, elts[i + 2] ),
+ get_vertex( draw, elts[i + 0] ),
+ get_vertex( draw, elts[i + 1] ),
+ get_vertex( draw, elts[i + 3] ));
+ }
+ break;
+
+
+ case GL_POLYGON:
+ if (count >= 3) {
+ prim.v[0] = 0;
+ prim.v[1] = get_vertex( draw, elts[1] );
+ prim.v[2] = get_vertex( draw, elts[0] );
+
+ for (i = 0; i+2 < count; i++) {
+ prim.v[0] = prim.v[1];
+ prim.v[1] = get_vertex( draw, elts[i+2] );
+
+ first->tri( first, &prim );
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+}
+
+static void draw_prim( struct draw_context *draw,
+ GLuint start,
+ GLuint count )
+{
+ struct prim_stage * const first = draw->softpipe->prim.first;
+ struct prim_header prim;
+ GLuint i;
+
+// _mesa_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
+
+ prim.det = 0; /* valid from cull stage onwards */
+ prim.v[0] = 0;
+ prim.v[1] = 0;
+ prim.v[2] = 0;
+
+ switch (draw->prim) {
+ case GL_POINTS:
+ for (i = 0; i < count; i ++) {
+ prim.v[0] = get_vertex( draw, start + i );
+ first->point( first, &prim );
+ }
+ break;
+
+ case GL_LINES:
+ for (i = 0; i+1 < count; i += 2) {
+ prim.v[0] = get_vertex( draw, start + i + 0 );
+ prim.v[1] = get_vertex( draw, start + i + 1 );
+
+ first->line( first, &prim );
+ }
+ break;
+
+ case GL_LINE_LOOP:
+ if (count >= 2) {
+ for (i = 1; i < count; i++) {
+ prim.v[0] = get_vertex( draw, start + i - 1 );
+ prim.v[1] = get_vertex( draw, start + i );
+ first->line( first, &prim );
+ }
+
+ prim.v[0] = get_vertex( draw, start + count - 1 );
+ prim.v[1] = get_vertex( draw, start + 0 );
+ first->line( first, &prim );
+ }
+ break;
+
+ case GL_LINE_STRIP:
+ if (count >= 2) {
+ prim.v[0] = 0;
+ prim.v[1] = get_vertex( draw, start + 0 );
+
+ for (i = 1; i < count; i++) {
+ prim.v[0] = prim.v[1];
+ prim.v[1] = get_vertex( draw, start + i );
+
+ first->line( first, &prim );
+ }
+ }
+ break;
+
+ case GL_TRIANGLES:
+ for (i = 0; i+2 < count; i += 3) {
+ prim.v[0] = get_vertex( draw, start + i + 0 );
+ prim.v[1] = get_vertex( draw, start + i + 1 );
+ prim.v[2] = get_vertex( draw, start + i + 2 );
+
+ first->tri( first, &prim );
+ }
+ break;
+
+ case GL_TRIANGLE_STRIP:
+ for (i = 0; i+2 < count; i++) {
+ if (i & 1) {
+ prim.v[0] = get_vertex( draw, start + i + 1 );
+ prim.v[1] = get_vertex( draw, start + i + 0 );
+ prim.v[2] = get_vertex( draw, start + i + 2 );
+ }
+ else {
+ prim.v[0] = get_vertex( draw, start + i + 0 );
+ prim.v[1] = get_vertex( draw, start + i + 1 );
+ prim.v[2] = get_vertex( draw, start + i + 2 );
+ }
+
+ first->tri( first, &prim );
+ }
+ break;
+
+ case GL_TRIANGLE_FAN:
+ if (count >= 3) {
+ prim.v[0] = get_vertex( draw, start + 0 );
+ prim.v[1] = 0;
+ prim.v[2] = get_vertex( draw, start + 1 );
+
+ for (i = 0; i+2 < count; i++) {
+ prim.v[1] = prim.v[2];
+ prim.v[2] = get_vertex( draw, start + i + 2 );
+
+ first->tri( first, &prim );
+ }
+ }
+ break;
+
+
+ case GL_QUADS:
+ for (i = 0; i+3 < count; i += 4) {
+ do_quad( first,
+ get_vertex( draw, start + i + 0 ),
+ get_vertex( draw, start + i + 1 ),
+ get_vertex( draw, start + i + 2 ),
+ get_vertex( draw, start + i + 3 ));
+ }
+ break;
+
+ case GL_QUAD_STRIP:
+ for (i = 0; i+3 < count; i += 2) {
+ do_quad( first,
+ get_vertex( draw, start + i + 2 ),
+ get_vertex( draw, start + i + 0 ),
+ get_vertex( draw, start + i + 1 ),
+ get_vertex( draw, start + i + 3 ));
+ }
+ break;
+
+ case GL_POLYGON:
+ if (count >= 3) {
+ prim.v[0] = 0;
+ prim.v[1] = get_vertex( draw, start + 1 );
+ prim.v[2] = get_vertex( draw, start + 0 );
+
+ for (i = 0; i+2 < count; i++) {
+ prim.v[0] = prim.v[1];
+ prim.v[1] = get_vertex( draw, start + i + 2 );
+
+ first->tri( first, &prim );
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+}
+
+
+static void draw_release_vertices( struct draw_context *draw )
+{
+ draw->softpipe->prim.first->end( draw->softpipe->prim.first );
+
+ FREE(draw->verts);
+ draw->verts = NULL;
+}
+
+
+struct header_dword {
+ GLuint clipmask:12;
+ GLuint edgeflag:1;
+ GLuint pad:19;
+};
+
+
+static void
+build_vertex_headers( struct draw_context *draw,
+ struct vertex_buffer *VB )
+{
+ if (draw->header.storage == NULL) {
+ draw->header.stride = sizeof(GLfloat);
+ draw->header.size = 1;
+ draw->header.storage = ALIGN_MALLOC( VB->Size * sizeof(GLfloat), 32 );
+ draw->header.data = draw->header.storage;
+ draw->header.count = 0;
+ draw->header.flags = VEC_SIZE_1 | VEC_MALLOC;
+ }
+
+ /* Build vertex header attribute.
+ *
+ */
+
+ {
+ GLuint i;
+ struct header_dword *header = (struct header_dword *)draw->header.storage;
+
+ /* yes its a hack
+ */
+ assert(sizeof(*header) == sizeof(GLfloat));
+
+ draw->header.count = VB->Count;
+
+ if (VB->EdgeFlag) {
+ for (i = 0; i < VB->Count; i++) {
+ header[i].clipmask = VB->ClipMask[i];
+ header[i].edgeflag = VB->EdgeFlag[i];
+ header[i].pad = 0;
+ }
+ }
+ else if (VB->ClipOrMask) {
+ for (i = 0; i < VB->Count; i++) {
+ header[i].clipmask = VB->ClipMask[i];
+ header[i].edgeflag = 0;
+ header[i].pad = 0;
+ }
+ }
+ else {
+ for (i = 0; i < VB->Count; i++) {
+ header[i].clipmask = 0;
+ header[i].edgeflag = 0;
+ header[i].pad = 0;
+ }
+ }
+ }
+
+ VB->AttribPtr[VF_ATTRIB_VERTEX_HEADER] = &draw->header;
+}
+
+
+
+
+
+static GLuint draw_prim_info(GLenum mode, GLuint *first, GLuint *incr)
+{
+ switch (mode) {
+ case GL_POINTS:
+ *first = 1;
+ *incr = 1;
+ return 0;
+ case GL_LINES:
+ *first = 2;
+ *incr = 2;
+ return 0;
+ case GL_LINE_STRIP:
+ *first = 2;
+ *incr = 1;
+ return 0;
+ case GL_LINE_LOOP:
+ *first = 2;
+ *incr = 1;
+ return 1;
+ case GL_TRIANGLES:
+ *first = 3;
+ *incr = 3;
+ return 0;
+ case GL_TRIANGLE_STRIP:
+ *first = 3;
+ *incr = 1;
+ return 0;
+ case GL_TRIANGLE_FAN:
+ case GL_POLYGON:
+ *first = 3;
+ *incr = 1;
+ return 1;
+ case GL_QUADS:
+ *first = 4;
+ *incr = 4;
+ return 0;
+ case GL_QUAD_STRIP:
+ *first = 4;
+ *incr = 2;
+ return 0;
+ default:
+ assert(0);
+ *first = 1;
+ *incr = 1;
+ return 0;
+ }
+}
+
+
+static GLuint trim( GLuint count, GLuint first, GLuint incr )
+{
+ if (count < first)
+ return 0;
+ else
+ return count - (count - first) % incr;
+}
+
+
+/* This is a hack & will all go away.
+ */
+void draw_vb(struct draw_context *draw,
+ struct vertex_buffer *VB )
+{
+ GLuint i;
+
+ VB->AttribPtr[VF_ATTRIB_POS] = VB->NdcPtr;
+ VB->AttribPtr[VF_ATTRIB_BFC0] = VB->ColorPtr[1];
+ VB->AttribPtr[VF_ATTRIB_BFC1] = VB->SecondaryColorPtr[1];
+ VB->AttribPtr[VF_ATTRIB_CLIP_POS] = VB->ClipPtr;
+
+ /* Build vertex headers:
+ */
+ build_vertex_headers( draw, VB );
+
+ draw->in_vb = 1;
+
+ /* Allocate the vertices:
+ */
+ draw_allocate_vertices( draw, VB->Count );
+
+ /* Bind the vb outputs:
+ */
+ vf_set_sources( draw->vf, VB->AttribPtr, 0 );
+
+ /* Build the hardware or prim-pipe vertices:
+ */
+ vf_emit_vertices( draw->vf, VB->Count, draw->verts );
+
+
+ for (i = 0; i < VB->PrimitiveCount; i++) {
+
+ GLenum mode = VB->Primitive[i].mode;
+ GLuint start = VB->Primitive[i].start;
+ GLuint length, first, incr;
+
+ /* Trim the primitive down to a legal size.
+ */
+ draw_prim_info( mode, &first, &incr );
+ length = trim( VB->Primitive[i].count, first, incr );
+
+ if (!length)
+ continue;
+
+ if (draw->prim != mode)
+ draw_set_prim( draw, mode );
+
+ if (VB->Elts) {
+ draw_indexed_prim( draw,
+ VB->Elts + start,
+ length );
+ }
+ else {
+ draw_prim( draw,
+ start,
+ length );
+ }
+ }
+
+ draw_release_vertices( draw );
+ draw->verts = NULL;
+ draw->in_vb = 0;
+}
+
+void draw_set_viewport( struct draw_context *draw,
+ const GLfloat *scale,
+ const GLfloat *translate )
+{
+ assert(!draw->in_vb);
+ vf_set_vp_scale_translate( draw->vf, scale, translate );
+}
+
+
+
+struct draw_context *draw_create( struct softpipe_context *softpipe )
+{
+ struct draw_context *draw = CALLOC_STRUCT( draw_context );
+ draw->softpipe = softpipe;
+ draw->vf = vf_create( GL_TRUE );
+
+ return draw;
+}
+
+
+void draw_destroy( struct draw_context *draw )
+{
+ if (draw->header.storage)
+ ALIGN_FREE( draw->header.storage );
+
+ vf_destroy( draw->vf );
+
+ FREE( draw );
+}
+
+#define EMIT_ATTR( ATTR, STYLE ) \
+do { \
+ draw->attrs[draw->nr_attrs].attrib = ATTR; \
+ draw->attrs[draw->nr_attrs].format = STYLE; \
+ draw->nr_attrs++; \
+} while (0)
+
+
+void draw_set_vertex_attributes( struct draw_context *draw,
+ const GLuint *attrs,
+ GLuint nr_attrs )
+{
+ GLuint i;
+
+ draw->nr_attrs = 0;
+
+ EMIT_ATTR(VF_ATTRIB_VERTEX_HEADER, EMIT_1F);
+ EMIT_ATTR(VF_ATTRIB_CLIP_POS, EMIT_4F);
+
+ assert(attrs[0] == VF_ATTRIB_POS);
+ EMIT_ATTR(attrs[0], EMIT_4F_VIEWPORT);
+
+ for (i = 1; i < nr_attrs; i++)
+ EMIT_ATTR(attrs[i], EMIT_4F);
+
+ draw->vertex_size = vf_set_vertex_attributes( draw->vf, draw->attrs, draw->nr_attrs, 0 );
+}
+
+
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "imports.h"
-
-#include "tnl/t_context.h"
-#include "vf/vf.h"
-
-#include "sp_context.h"
-#include "sp_prim.h"
-#include "sp_headers.h"
-#include "sp_draw.h"
-
-/* This file is a temporary set of hooks to allow us to use the tnl/
- * and vf/ modules until we have replacements in pipe.
- */
-
-
-struct draw_context
-{
- struct softpipe_context *softpipe;
-
- struct vf_attr_map attrs[VF_ATTRIB_MAX];
- GLuint nr_attrs;
- GLuint vertex_size;
- struct vertex_fetch *vf;
-
- GLubyte *verts;
- GLuint nr_vertices;
- GLboolean in_vb;
-
- GLenum prim;
-
- /* Helper for tnl:
- */
- GLvector4f header;
-};
-
-
-static struct vertex_header *get_vertex( struct draw_context *pipe,
- GLuint i )
-{
- return (struct vertex_header *)(pipe->verts + i * pipe->vertex_size);
-}
-
-
-
-static void draw_allocate_vertices( struct draw_context *draw,
- GLuint nr_vertices )
-{
- draw->nr_vertices = nr_vertices;
- draw->verts = MALLOC( nr_vertices * draw->vertex_size );
-
- draw->softpipe->prim.first->begin( draw->softpipe->prim.first );
-}
-
-static void draw_set_prim( struct draw_context *draw,
- GLenum prim )
-{
- draw->prim = prim;
-
- /* Not done yet - need to force edgeflags to 1 in strip/fan
- * primitives.
- */
-#if 0
- switch (prim) {
- case GL_TRIANGLES:
- case GL_POLYGON:
- case GL_QUADS:
- case GL_QUAD_STRIP: /* yes, we need this */
- respect_edgeflags( pipe, GL_TRUE );
- break;
-
- default:
- respect_edgeflags( pipe, GL_FALSE );
- break;
- }
-#endif
-}
-
-
-
-static void do_quad( struct prim_stage *first,
- struct vertex_header *v0,
- struct vertex_header *v1,
- struct vertex_header *v2,
- struct vertex_header *v3 )
-{
- struct prim_header prim;
-
- {
- GLuint tmp = v1->edgeflag;
- v1->edgeflag = 0;
-
- prim.v[0] = v0;
- prim.v[1] = v1;
- prim.v[2] = v3;
- first->tri( first, &prim );
-
- v1->edgeflag = tmp;
- }
-
- {
- GLuint tmp = v3->edgeflag;
- v3->edgeflag = 0;
-
- prim.v[0] = v1;
- prim.v[1] = v2;
- prim.v[2] = v3;
- first->tri( first, &prim );
-
- v3->edgeflag = tmp;
- }
-}
-
-
-
-
-static void draw_indexed_prim( struct draw_context *draw,
- const GLuint *elts,
- GLuint count )
-{
- struct prim_stage * const first = draw->softpipe->prim.first;
- struct prim_header prim;
- GLuint i;
-
- prim.det = 0; /* valid from cull stage onwards */
- prim.v[0] = 0;
- prim.v[1] = 0;
- prim.v[2] = 0;
-
- switch (draw->prim) {
- case GL_POINTS:
- for (i = 0; i < count; i ++) {
- prim.v[0] = get_vertex( draw, elts[i] );
-
- first->point( first, &prim );
- }
- break;
-
- case GL_LINES:
- for (i = 0; i+1 < count; i += 2) {
- prim.v[0] = get_vertex( draw, elts[i + 0] );
- prim.v[1] = get_vertex( draw, elts[i + 1] );
-
- first->line( first, &prim );
- }
- break;
-
- case GL_LINE_LOOP:
- if (count >= 2) {
- for (i = 1; i < count; i++) {
- prim.v[0] = get_vertex( draw, elts[i-1] );
- prim.v[1] = get_vertex( draw, elts[i] );
- first->line( first, &prim );
- }
-
- prim.v[0] = get_vertex( draw, elts[count-1] );
- prim.v[1] = get_vertex( draw, elts[0] );
- first->line( first, &prim );
- }
- break;
-
- case GL_LINE_STRIP:
- /* I'm guessing it will be necessary to have something like a
- * render->reset_line_stipple() method to properly support
- * splitting strips into primitives like this. Alternately we
- * could just scan ahead to find individual clipped lines and
- * otherwise leave the strip intact - that might be better, but
- * require more complex code here.
- */
- if (count >= 2) {
- prim.v[0] = 0;
- prim.v[1] = get_vertex( draw, elts[0] );
-
- for (i = 1; i < count; i++) {
- prim.v[0] = prim.v[1];
- prim.v[1] = get_vertex( draw, elts[i] );
-
- first->line( first, &prim );
- }
- }
- break;
-
- case GL_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- prim.v[0] = get_vertex( draw, elts[i + 0] );
- prim.v[1] = get_vertex( draw, elts[i + 1] );
- prim.v[2] = get_vertex( draw, elts[i + 2] );
-
- first->tri( first, &prim );
- }
- break;
-
- case GL_TRIANGLE_STRIP:
- for (i = 0; i+2 < count; i++) {
- if (i & 1) {
- prim.v[0] = get_vertex( draw, elts[i + 1] );
- prim.v[1] = get_vertex( draw, elts[i + 0] );
- prim.v[2] = get_vertex( draw, elts[i + 2] );
- }
- else {
- prim.v[0] = get_vertex( draw, elts[i + 0] );
- prim.v[1] = get_vertex( draw, elts[i + 1] );
- prim.v[2] = get_vertex( draw, elts[i + 2] );
- }
-
- first->tri( first, &prim );
- }
- break;
-
- case GL_TRIANGLE_FAN:
- if (count >= 3) {
- prim.v[0] = get_vertex( draw, elts[0] );
- prim.v[1] = 0;
- prim.v[2] = get_vertex( draw, elts[1] );
-
- for (i = 0; i+2 < count; i++) {
- prim.v[1] = prim.v[2];
- prim.v[2] = get_vertex( draw, elts[i+2] );
-
- first->tri( first, &prim );
- }
- }
- break;
-
- case GL_QUADS:
- for (i = 0; i+3 < count; i += 4) {
- do_quad( first,
- get_vertex( draw, elts[i + 0] ),
- get_vertex( draw, elts[i + 1] ),
- get_vertex( draw, elts[i + 2] ),
- get_vertex( draw, elts[i + 3] ));
- }
- break;
-
- case GL_QUAD_STRIP:
- for (i = 0; i+3 < count; i += 2) {
- do_quad( first,
- get_vertex( draw, elts[i + 2] ),
- get_vertex( draw, elts[i + 0] ),
- get_vertex( draw, elts[i + 1] ),
- get_vertex( draw, elts[i + 3] ));
- }
- break;
-
-
- case GL_POLYGON:
- if (count >= 3) {
- prim.v[0] = 0;
- prim.v[1] = get_vertex( draw, elts[1] );
- prim.v[2] = get_vertex( draw, elts[0] );
-
- for (i = 0; i+2 < count; i++) {
- prim.v[0] = prim.v[1];
- prim.v[1] = get_vertex( draw, elts[i+2] );
-
- first->tri( first, &prim );
- }
- }
- break;
-
- default:
- assert(0);
- break;
- }
-}
-
-static void draw_prim( struct draw_context *draw,
- GLuint start,
- GLuint count )
-{
- struct prim_stage * const first = draw->softpipe->prim.first;
- struct prim_header prim;
- GLuint i;
-
-// _mesa_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
-
- prim.det = 0; /* valid from cull stage onwards */
- prim.v[0] = 0;
- prim.v[1] = 0;
- prim.v[2] = 0;
-
- switch (draw->prim) {
- case GL_POINTS:
- for (i = 0; i < count; i ++) {
- prim.v[0] = get_vertex( draw, start + i );
- first->point( first, &prim );
- }
- break;
-
- case GL_LINES:
- for (i = 0; i+1 < count; i += 2) {
- prim.v[0] = get_vertex( draw, start + i + 0 );
- prim.v[1] = get_vertex( draw, start + i + 1 );
-
- first->line( first, &prim );
- }
- break;
-
- case GL_LINE_LOOP:
- if (count >= 2) {
- for (i = 1; i < count; i++) {
- prim.v[0] = get_vertex( draw, start + i - 1 );
- prim.v[1] = get_vertex( draw, start + i );
- first->line( first, &prim );
- }
-
- prim.v[0] = get_vertex( draw, start + count - 1 );
- prim.v[1] = get_vertex( draw, start + 0 );
- first->line( first, &prim );
- }
- break;
-
- case GL_LINE_STRIP:
- if (count >= 2) {
- prim.v[0] = 0;
- prim.v[1] = get_vertex( draw, start + 0 );
-
- for (i = 1; i < count; i++) {
- prim.v[0] = prim.v[1];
- prim.v[1] = get_vertex( draw, start + i );
-
- first->line( first, &prim );
- }
- }
- break;
-
- case GL_TRIANGLES:
- for (i = 0; i+2 < count; i += 3) {
- prim.v[0] = get_vertex( draw, start + i + 0 );
- prim.v[1] = get_vertex( draw, start + i + 1 );
- prim.v[2] = get_vertex( draw, start + i + 2 );
-
- first->tri( first, &prim );
- }
- break;
-
- case GL_TRIANGLE_STRIP:
- for (i = 0; i+2 < count; i++) {
- if (i & 1) {
- prim.v[0] = get_vertex( draw, start + i + 1 );
- prim.v[1] = get_vertex( draw, start + i + 0 );
- prim.v[2] = get_vertex( draw, start + i + 2 );
- }
- else {
- prim.v[0] = get_vertex( draw, start + i + 0 );
- prim.v[1] = get_vertex( draw, start + i + 1 );
- prim.v[2] = get_vertex( draw, start + i + 2 );
- }
-
- first->tri( first, &prim );
- }
- break;
-
- case GL_TRIANGLE_FAN:
- if (count >= 3) {
- prim.v[0] = get_vertex( draw, start + 0 );
- prim.v[1] = 0;
- prim.v[2] = get_vertex( draw, start + 1 );
-
- for (i = 0; i+2 < count; i++) {
- prim.v[1] = prim.v[2];
- prim.v[2] = get_vertex( draw, start + i + 2 );
-
- first->tri( first, &prim );
- }
- }
- break;
-
-
- case GL_QUADS:
- for (i = 0; i+3 < count; i += 4) {
- do_quad( first,
- get_vertex( draw, start + i + 0 ),
- get_vertex( draw, start + i + 1 ),
- get_vertex( draw, start + i + 2 ),
- get_vertex( draw, start + i + 3 ));
- }
- break;
-
- case GL_QUAD_STRIP:
- for (i = 0; i+3 < count; i += 2) {
- do_quad( first,
- get_vertex( draw, start + i + 2 ),
- get_vertex( draw, start + i + 0 ),
- get_vertex( draw, start + i + 1 ),
- get_vertex( draw, start + i + 3 ));
- }
- break;
-
- case GL_POLYGON:
- if (count >= 3) {
- prim.v[0] = 0;
- prim.v[1] = get_vertex( draw, start + 1 );
- prim.v[2] = get_vertex( draw, start + 0 );
-
- for (i = 0; i+2 < count; i++) {
- prim.v[0] = prim.v[1];
- prim.v[1] = get_vertex( draw, start + i + 2 );
-
- first->tri( first, &prim );
- }
- }
- break;
-
- default:
- assert(0);
- break;
- }
-}
-
-
-static void draw_release_vertices( struct draw_context *draw )
-{
- draw->softpipe->prim.first->end( draw->softpipe->prim.first );
-
- FREE(draw->verts);
- draw->verts = NULL;
-}
-
-
-struct header_dword {
- GLuint clipmask:12;
- GLuint edgeflag:1;
- GLuint pad:19;
-};
-
-
-static void
-build_vertex_headers( struct draw_context *draw,
- struct vertex_buffer *VB )
-{
- if (draw->header.storage == NULL) {
- draw->header.stride = sizeof(GLfloat);
- draw->header.size = 1;
- draw->header.storage = ALIGN_MALLOC( VB->Size * sizeof(GLfloat), 32 );
- draw->header.data = draw->header.storage;
- draw->header.count = 0;
- draw->header.flags = VEC_SIZE_1 | VEC_MALLOC;
- }
-
- /* Build vertex header attribute.
- *
- */
-
- {
- GLuint i;
- struct header_dword *header = (struct header_dword *)draw->header.storage;
-
- /* yes its a hack
- */
- assert(sizeof(*header) == sizeof(GLfloat));
-
- draw->header.count = VB->Count;
-
- if (VB->EdgeFlag) {
- for (i = 0; i < VB->Count; i++) {
- header[i].clipmask = VB->ClipMask[i];
- header[i].edgeflag = VB->EdgeFlag[i];
- header[i].pad = 0;
- }
- }
- else if (VB->ClipOrMask) {
- for (i = 0; i < VB->Count; i++) {
- header[i].clipmask = VB->ClipMask[i];
- header[i].edgeflag = 0;
- header[i].pad = 0;
- }
- }
- else {
- for (i = 0; i < VB->Count; i++) {
- header[i].clipmask = 0;
- header[i].edgeflag = 0;
- header[i].pad = 0;
- }
- }
- }
-
- VB->AttribPtr[VF_ATTRIB_VERTEX_HEADER] = &draw->header;
-}
-
-
-
-
-
-static GLuint draw_prim_info(GLenum mode, GLuint *first, GLuint *incr)
-{
- switch (mode) {
- case GL_POINTS:
- *first = 1;
- *incr = 1;
- return 0;
- case GL_LINES:
- *first = 2;
- *incr = 2;
- return 0;
- case GL_LINE_STRIP:
- *first = 2;
- *incr = 1;
- return 0;
- case GL_LINE_LOOP:
- *first = 2;
- *incr = 1;
- return 1;
- case GL_TRIANGLES:
- *first = 3;
- *incr = 3;
- return 0;
- case GL_TRIANGLE_STRIP:
- *first = 3;
- *incr = 1;
- return 0;
- case GL_TRIANGLE_FAN:
- case GL_POLYGON:
- *first = 3;
- *incr = 1;
- return 1;
- case GL_QUADS:
- *first = 4;
- *incr = 4;
- return 0;
- case GL_QUAD_STRIP:
- *first = 4;
- *incr = 2;
- return 0;
- default:
- assert(0);
- *first = 1;
- *incr = 1;
- return 0;
- }
-}
-
-
-static GLuint trim( GLuint count, GLuint first, GLuint incr )
-{
- if (count < first)
- return 0;
- else
- return count - (count - first) % incr;
-}
-
-
-/* This is a hack & will all go away.
- */
-void draw_vb(struct draw_context *draw,
- struct vertex_buffer *VB )
-{
- GLuint i;
-
- VB->AttribPtr[VF_ATTRIB_POS] = VB->NdcPtr;
- VB->AttribPtr[VF_ATTRIB_BFC0] = VB->ColorPtr[1];
- VB->AttribPtr[VF_ATTRIB_BFC1] = VB->SecondaryColorPtr[1];
- VB->AttribPtr[VF_ATTRIB_CLIP_POS] = VB->ClipPtr;
-
- /* Build vertex headers:
- */
- build_vertex_headers( draw, VB );
-
- draw->in_vb = 1;
-
- /* Allocate the vertices:
- */
- draw_allocate_vertices( draw, VB->Count );
-
- /* Bind the vb outputs:
- */
- vf_set_sources( draw->vf, VB->AttribPtr, 0 );
-
- /* Build the hardware or prim-pipe vertices:
- */
- vf_emit_vertices( draw->vf, VB->Count, draw->verts );
-
-
- for (i = 0; i < VB->PrimitiveCount; i++) {
-
- GLenum mode = VB->Primitive[i].mode;
- GLuint start = VB->Primitive[i].start;
- GLuint length, first, incr;
-
- /* Trim the primitive down to a legal size.
- */
- draw_prim_info( mode, &first, &incr );
- length = trim( VB->Primitive[i].count, first, incr );
-
- if (!length)
- continue;
-
- if (draw->prim != mode)
- draw_set_prim( draw, mode );
-
- if (VB->Elts) {
- draw_indexed_prim( draw,
- VB->Elts + start,
- length );
- }
- else {
- draw_prim( draw,
- start,
- length );
- }
- }
-
- draw_release_vertices( draw );
- draw->verts = NULL;
- draw->in_vb = 0;
-}
-
-void draw_set_viewport( struct draw_context *draw,
- const GLfloat *scale,
- const GLfloat *translate )
-{
- assert(!draw->in_vb);
- vf_set_vp_scale_translate( draw->vf, scale, translate );
-}
-
-
-
-struct draw_context *draw_create( struct softpipe_context *softpipe )
-{
- struct draw_context *draw = CALLOC_STRUCT( draw_context );
- draw->softpipe = softpipe;
- draw->vf = vf_create( GL_TRUE );
-
- return draw;
-}
-
-
-void draw_destroy( struct draw_context *draw )
-{
- if (draw->header.storage)
- ALIGN_FREE( draw->header.storage );
-
- vf_destroy( draw->vf );
-
- FREE( draw );
-}
-
-#define EMIT_ATTR( ATTR, STYLE ) \
-do { \
- draw->attrs[draw->nr_attrs].attrib = ATTR; \
- draw->attrs[draw->nr_attrs].format = STYLE; \
- draw->nr_attrs++; \
-} while (0)
-
-
-void draw_set_vertex_attributes( struct draw_context *draw,
- const GLuint *attrs,
- GLuint nr_attrs )
-{
- GLuint i;
-
- draw->nr_attrs = 0;
-
- EMIT_ATTR(VF_ATTRIB_VERTEX_HEADER, EMIT_1F);
- EMIT_ATTR(VF_ATTRIB_CLIP_POS, EMIT_4F);
-
- assert(attrs[0] == VF_ATTRIB_POS);
- EMIT_ATTR(attrs[0], EMIT_4F_VIEWPORT);
-
- for (i = 1; i < nr_attrs; i++)
- EMIT_ATTR(attrs[i], EMIT_4F);
-
- draw->vertex_size = vf_set_vertex_attributes( draw->vf, draw->attrs, draw->nr_attrs, 0 );
-}
-
-
+++ /dev/null
-
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef G_DRAW_H
-#define G_DRAW_H
-
-#include "glheader.h"
-#include "pipe/p_state.h"
-
-
-struct draw_context;
-
-struct draw_context *draw_create( struct softpipe_context *softpipe );
-
-void draw_destroy( struct draw_context *draw );
-
-void draw_set_viewport( struct draw_context *draw,
- const GLfloat *scale,
- const GLfloat *translate );
-
-void draw_set_vertex_attributes( struct draw_context *draw,
- const GLuint *attrs,
- GLuint nr_attrs );
-
-void draw_vb(struct draw_context *draw,
- struct vertex_buffer *VB );
-
-#endif
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef G_PRIM_H
-#define G_PRIM_H
-
-#include "glheader.h"
-#include "sp_headers.h"
-
-struct softpipe_context;
-
-struct prim_stage *prim_setup( struct softpipe_context *context );
-struct prim_stage *prim_unfilled( struct softpipe_context *context );
-struct prim_stage *prim_twoside( struct softpipe_context *context );
-struct prim_stage *prim_offset( struct softpipe_context *context );
-struct prim_stage *prim_clip( struct softpipe_context *context );
-struct prim_stage *prim_flatshade( struct softpipe_context *context );
-struct prim_stage *prim_cull( struct softpipe_context *context );
-
-
-/* Internal structs and helpers for the primitive clip/setup pipeline:
- */
-struct prim_stage {
- struct softpipe_context *softpipe;
-
- struct prim_stage *next;
-
- struct vertex_header **tmp;
- GLuint nr_tmps;
-
- void (*begin)( struct prim_stage * );
-
- void (*point)( struct prim_stage *,
- struct prim_header * );
-
- void (*line)( struct prim_stage *,
- struct prim_header * );
-
- void (*tri)( struct prim_stage *,
- struct prim_header * );
-
- void (*end)( struct prim_stage * );
-};
-
-
-
-/* Get a writeable copy of a vertex:
- */
-static INLINE struct vertex_header *
-dup_vert( struct prim_stage *stage,
- const struct vertex_header *vert,
- GLuint idx )
-{
- struct vertex_header *tmp = stage->tmp[idx];
- memcpy(tmp, vert, stage->softpipe->prim.vertex_size );
- return tmp;
-}
-
-void prim_free_tmps( struct prim_stage *stage );
-void prim_alloc_tmps( struct prim_stage *stage, GLuint nr );
-
-
-#endif
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "imports.h"
-#include "macros.h"
-
-#include "sp_context.h"
-#include "sp_prim.h"
-
-struct clipper {
- struct prim_stage stage;
-
- GLuint active_user_planes;
-};
-
-/* This is a bit confusing:
- */
-static INLINE struct clipper *clipper_stage( struct prim_stage *stage )
-{
- return (struct clipper *)stage;
-}
-
-
-#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
-
-
-/* All attributes are float[4], so this is easy:
- */
-static void interp_attr( GLfloat *fdst,
- GLfloat t,
- const GLfloat *fin,
- const GLfloat *fout )
-{
- fdst[0] = LINTERP( t, fout[0], fin[0] );
- fdst[1] = LINTERP( t, fout[1], fin[1] );
- fdst[2] = LINTERP( t, fout[2], fin[2] );
- fdst[3] = LINTERP( t, fout[3], fin[3] );
-}
-
-
-
-
-/* Interpolate between two vertices to produce a third.
- */
-static void interp( struct clipper *clip,
- struct vertex_header *dst,
- GLfloat t,
- const struct vertex_header *out,
- const struct vertex_header *in )
-{
- const GLuint nr_attrs = clip->stage.softpipe->nr_attrs;
- GLuint j;
-
- /* Vertex header.
- */
- {
- dst->clipmask = 0;
- dst->edgeflag = 0;
- dst->pad = 0;
- }
-
- /* Clip coordinates: interpolate normally
- */
- {
- interp_attr(dst->clip, t, in->clip, out->clip);
- }
-
- /* Do the projective divide and insert window coordinates:
- */
- {
- const GLfloat *pos = dst->clip;
- const GLfloat *scale = clip->stage.softpipe->viewport.scale;
- const GLfloat *trans = clip->stage.softpipe->viewport.translate;
- GLfloat oow;
-
- oow = 1.0 / pos[3];
-
- dst->data[0][0] = pos[0] * oow * scale[0] + trans[0];
- dst->data[0][1] = pos[1] * oow * scale[1] + trans[1];
- dst->data[0][2] = pos[2] * oow * scale[2] + trans[2];
- dst->data[0][3] = oow;
- }
-
-
- /* Other attributes
- */
- for (j = 1; j < nr_attrs-1; j++) {
- interp_attr(dst->data[j], t, in->data[j], out->data[j]);
- }
-}
-
-
-#define CLIP_USER_BIT 0x40
-#define CLIP_CULL_BIT 0x80
-
-
-static INLINE GLfloat dot4( const GLfloat *a,
- const GLfloat *b )
-{
- GLfloat result = (a[0]*b[0] +
- a[1]*b[1] +
- a[2]*b[2] +
- a[3]*b[3]);
-
- return result;
-}
-
-
-#if 0
-static INLINE void do_tri( struct prim_stage *next,
- struct prim_header *header )
-{
- GLuint i;
- for (i = 0; i < 3; i++) {
- GLfloat *ndc = header->v[i]->data[0];
- _mesa_printf("ndc %f %f %f\n", ndc[0], ndc[1], ndc[2]);
- assert(ndc[0] >= -1 && ndc[0] <= 641);
- assert(ndc[1] >= 30 && ndc[1] <= 481);
- }
- _mesa_printf("\n");
- next->tri(next, header);
-}
-#endif
-
-
-static void emit_poly( struct prim_stage *stage,
- struct vertex_header **inlist,
- GLuint n )
-{
- struct prim_header header;
- GLuint i;
-
- for (i = 2; i < n; i++) {
- header.v[0] = inlist[0];
- header.v[1] = inlist[i-1];
- header.v[2] = inlist[i];
-
- {
- GLuint tmp0 = header.v[0]->edgeflag;
- GLuint tmp2 = header.v[2]->edgeflag;
-
- if (i != 2) header.v[0]->edgeflag = 0;
- if (i != n-1) header.v[2]->edgeflag = 0;
-
- stage->next->tri( stage->next, &header );
-
- header.v[0]->edgeflag = tmp0;
- header.v[2]->edgeflag = tmp2;
- }
- }
-}
-
-
-#if 0
-static void emit_poly( struct prim_stage *stage )
-{
- GLuint i;
-
- for (i = 2; i < n; i++) {
- header->v[0] = inlist[0];
- header->v[1] = inlist[i-1];
- header->v[2] = inlist[i];
-
- stage->next->tri( stage->next, header );
- }
-}
-#endif
-
-
-/* Clip a triangle against the viewport and user clip planes.
- */
-static void
-do_clip_tri( struct prim_stage *stage,
- struct prim_header *header,
- GLuint clipmask )
-{
- struct clipper *clipper = clipper_stage( stage );
- struct vertex_header *a[MAX_CLIPPED_VERTICES];
- struct vertex_header *b[MAX_CLIPPED_VERTICES];
- struct vertex_header **inlist = a;
- struct vertex_header **outlist = b;
- GLuint tmpnr = 0;
- GLuint n = 3;
- GLuint i;
-
- inlist[0] = header->v[0];
- inlist[1] = header->v[1];
- inlist[2] = header->v[2];
-
- /* XXX: Note stupid hack to deal with tnl's 8-bit clipmask. Remove
- * this once we correctly use 16bit masks for userclip planes.
- */
- clipmask &= ~CLIP_CULL_BIT;
- if (clipmask & CLIP_USER_BIT) {
- clipmask &= ~CLIP_USER_BIT;
- clipmask |= clipper->active_user_planes;
- }
-
- while (clipmask && n >= 3) {
- GLuint plane_idx = ffs(clipmask)-1;
- const GLfloat *plane = clipper->stage.softpipe->plane[plane_idx];
- struct vertex_header *vert_prev = inlist[0];
- GLfloat dp_prev = dot4( vert_prev->clip, plane );
- GLuint outcount = 0;
-
- clipmask &= ~(1<<plane_idx);
-
- inlist[n] = inlist[0]; /* prevent rotation of vertices */
-
- for (i = 1; i <= n; i++) {
- struct vertex_header *vert = inlist[i];
-
- GLfloat dp = dot4( vert->clip, plane );
-
- if (!IS_NEGATIVE(dp_prev)) {
- outlist[outcount++] = vert_prev;
- }
-
- if (DIFFERENT_SIGNS(dp, dp_prev)) {
- struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++];
- outlist[outcount++] = new_vert;
-
- if (IS_NEGATIVE(dp)) {
- /* Going out of bounds. Avoid division by zero as we
- * know dp != dp_prev from DIFFERENT_SIGNS, above.
- */
- GLfloat t = dp / (dp - dp_prev);
- interp( clipper, new_vert, t, vert, vert_prev );
-
- /* Force edgeflag true in this case:
- */
- new_vert->edgeflag = 1;
- } else {
- /* Coming back in.
- */
- GLfloat t = dp_prev / (dp_prev - dp);
- interp( clipper, new_vert, t, vert_prev, vert );
-
- /* Copy starting vert's edgeflag:
- */
- new_vert->edgeflag = vert_prev->edgeflag;
- }
- }
-
- vert_prev = vert;
- dp_prev = dp;
- }
-
- {
- struct vertex_header **tmp = inlist;
- inlist = outlist;
- outlist = tmp;
- n = outcount;
- }
- }
-
- /* Emit the polygon as triangles to the setup stage:
- */
- if (n >= 3)
- emit_poly( stage, inlist, n );
-}
-
-
-/* Clip a line against the viewport and user clip planes.
- */
-static void
-do_clip_line( struct prim_stage *stage,
- struct prim_header *header,
- GLuint clipmask )
-{
- struct clipper *clipper = clipper_stage( stage );
- struct vertex_header *v0 = header->v[0];
- struct vertex_header *v1 = header->v[1];
- const GLfloat *pos0 = v0->clip;
- const GLfloat *pos1 = v1->clip;
- GLfloat t0 = 0;
- GLfloat t1 = 0;
-
- /* XXX: Note stupid hack to deal with tnl's 8-bit clipmask. Remove
- * this once we correctly use 16bit masks for userclip planes.
- */
- clipmask &= ~CLIP_CULL_BIT;
- if (clipmask & CLIP_USER_BIT) {
- clipmask &= ~CLIP_USER_BIT;
- clipmask |= clipper->active_user_planes;
- }
-
- while (clipmask) {
- GLuint plane_idx = ffs(clipmask)-1;
- const GLfloat *plane = clipper->stage.softpipe->plane[plane_idx];
-
- clipmask &= ~(1<<plane_idx);
-
- const GLfloat dp0 = dot4( pos0, plane );
- const GLfloat dp1 = dot4( pos1, plane );
-
- if (dp1 < 0) {
- GLfloat t = dp1 / (dp1 - dp0);
- if (t > t1) t1 = t;
- }
-
- if (dp0 < 0) {
- GLfloat t = dp0 / (dp0 - dp1);
- if (t > t0) t0 = t;
- }
-
- if (t0 + t1 >= 1.0)
- return; /* discard */
- }
-
- if (v0->clipmask) {
- interp( clipper, stage->tmp[0], t0, v0, v1 );
- header->v[0] = stage->tmp[0];
- }
-
- if (v1->clipmask) {
- interp( clipper, stage->tmp[1], t1, v1, v0 );
- header->v[1] = stage->tmp[1];
- }
-
- stage->next->line( stage->next, header );
-}
-
-
-
-static void clip_begin( struct prim_stage *stage )
-{
- struct clipper *clipper = clipper_stage(stage);
- GLuint nr = stage->softpipe->nr_planes;
-
- /* Hacky bitmask to use when we hit CLIP_USER_BIT:
- */
- clipper->active_user_planes = ((1<<nr)-1) & ~((1<<6)-1);
-
- stage->next->begin( stage->next );
-}
-
-static void
-clip_point( struct prim_stage *stage,
- struct prim_header *header )
-{
- if (header->v[0]->clipmask == 0)
- stage->next->point( stage->next, header );
-}
-
-
-static void
-clip_line( struct prim_stage *stage,
- struct prim_header *header )
-{
- GLuint clipmask = (header->v[0]->clipmask |
- header->v[1]->clipmask);
-
- if (clipmask == 0) {
- stage->next->line( stage->next, header );
- }
- else if ((header->v[0]->clipmask &
- header->v[1]->clipmask) == 0) {
- do_clip_line(stage, header, clipmask);
- }
-}
-
-
-static void
-clip_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- GLuint clipmask = (header->v[0]->clipmask |
- header->v[1]->clipmask |
- header->v[2]->clipmask);
-
- if (clipmask == 0) {
- stage->next->tri( stage->next, header );
- }
- else if ((header->v[0]->clipmask &
- header->v[1]->clipmask &
- header->v[2]->clipmask) == 0) {
- do_clip_tri(stage, header, clipmask);
- }
-}
-
-static void clip_end( struct prim_stage *stage )
-{
- stage->next->end( stage->next );
-}
-
-
-struct prim_stage *prim_clip( struct softpipe_context *softpipe )
-{
- struct clipper *clipper = CALLOC_STRUCT(clipper);
-
- prim_alloc_tmps( &clipper->stage, MAX_CLIPPED_VERTICES );
-
- clipper->stage.softpipe = softpipe;
- clipper->stage.begin = clip_begin;
- clipper->stage.point = clip_point;
- clipper->stage.line = clip_line;
- clipper->stage.tri = clip_tri;
- clipper->stage.end = clip_end;
-
- return &clipper->stage;
-}
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-#include "imports.h"
-
-#include "pipe/p_defines.h"
-#include "sp_context.h"
-#include "sp_prim.h"
-
-
-
-struct cull_stage {
- struct prim_stage stage;
- GLuint mode;
-};
-
-
-
-static INLINE struct cull_stage *cull_stage( struct prim_stage *stage )
-{
- return (struct cull_stage *)stage;
-}
-
-
-static void cull_begin( struct prim_stage *stage )
-{
- struct cull_stage *cull = cull_stage(stage);
-
- cull->mode = stage->softpipe->setup.cull_mode;
-
- stage->next->begin( stage->next );
-}
-
-
-static void cull_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- /* Window coords: */
- GLfloat *v0 = (GLfloat *)&(header->v[0]->data[0]);
- GLfloat *v1 = (GLfloat *)&(header->v[1]->data[0]);
- GLfloat *v2 = (GLfloat *)&(header->v[2]->data[0]);
-
- GLfloat ex = v0[0] - v2[0];
- GLfloat ey = v0[1] - v2[1];
- GLfloat fx = v1[0] - v2[0];
- GLfloat fy = v1[1] - v2[1];
-
- header->det = ex * fy - ey * fx;
-
- _mesa_printf("%s %f\n", __FUNCTION__, header->det );
-
- if (header->det != 0) {
- GLuint mode = (header->det < 0) ? PIPE_WINDING_CW : PIPE_WINDING_CCW;
-
- if ((mode & cull_stage(stage)->mode) == 0)
- stage->next->tri( stage->next, header );
- }
-}
-
-
-static void cull_line( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->line( stage->next, header );
-}
-
-
-static void cull_point( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->point( stage->next, header );
-}
-
-static void cull_end( struct prim_stage *stage )
-{
- stage->next->end( stage->next );
-}
-
-struct prim_stage *prim_cull( struct softpipe_context *softpipe )
-{
- struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
-
- prim_alloc_tmps( &cull->stage, 0 );
-
- cull->stage.softpipe = softpipe;
- cull->stage.next = NULL;
- cull->stage.begin = cull_begin;
- cull->stage.point = cull_point;
- cull->stage.line = cull_line;
- cull->stage.tri = cull_tri;
- cull->stage.end = cull_end;
-
- return &cull->stage;
-}
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-#include "imports.h"
-
-#include "vf/vf.h"
-
-#include "sp_context.h"
-#include "sp_prim.h"
-
-
-struct flatshade_stage {
- struct prim_stage stage;
-
- const GLuint *lookup;
-};
-
-
-
-static INLINE struct flatshade_stage *flatshade_stage( struct prim_stage *stage )
-{
- return (struct flatshade_stage *)stage;
-}
-
-
-static void flatshade_begin( struct prim_stage *stage )
-{
- stage->next->begin( stage->next );
-}
-
-
-
-static INLINE void copy_attr( GLuint attr,
- struct vertex_header *dst,
- const struct vertex_header *src )
-{
- if (attr) {
- memcpy( dst->data[attr],
- src->data[attr],
- sizeof(src->data[0]) );
- }
-}
-
-static void copy_colors( struct prim_stage *stage,
- struct vertex_header *dst,
- const struct vertex_header *src )
-{
- struct flatshade_stage *flatshade = flatshade_stage(stage);
- const GLuint *lookup = flatshade->lookup;
-
- copy_attr( lookup[VF_ATTRIB_COLOR0], dst, src );
- copy_attr( lookup[VF_ATTRIB_COLOR1], dst, src );
- copy_attr( lookup[VF_ATTRIB_BFC0], dst, src );
- copy_attr( lookup[VF_ATTRIB_BFC1], dst, src );
-}
-
-
-
-/* Flatshade tri. Required for clipping and when unfilled tris are
- * active, otherwise handled by hardware.
- */
-static void flatshade_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct prim_header tmp;
-
- tmp.det = header->det;
- tmp.v[0] = dup_vert(stage, header->v[0], 0);
- tmp.v[1] = dup_vert(stage, header->v[1], 1);
- tmp.v[2] = header->v[2];
-
- copy_colors(stage, tmp.v[0], tmp.v[2]);
- copy_colors(stage, tmp.v[1], tmp.v[2]);
-
- stage->next->tri( stage->next, &tmp );
-}
-
-
-/* Flatshade line. Required for clipping.
- */
-static void flatshade_line( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct prim_header tmp;
-
- tmp.v[0] = dup_vert(stage, header->v[0], 0);
- tmp.v[1] = header->v[1];
-
- copy_colors(stage, tmp.v[0], tmp.v[1]);
-
- stage->next->line( stage->next, &tmp );
-}
-
-
-static void flatshade_point( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->point( stage->next, header );
-}
-
-static void flatshade_end( struct prim_stage *stage )
-{
- stage->next->end( stage->next );
-}
-
-struct prim_stage *prim_flatshade( struct softpipe_context *softpipe )
-{
- struct flatshade_stage *flatshade = CALLOC_STRUCT(flatshade_stage);
-
- prim_alloc_tmps( &flatshade->stage, 2 );
-
- flatshade->stage.softpipe = softpipe;
- flatshade->stage.next = NULL;
- flatshade->stage.begin = flatshade_begin;
- flatshade->stage.point = flatshade_point;
- flatshade->stage.line = flatshade_line;
- flatshade->stage.tri = flatshade_tri;
- flatshade->stage.end = flatshade_end;
-
- flatshade->lookup = softpipe->vf_attr_to_slot;
-
- return &flatshade->stage;
-}
-
-
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-#include "imports.h"
-#include "macros.h"
-
-#include "sp_context.h"
-#include "sp_prim.h"
-
-
-
-struct offset_stage {
- struct prim_stage stage;
-
- GLuint hw_data_offset;
-
- GLfloat scale;
- GLfloat units;
-};
-
-
-
-static INLINE struct offset_stage *offset_stage( struct prim_stage *stage )
-{
- return (struct offset_stage *)stage;
-}
-
-
-static void offset_begin( struct prim_stage *stage )
-{
- struct offset_stage *offset = offset_stage(stage);
-
- offset->units = stage->softpipe->setup.offset_units;
- offset->scale = stage->softpipe->setup.offset_scale;
-
- stage->next->begin( stage->next );
-}
-
-
-/* Offset tri. Some hardware can handle this, but not usually when
- * doing unfilled rendering.
- */
-static void do_offset_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct offset_stage *offset = offset_stage(stage);
- GLfloat inv_det = 1.0 / header->det;
-
- /* Window coords:
- */
- GLfloat *v0 = (GLfloat *)&(header->v[0]->data[0]);
- GLfloat *v1 = (GLfloat *)&(header->v[1]->data[0]);
- GLfloat *v2 = (GLfloat *)&(header->v[2]->data[0]);
-
- GLfloat ex = v0[0] - v2[2];
- GLfloat fx = v1[0] - v2[2];
- GLfloat ey = v0[1] - v2[2];
- GLfloat fy = v1[1] - v2[2];
- GLfloat ez = v0[2] - v2[2];
- GLfloat fz = v1[2] - v2[2];
-
- GLfloat a = ey*fz - ez*fy;
- GLfloat b = ez*fx - ex*fz;
-
- GLfloat ac = a * inv_det;
- GLfloat bc = b * inv_det;
- GLfloat zoffset;
-
- if ( ac < 0.0f ) ac = -ac;
- if ( bc < 0.0f ) bc = -bc;
-
- zoffset = offset->units + MAX2( ac, bc ) * offset->scale;
-
- v0[2] += zoffset;
- v1[2] += zoffset;
- v2[2] += zoffset;
-
- stage->next->tri( stage->next, header );
-}
-
-
-static void offset_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct prim_header tmp;
-
- tmp.det = header->det;
- tmp.v[0] = dup_vert(stage, header->v[0], 0);
- tmp.v[1] = dup_vert(stage, header->v[1], 1);
- tmp.v[2] = dup_vert(stage, header->v[2], 2);
-
- do_offset_tri( stage->next, &tmp );
-}
-
-
-
-static void offset_line( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->line( stage->next, header );
-}
-
-
-static void offset_point( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->point( stage->next, header );
-}
-
-
-static void offset_end( struct prim_stage *stage )
-{
- stage->next->end( stage->next );
-}
-
-struct prim_stage *prim_offset( struct softpipe_context *softpipe )
-{
- struct offset_stage *offset = CALLOC_STRUCT(offset_stage);
-
- prim_alloc_tmps( &offset->stage, 3 );
-
- offset->stage.softpipe = softpipe;
- offset->stage.next = NULL;
- offset->stage.begin = offset_begin;
- offset->stage.point = offset_point;
- offset->stage.line = offset_line;
- offset->stage.tri = offset_tri;
- offset->stage.end = offset_end;
-
- return &offset->stage;
-}
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-#include "imports.h"
-#include "vf/vf.h"
-
-#include "pipe/p_defines.h"
-#include "sp_context.h"
-#include "sp_prim.h"
-
-
-struct twoside_stage {
- struct prim_stage stage;
-
- GLfloat facing;
- const GLuint *lookup;
-};
-
-
-static INLINE struct twoside_stage *twoside_stage( struct prim_stage *stage )
-{
- return (struct twoside_stage *)stage;
-}
-
-
-static void twoside_begin( struct prim_stage *stage )
-{
- struct twoside_stage *twoside = twoside_stage(stage);
-
- twoside->facing = (stage->softpipe->setup.front_winding == PIPE_WINDING_CW) ? -1 : 1;
-
- stage->next->begin( stage->next );
-}
-
-
-static INLINE void copy_color( GLuint attr_dst,
- GLuint attr_src,
- struct vertex_header *v )
-{
- if (attr_dst && attr_src) {
- memcpy( v->data[attr_dst],
- v->data[attr_src],
- sizeof(v->data[0]) );
- }
-}
-
-
-static struct vertex_header *copy_bfc( struct twoside_stage *twoside,
- const struct vertex_header *v,
- GLuint idx )
-{
- struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
-
- copy_color( twoside->lookup[VF_ATTRIB_COLOR0],
- twoside->lookup[VF_ATTRIB_BFC0],
- tmp );
-
- copy_color( twoside->lookup[VF_ATTRIB_COLOR1],
- twoside->lookup[VF_ATTRIB_BFC1],
- tmp );
-
- return tmp;
-}
-
-
-/* Twoside tri:
- */
-static void twoside_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct twoside_stage *twoside = twoside_stage(stage);
-
- if (header->det * twoside->facing < 0) {
- struct prim_header tmp;
-
- tmp.det = header->det;
- tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
- tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
- tmp.v[2] = copy_bfc(twoside, header->v[2], 2);
-
- stage->next->tri( stage->next, &tmp );
- }
- else {
- stage->next->tri( stage->next, header );
- }
-}
-
-
-static void twoside_line( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->line( stage->next, header );
-}
-
-
-static void twoside_point( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->point( stage->next, header );
-}
-
-static void twoside_end( struct prim_stage *stage )
-{
- stage->next->end( stage->next );
-}
-
-
-
-struct prim_stage *prim_twoside( struct softpipe_context *softpipe )
-{
- struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage);
-
- prim_alloc_tmps( &twoside->stage, 3 );
-
- twoside->stage.softpipe = softpipe;
- twoside->stage.next = NULL;
- twoside->stage.begin = twoside_begin;
- twoside->stage.point = twoside_point;
- twoside->stage.line = twoside_line;
- twoside->stage.tri = twoside_tri;
- twoside->stage.end = twoside_end;
-
- twoside->lookup = softpipe->vf_attr_to_slot;
-
- return &twoside->stage;
-}
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-#include "imports.h"
-
-#include "sp_context.h"
-#include "sp_prim.h"
-#include "pipe/p_defines.h"
-
-
-struct unfilled_stage {
- struct prim_stage stage;
-
- GLuint mode[2];
-};
-
-
-static INLINE struct unfilled_stage *unfilled_stage( struct prim_stage *stage )
-{
- return (struct unfilled_stage *)stage;
-}
-
-
-static void unfilled_begin( struct prim_stage *stage )
-{
- struct unfilled_stage *unfilled = unfilled_stage(stage);
-
- unfilled->mode[0] = stage->softpipe->setup.fill_ccw;
- unfilled->mode[1] = stage->softpipe->setup.fill_cw;
-
- stage->next->begin( stage->next );
-}
-
-static void point( struct prim_stage *stage,
- struct vertex_header *v0 )
-{
- struct prim_header tmp;
- tmp.v[0] = v0;
- stage->next->point( stage->next, &tmp );
-}
-
-static void line( struct prim_stage *stage,
- struct vertex_header *v0,
- struct vertex_header *v1 )
-{
- struct prim_header tmp;
- tmp.v[0] = v0;
- tmp.v[1] = v1;
- stage->next->line( stage->next, &tmp );
-}
-
-
-static void points( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct vertex_header *v0 = header->v[0];
- struct vertex_header *v1 = header->v[1];
- struct vertex_header *v2 = header->v[2];
-
- if (v0->edgeflag) point( stage, v0 );
- if (v1->edgeflag) point( stage, v1 );
- if (v2->edgeflag) point( stage, v2 );
-}
-
-static void lines( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct vertex_header *v0 = header->v[0];
- struct vertex_header *v1 = header->v[1];
- struct vertex_header *v2 = header->v[2];
-
- if (v0->edgeflag) line( stage, v0, v1 );
- if (v1->edgeflag) line( stage, v1, v2 );
- if (v2->edgeflag) line( stage, v2, v0 );
-}
-
-
-/* Unfilled tri:
- *
- * Note edgeflags in the vertex struct is not sufficient as we will
- * need to manipulate them when decomposing primitives???
- */
-static void unfilled_tri( struct prim_stage *stage,
- struct prim_header *header )
-{
- struct unfilled_stage *unfilled = unfilled_stage(stage);
- GLuint mode = unfilled->mode[header->det < 0];
-
- switch (mode) {
- case PIPE_POLYGON_MODE_FILL:
- stage->next->tri( stage->next, header );
- break;
- case PIPE_POLYGON_MODE_LINE:
- lines( stage, header );
- break;
- case PIPE_POLYGON_MODE_POINT:
- points( stage, header );
- break;
- default:
- abort();
- }
-}
-
-static void unfilled_line( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->line( stage->next, header );
-}
-
-
-static void unfilled_point( struct prim_stage *stage,
- struct prim_header *header )
-{
- stage->next->point( stage->next, header );
-}
-
-
-static void unfilled_end( struct prim_stage *stage )
-{
- stage->next->end( stage->next );
-}
-
-struct prim_stage *prim_unfilled( struct softpipe_context *softpipe )
-{
- struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage);
-
- prim_alloc_tmps( &unfilled->stage, 0 );
-
- unfilled->stage.softpipe = softpipe;
- unfilled->stage.next = NULL;
- unfilled->stage.tmp = NULL;
- unfilled->stage.begin = unfilled_begin;
- unfilled->stage.point = unfilled_point;
- unfilled->stage.line = unfilled_line;
- unfilled->stage.tri = unfilled_tri;
- unfilled->stage.end = unfilled_end;
-
- return &unfilled->stage;
-}