From: Brian Date: Mon, 9 Jul 2007 22:04:08 +0000 (-0600) Subject: Rename/move some files to modularize the primitive/draw code. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=10f4b37bd70c12c8caaa85ff5b94aec532788abd;p=mesa.git Rename/move some files to modularize the primitive/draw code. --- diff --git a/src/mesa/pipe/draw/draw_clip.c b/src/mesa/pipe/draw/draw_clip.c new file mode 100644 index 00000000000..304c43c3f48 --- /dev/null +++ b/src/mesa/pipe/draw/draw_clip.c @@ -0,0 +1,429 @@ +/************************************************************************** + * + * 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 + */ + +#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<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< 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<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; +} diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h new file mode 100644 index 00000000000..a138f812fa4 --- /dev/null +++ b/src/mesa/pipe/draw/draw_context.h @@ -0,0 +1,56 @@ + +/************************************************************************** + * + * 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 + */ + +#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 diff --git a/src/mesa/pipe/draw/draw_cull.c b/src/mesa/pipe/draw/draw_cull.c new file mode 100644 index 00000000000..63099fbee0a --- /dev/null +++ b/src/mesa/pipe/draw/draw_cull.c @@ -0,0 +1,120 @@ +/************************************************************************** + * + * 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 + */ +#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; +} diff --git a/src/mesa/pipe/draw/draw_flatshade.c b/src/mesa/pipe/draw/draw_flatshade.c new file mode 100644 index 00000000000..3a7d9de4667 --- /dev/null +++ b/src/mesa/pipe/draw/draw_flatshade.c @@ -0,0 +1,151 @@ +/************************************************************************** + * + * 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 + */ +#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; +} + + diff --git a/src/mesa/pipe/draw/draw_offset.c b/src/mesa/pipe/draw/draw_offset.c new file mode 100644 index 00000000000..5fd6ac911a5 --- /dev/null +++ b/src/mesa/pipe/draw/draw_offset.c @@ -0,0 +1,157 @@ +/************************************************************************** + * + * 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 + */ +#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; +} diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h new file mode 100644 index 00000000000..b6cbaae085d --- /dev/null +++ b/src/mesa/pipe/draw/draw_private.h @@ -0,0 +1,90 @@ +/************************************************************************** + * + * 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 + */ + +#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 diff --git a/src/mesa/pipe/draw/draw_twoside.c b/src/mesa/pipe/draw/draw_twoside.c new file mode 100644 index 00000000000..5e9f218d1e9 --- /dev/null +++ b/src/mesa/pipe/draw/draw_twoside.c @@ -0,0 +1,152 @@ +/************************************************************************** + * + * 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 + */ +#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; +} diff --git a/src/mesa/pipe/draw/draw_unfilled.c b/src/mesa/pipe/draw/draw_unfilled.c new file mode 100644 index 00000000000..ab0dab09d4b --- /dev/null +++ b/src/mesa/pipe/draw/draw_unfilled.c @@ -0,0 +1,165 @@ +/************************************************************************** + * + * 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 + */ +#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; +} diff --git a/src/mesa/pipe/draw/draw_vb.c b/src/mesa/pipe/draw/draw_vb.c new file mode 100644 index 00000000000..3fc30dd2034 --- /dev/null +++ b/src/mesa/pipe/draw/draw_vb.c @@ -0,0 +1,697 @@ +/************************************************************************** + * + * 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 + */ + +#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 ); +} + + diff --git a/src/mesa/pipe/softpipe/sp_draw.c b/src/mesa/pipe/softpipe/sp_draw.c deleted file mode 100644 index 3fc30dd2034..00000000000 --- a/src/mesa/pipe/softpipe/sp_draw.c +++ /dev/null @@ -1,697 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#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 ); -} - - diff --git a/src/mesa/pipe/softpipe/sp_draw.h b/src/mesa/pipe/softpipe/sp_draw.h deleted file mode 100644 index a138f812fa4..00000000000 --- a/src/mesa/pipe/softpipe/sp_draw.h +++ /dev/null @@ -1,56 +0,0 @@ - -/************************************************************************** - * - * 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 - */ - -#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 diff --git a/src/mesa/pipe/softpipe/sp_prim.h b/src/mesa/pipe/softpipe/sp_prim.h deleted file mode 100644 index b6cbaae085d..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim.h +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#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 diff --git a/src/mesa/pipe/softpipe/sp_prim_clip.c b/src/mesa/pipe/softpipe/sp_prim_clip.c deleted file mode 100644 index 304c43c3f48..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim_clip.c +++ /dev/null @@ -1,429 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#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<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< 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<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; -} diff --git a/src/mesa/pipe/softpipe/sp_prim_cull.c b/src/mesa/pipe/softpipe/sp_prim_cull.c deleted file mode 100644 index 63099fbee0a..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim_cull.c +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************** - * - * 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 - */ -#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; -} diff --git a/src/mesa/pipe/softpipe/sp_prim_flatshade.c b/src/mesa/pipe/softpipe/sp_prim_flatshade.c deleted file mode 100644 index 3a7d9de4667..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim_flatshade.c +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** - * - * 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 - */ -#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; -} - - diff --git a/src/mesa/pipe/softpipe/sp_prim_offset.c b/src/mesa/pipe/softpipe/sp_prim_offset.c deleted file mode 100644 index 5fd6ac911a5..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim_offset.c +++ /dev/null @@ -1,157 +0,0 @@ -/************************************************************************** - * - * 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 - */ -#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; -} diff --git a/src/mesa/pipe/softpipe/sp_prim_twoside.c b/src/mesa/pipe/softpipe/sp_prim_twoside.c deleted file mode 100644 index 5e9f218d1e9..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim_twoside.c +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************** - * - * 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 - */ -#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; -} diff --git a/src/mesa/pipe/softpipe/sp_prim_unfilled.c b/src/mesa/pipe/softpipe/sp_prim_unfilled.c deleted file mode 100644 index ab0dab09d4b..00000000000 --- a/src/mesa/pipe/softpipe/sp_prim_unfilled.c +++ /dev/null @@ -1,165 +0,0 @@ -/************************************************************************** - * - * 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 - */ -#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; -}