18e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/**************************************************************************
28e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
38e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
48e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * All Rights Reserved.
58e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
68e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
78e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * copy of this software and associated documentation files (the
88e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * "Software"), to deal in the Software without restriction, including
98e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * the following conditions:
138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * The above copyright notice and this permission notice (including the
158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * of the Software.
178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
208e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
248e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell *
268e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell **************************************************************************/
278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
285b06424a1507dadad8832d557e79f68a3b68b9c2Brian/**
295b06424a1507dadad8832d557e79f68a3b68b9c2Brian * \brief  Clipping stage
305b06424a1507dadad8832d557e79f68a3b68b9c2Brian *
315b06424a1507dadad8832d557e79f68a3b68b9c2Brian * \author  Keith Whitwell <keith@tungstengraphics.com>
328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
338e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
345b06424a1507dadad8832d557e79f68a3b68b9c2Brian
354f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
364f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
374f25420bdd834e81a3e22733304efc5261c2998aBrian Paul
3882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell#include "pipe/p_shader_tokens.h"
3982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
40280bcff1fa200b790d8712946a4ffbaa47a67433Keith Whitwell#include "draw_vs.h"
41507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h"
424625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert#include "draw_fs.h"
438e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
447668e53c8c64570d66a626c96302a953164f319eBrian
453fc926f3740da9ec27853d158243055f3cb43d43Brian#ifndef IS_NEGATIVE
463fc926f3740da9ec27853d158243055f3cb43d43Brian#define IS_NEGATIVE(X) ((X) < 0.0)
473fc926f3740da9ec27853d158243055f3cb43d43Brian#endif
483fc926f3740da9ec27853d158243055f3cb43d43Brian
493fc926f3740da9ec27853d158243055f3cb43d43Brian#ifndef DIFFERENT_SIGNS
503fc926f3740da9ec27853d158243055f3cb43d43Brian#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
513fc926f3740da9ec27853d158243055f3cb43d43Brian#endif
523fc926f3740da9ec27853d158243055f3cb43d43Brian
533fc926f3740da9ec27853d158243055f3cb43d43Brian#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1)
543fc926f3740da9ec27853d158243055f3cb43d43Brian
558e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
56f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian
57bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paulstruct clip_stage {
58ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brian   struct draw_stage stage;      /**< base class */
598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
604625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   /* List of the attributes to be flatshaded. */
614625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   uint num_flat_attribs;
624625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   uint flat_attribs[PIPE_MAX_SHADER_OUTPUTS];
634625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert
644625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   /* Mask of attributes in noperspective mode */
654625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   boolean noperspective_attribs[PIPE_MAX_SHADER_OUTPUTS];
6682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
673fc926f3740da9ec27853d158243055f3cb43d43Brian   float (*plane)[4];
688e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell};
698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
70279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian
71d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul/** Cast wrapper */
72bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paulstatic INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
74bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   return (struct clip_stage *)stage;
758e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
768e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
778e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
788e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
798e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
808e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
818e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* All attributes are float[4], so this is easy:
828e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
83d88b6e19c14900f4cad94cf7a28d159369463108Brian Paulstatic void interp_attr( float dst[4],
843fc926f3740da9ec27853d158243055f3cb43d43Brian			 float t,
85d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul			 const float in[4],
86d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul			 const float out[4] )
878e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
88d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst[0] = LINTERP( t, out[0], in[0] );
89d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst[1] = LINTERP( t, out[1], in[1] );
90d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst[2] = LINTERP( t, out[2], in[2] );
91d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst[3] = LINTERP( t, out[3], in[3] );
928e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
938e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
94c87361340352850ba793a481c969081b6ecfc0c6Brian Paul
95d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul/**
964625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert * Copy flat shaded attributes src vertex to dst vertex.
97d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul */
984625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibertstatic void copy_flat( struct draw_stage *stage,
994625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert                       struct vertex_header *dst,
1004625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert                       const struct vertex_header *src )
10182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
102bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   const struct clip_stage *clipper = clip_stage(stage);
10382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   uint i;
1044625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   for (i = 0; i < clipper->num_flat_attribs; i++) {
1054625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      const uint attr = clipper->flat_attribs[i];
10682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      COPY_4FV(dst->data[attr], src->data[attr]);
10782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
10882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
1098e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Interpolate between two vertices to produce a third.
1138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
114bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paulstatic void interp( const struct clip_stage *clip,
1158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		    struct vertex_header *dst,
1163fc926f3740da9ec27853d158243055f3cb43d43Brian		    float t,
1178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		    const struct vertex_header *out,
1188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		    const struct vertex_header *in )
1198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
12089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
12189d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
12240c5987ed84f9f0b8bb1f707bb13c1aafc39330aDave Airlie   const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw);
1233fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned j;
1244625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   float t_nopersp;
1258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1268e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Vertex header.
1278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
128d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst->clipmask = 0;
129d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst->edgeflag = 0;        /* will get overwritten later */
1301865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   dst->have_clipdist = in->have_clipdist;
131d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   dst->vertex_id = UNDEFINED_VERTEX_ID;
1328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
133d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   /* Interpolate the clip-space coords.
1348e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
135d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   interp_attr(dst->clip, t, in->clip, out->clip);
13640c5987ed84f9f0b8bb1f707bb13c1aafc39330aDave Airlie   /* interpolate the clip-space position */
13740c5987ed84f9f0b8bb1f707bb13c1aafc39330aDave Airlie   interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos);
1388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
139d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul   /* Do the projective divide and viewport transformation to get
140d88b6e19c14900f4cad94cf7a28d159369463108Brian Paul    * new window coordinates:
1418e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
1428e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   {
14340c5987ed84f9f0b8bb1f707bb13c1aafc39330aDave Airlie      const float *pos = dst->pre_clip_pos;
1443fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *scale = clip->stage.draw->viewport.scale;
1453fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *trans = clip->stage.draw->viewport.translate;
146eb51761b825018bf89080855d0fa3fcb84b9c215michal      const float oow = 1.0f / pos[3];
1478e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1482161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
1492161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1];
1502161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2];
1512161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][3] = oow;
1528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
1534625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert
1544625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   /**
1554625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * Compute the t in screen-space instead of 3d space to use
1564625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * for noperspective interpolation.
1574625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    *
1584625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * The points can be aligned with the X axis, so in that case try
1594625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * the Y.  When both points are at the same screen position, we can
1604625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * pick whatever value (the interpolated point won't be in front
1614625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * anyway), so just use the 3d t.
1624625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    */
1634625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   {
1644625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      int k;
1654625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      t_nopersp = t;
1664625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      for (k = 0; k < 2; k++)
1674625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         if (in->data[pos_attr][k] != out->data[pos_attr][k]) {
1684625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert            t_nopersp = (dst->data[pos_attr][k] - out->data[pos_attr][k]) /
1694625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert               (in->data[pos_attr][k] - out->data[pos_attr][k]);
1704625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert            break;
1714625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         }
1724625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   }
1738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1748e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Other attributes
1758e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
1762161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   for (j = 0; j < nr_attrs; j++) {
1774625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      if (j != pos_attr && j != clip_attr) {
1784625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         if (clip->noperspective_attribs[j])
1794625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert            interp_attr(dst->data[j], t_nopersp, in->data[j], out->data[j]);
1804625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         else
1814625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert            interp_attr(dst->data[j], t, in->data[j], out->data[j]);
1824625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      }
1838e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
1848e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
1858e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1868e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
18774fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul/**
18874fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul * Emit a post-clip polygon to the next pipeline stage.  The polygon
18974fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul * will be convex and the provoking vertex will always be vertex[0].
19074fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul */
191ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstatic void emit_poly( struct draw_stage *stage,
1928e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		       struct vertex_header **inlist,
193f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                       const boolean *edgeflags,
194aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian		       unsigned n,
19582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell		       const struct prim_header *origPrim)
1968e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
1978e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct prim_header header;
1983fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned i;
199cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   ushort edge_first, edge_middle, edge_last;
2008e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
201cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   if (stage->draw->rasterizer->flatshade_first) {
202cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_first  = DRAW_PIPE_EDGE_FLAG_0;
203cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_middle = DRAW_PIPE_EDGE_FLAG_1;
204cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_last   = DRAW_PIPE_EDGE_FLAG_2;
205cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   }
206cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   else {
207cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_first  = DRAW_PIPE_EDGE_FLAG_2;
208cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_middle = DRAW_PIPE_EDGE_FLAG_0;
209cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_last   = DRAW_PIPE_EDGE_FLAG_1;
210cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   }
211f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
212f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   if (!edgeflags[0])
213f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      edge_first = 0;
214f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul
215aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian   /* later stages may need the determinant, but only the sign matters */
216aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian   header.det = origPrim->det;
217f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell   header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
218f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell   header.pad = 0;
219aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian
22014a13e3767f080a48a4ae01f803dd0bc8754f441Keith Whitwell   for (i = 2; i < n; i++, header.flags = edge_middle) {
22174fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul      /* order the triangle verts to respect the provoking vertex mode */
222ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      if (stage->draw->rasterizer->flatshade_first) {
22374fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul         header.v[0] = inlist[0];  /* the provoking vertex */
224ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[1] = inlist[i-1];
225ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[2] = inlist[i];
226ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
227ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      else {
228ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[0] = inlist[i-1];
229ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[1] = inlist[i];
23074fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul         header.v[2] = inlist[0];  /* the provoking vertex */
231ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
232f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
233f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      if (!edgeflags[i-1]) {
234f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul         header.flags &= ~edge_middle;
235f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      }
236f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul
237f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      if (i == n - 1 && edgeflags[i])
238c87361340352850ba793a481c969081b6ecfc0c6Brian Paul         header.flags |= edge_last;
239f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
240f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell      if (0) {
2412f0d1396e4c1626b3b1ac799bd29e86a9530369eKeith Whitwell         const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
242f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell         uint j, k;
24374fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul         debug_printf("Clipped tri: (flat-shade-first = %d)\n",
24474fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul                      stage->draw->rasterizer->flatshade_first);
245f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell         for (j = 0; j < 3; j++) {
246f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell            for (k = 0; k < vs->info.num_outputs; k++) {
247f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell               debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
248f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][0],
249f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][1],
250f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][2],
251f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][3]);
2525ffc5cce1507fd407399911abefeea988a69394eBrian Paul            }
2535ffc5cce1507fd407399911abefeea988a69394eBrian Paul         }
2548e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
255f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
256f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell      stage->next->tri( stage->next, &header );
2578e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
2588e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
2598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
260c87361340352850ba793a481c969081b6ecfc0c6Brian Paul
261507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwellstatic INLINE float
262507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwelldot4(const float *a, const float *b)
263507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell{
264c87361340352850ba793a481c969081b6ecfc0c6Brian Paul   return (a[0] * b[0] +
265c87361340352850ba793a481c969081b6ecfc0c6Brian Paul           a[1] * b[1] +
266c87361340352850ba793a481c969081b6ecfc0c6Brian Paul           a[2] * b[2] +
267c87361340352850ba793a481c969081b6ecfc0c6Brian Paul           a[3] * b[3]);
268507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell}
2698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2701865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie/*
2711865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie * this function extracts the clip distance for the current plane,
2721865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie * it first checks if the shader provided a clip distance, otherwise
2731865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie * it works out the value using the clipvertex
2741865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie */
2751865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airliestatic INLINE float getclipdist(const struct clip_stage *clipper,
2761865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie                                struct vertex_header *vert,
2771865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie                                int plane_idx)
2781865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie{
2791865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   const float *plane;
2801865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   float dp;
2811865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   if (vert->have_clipdist && plane_idx >= 6) {
2821865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      /* pick the correct clipdistance element from the output vectors */
2831865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      int _idx = plane_idx - 6;
2841865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      int cdi = _idx >= 4;
2851865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      int vidx = cdi ? _idx - 4 : _idx;
2861865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      dp = vert->data[draw_current_shader_clipdistance_output(clipper->stage.draw, cdi)][vidx];
2871865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   } else {
2881865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      plane = clipper->plane[plane_idx];
2891865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      dp = dot4(vert->clip, plane);
2901865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   }
2911865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie   return dp;
2921865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie}
2938e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2948e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Clip a triangle against the viewport and user clip planes.
2958e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
2968e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
297ea470eec86715cd2bc9aa86d36e6ea803d0d4017Briando_clip_tri( struct draw_stage *stage,
2988e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	     struct prim_header *header,
2993fc926f3740da9ec27853d158243055f3cb43d43Brian	     unsigned clipmask )
3008e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
301bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   struct clip_stage *clipper = clip_stage( stage );
3028e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *a[MAX_CLIPPED_VERTICES];
3038e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *b[MAX_CLIPPED_VERTICES];
3048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header **inlist = a;
3058e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header **outlist = b;
3063fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned tmpnr = 0;
3073fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned n = 3;
3083fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned i;
309f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   boolean aEdges[MAX_CLIPPED_VERTICES];
310f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   boolean bEdges[MAX_CLIPPED_VERTICES];
311f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   boolean *inEdges = aEdges;
312f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   boolean *outEdges = bEdges;
3138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   inlist[0] = header->v[0];
3158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   inlist[1] = header->v[1];
3168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   inlist[2] = header->v[2];
3178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
318f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   /*
319f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    * Note: at this point we can't just use the per-vertex edge flags.
320f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    * We have to observe the edge flag bits set in header->flags which
321f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    * were set during primitive decomposition.  Put those flags into
322f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    * an edge flags array which parallels the vertex array.
323f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    * Later, in the 'unfilled' pipeline stage we'll draw the edge if both
324f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    * the header.flags bit is set AND the per-vertex edgeflag field is set.
325f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul    */
326f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   inEdges[0] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_0);
327f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   inEdges[1] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_1);
328f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul   inEdges[2] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_2);
329f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul
3308e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   while (clipmask && n >= 3) {
331f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      const unsigned plane_idx = ffs(clipmask)-1;
332f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      const boolean is_user_clip_plane = plane_idx >= 6;
3338e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      struct vertex_header *vert_prev = inlist[0];
334f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      boolean *edge_prev = &inEdges[0];
3351865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      float dp_prev;
3363fc926f3740da9ec27853d158243055f3cb43d43Brian      unsigned outcount = 0;
3378e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3381865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      dp_prev = getclipdist(clipper, vert_prev, plane_idx);
3398e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      clipmask &= ~(1<<plane_idx);
3408e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
341ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul      assert(n < MAX_CLIPPED_VERTICES);
342440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca      if (n >= MAX_CLIPPED_VERTICES)
343440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca         return;
3448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      inlist[n] = inlist[0]; /* prevent rotation of vertices */
345f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      inEdges[n] = inEdges[0];
3468e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3478e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      for (i = 1; i <= n; i++) {
3488e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 struct vertex_header *vert = inlist[i];
349f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul         boolean *edge = &inEdges[i];
3508e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3511865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie         float dp = getclipdist(clipper, vert, plane_idx);
3528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3538e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 if (!IS_NEGATIVE(dp_prev)) {
354ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(outcount < MAX_CLIPPED_VERTICES);
355440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca            if (outcount >= MAX_CLIPPED_VERTICES)
356440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca               return;
357f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul            outEdges[outcount] = *edge_prev;
3588e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    outlist[outcount++] = vert_prev;
3598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 }
3608e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3618e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 if (DIFFERENT_SIGNS(dp, dp_prev)) {
362ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul	    struct vertex_header *new_vert;
363f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul            boolean *new_edge;
364ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul
365440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca            assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
366440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca            if (tmpnr >= MAX_CLIPPED_VERTICES + 1)
367440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca               return;
368ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            new_vert = clipper->stage.tmp[tmpnr++];
369ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul
370ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(outcount < MAX_CLIPPED_VERTICES);
371440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca            if (outcount >= MAX_CLIPPED_VERTICES)
372440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca               return;
373f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul
374f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul            new_edge = &outEdges[outcount];
3758e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    outlist[outcount++] = new_vert;
3768e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3778e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    if (IS_NEGATIVE(dp)) {
3788e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Going out of bounds.  Avoid division by zero as we
3798e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		* know dp != dp_prev from DIFFERENT_SIGNS, above.
3808e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
3813fc926f3740da9ec27853d158243055f3cb43d43Brian	       float t = dp / (dp - dp_prev);
3828e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       interp( clipper, new_vert, t, vert, vert_prev );
3838e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
384f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul	       /* Whether or not to set edge flag for the new vert depends
385f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                * on whether it's a user-defined clipping plane.  We're
386f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                * copying NVIDIA's behaviour here.
3878e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
388f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul               if (is_user_clip_plane) {
389f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                  /* we want to see an edge along the clip plane */
390f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                  *new_edge = TRUE;
391f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                  new_vert->edgeflag = TRUE;
392f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul               }
393f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul               else {
394f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                  /* we don't want to see an edge along the frustum clip plane */
395f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                  *new_edge = *edge_prev;
396f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul                  new_vert->edgeflag = FALSE;
397f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul               }
398f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul	    }
399f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul            else {
4008e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Coming back in.
4018e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
4023fc926f3740da9ec27853d158243055f3cb43d43Brian	       float t = dp_prev / (dp_prev - dp);
4038e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       interp( clipper, new_vert, t, vert_prev, vert );
4048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4058e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Copy starting vert's edgeflag:
4068e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
4078e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       new_vert->edgeflag = vert_prev->edgeflag;
408f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul               *new_edge = *edge_prev;
4098e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    }
4108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 }
4118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 vert_prev = vert;
413f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul         edge_prev = edge;
4148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 dp_prev = dp;
4158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
4168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
417c87361340352850ba793a481c969081b6ecfc0c6Brian Paul      /* swap in/out lists */
4188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      {
4198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 struct vertex_header **tmp = inlist;
4208e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 inlist = outlist;
4218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 outlist = tmp;
4228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 n = outcount;
4238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
424f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      {
425f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul         boolean *tmp = inEdges;
426f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul         inEdges = outEdges;
427f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul         outEdges = tmp;
428f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      }
429f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul
4308e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
4318e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
43274fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul   /* If flat-shading, copy provoking vertex color to polygon vertex[0]
43382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell    */
4348b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell   if (n >= 3) {
4354625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      if (clipper->num_flat_attribs) {
4368b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell         if (stage->draw->rasterizer->flatshade_first) {
4378b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell            if (inlist[0] != header->v[0]) {
4388b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell               assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
439440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca               if (tmpnr >= MAX_CLIPPED_VERTICES + 1)
440440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca                  return;
4418b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell               inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
4424625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert               copy_flat(stage, inlist[0], header->v[0]);
4438b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell            }
444cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
4458b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell         else {
4468b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell            if (inlist[0] != header->v[2]) {
4478b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell               assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
448440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca               if (tmpnr >= MAX_CLIPPED_VERTICES + 1)
449440129521c36bc2c2e59c462a94394b2f42a847eJosé Fonseca                  return;
4508b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell               inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
4514625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert               copy_flat(stage, inlist[0], header->v[2]);
4528b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell            }
453cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
454ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
4558b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell
4568b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell      /* Emit the polygon as triangles to the setup stage:
4578b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell       */
458f6572017b94a137a4102342ebf6cd20dedc90271Brian Paul      emit_poly( stage, inlist, inEdges, n, header );
4598b597b4ea4290301bd97587db5389f151cb5f25fKeith Whitwell   }
4608e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
4618e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4628e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4638e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Clip a line against the viewport and user clip planes.
4648e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
4658e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
466ea470eec86715cd2bc9aa86d36e6ea803d0d4017Briando_clip_line( struct draw_stage *stage,
4678e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	      struct prim_header *header,
4683fc926f3740da9ec27853d158243055f3cb43d43Brian	      unsigned clipmask )
4698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
470bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   const struct clip_stage *clipper = clip_stage( stage );
4718e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *v0 = header->v[0];
4728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *v1 = header->v[1];
473f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian   float t0 = 0.0F;
474f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian   float t1 = 0.0F;
475a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   struct prim_header newprim;
4768e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4778e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   while (clipmask) {
4783fc926f3740da9ec27853d158243055f3cb43d43Brian      const unsigned plane_idx = ffs(clipmask)-1;
4791865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      const float dp0 = getclipdist(clipper, v0, plane_idx);
4801865f341d8f45b389061fc08d2da90b7aa8a6099Dave Airlie      const float dp1 = getclipdist(clipper, v1, plane_idx);
4818e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
482f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      if (dp1 < 0.0F) {
4833fc926f3740da9ec27853d158243055f3cb43d43Brian	 float t = dp1 / (dp1 - dp0);
4845b06424a1507dadad8832d557e79f68a3b68b9c2Brian         t1 = MAX2(t1, t);
4858e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
4868e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
487f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      if (dp0 < 0.0F) {
4883fc926f3740da9ec27853d158243055f3cb43d43Brian	 float t = dp0 / (dp0 - dp1);
4895b06424a1507dadad8832d557e79f68a3b68b9c2Brian         t0 = MAX2(t0, t);
4908e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
4918e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
492f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      if (t0 + t1 >= 1.0F)
4938e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 return; /* discard */
494a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian
495a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
4968e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
4978e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4988e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (v0->clipmask) {
4998e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      interp( clipper, stage->tmp[0], t0, v0, v1 );
5004625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      copy_flat(stage, stage->tmp[0], v0);
501a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[0] = stage->tmp[0];
502a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   }
503a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   else {
504a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[0] = v0;
5058e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
5068e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5078e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (v1->clipmask) {
5088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      interp( clipper, stage->tmp[1], t1, v1, v0 );
509a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[1] = stage->tmp[1];
510a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   }
511a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   else {
512a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[1] = v1;
5138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
5148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
515a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   stage->next->line( stage->next, &newprim );
5168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
5178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
520ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianclip_point( struct draw_stage *stage,
5218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    struct prim_header *header )
5228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
523cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin   if (header->v[0]->clipmask == 0)
5248e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      stage->next->point( stage->next, header );
5258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
5268e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5288e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
529ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianclip_line( struct draw_stage *stage,
5308e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	   struct prim_header *header )
5318e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
5323fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned clipmask = (header->v[0]->clipmask |
533f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian                        header->v[1]->clipmask);
5348e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5358e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (clipmask == 0) {
536279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian      /* no clipping needed */
5378e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      stage->next->line( stage->next, header );
5388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
539cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin   else if ((header->v[0]->clipmask &
540cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin             header->v[1]->clipmask) == 0) {
5418e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      do_clip_line(stage, header, clipmask);
5428e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
543f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian   /* else, totally clipped */
5448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
5458e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5468e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5478e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
548ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianclip_tri( struct draw_stage *stage,
5498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	  struct prim_header *header )
5508e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
5513fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned clipmask = (header->v[0]->clipmask |
552f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian                        header->v[1]->clipmask |
553f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian                        header->v[2]->clipmask);
5548e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5558e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (clipmask == 0) {
556279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian      /* no clipping needed */
5578e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      stage->next->tri( stage->next, header );
5588e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
559cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin   else if ((header->v[0]->clipmask &
560cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin             header->v[1]->clipmask &
561cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin             header->v[2]->clipmask) == 0) {
5628e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      do_clip_tri(stage, header, clipmask);
5638e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
5648e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
5658e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
566c87361340352850ba793a481c969081b6ecfc0c6Brian Paul
56782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell/* Update state.  Could further delay this until we hit the first
56882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell * primitive that really requires clipping.
56982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell */
57082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void
57182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellclip_init_state( struct draw_stage *stage )
57282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
573bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   struct clip_stage *clipper = clip_stage( stage );
5744625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
5754625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   const struct draw_fragment_shader *fs = stage->draw->fs.fragment_shader;
5764625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   uint i;
57782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
5784625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   /* We need to know for each attribute what kind of interpolation is
5794625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * done on it (flat, smooth or noperspective).  But the information
5804625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * is not directly accessible for outputs, only for inputs.  So we
5814625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * have to match semantic name and index between the VS (or GS/ES)
5824625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * outputs and the FS inputs to get to the interpolation mode.
5834625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    *
5844625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * The only hitch is with gl_FrontColor/gl_BackColor which map to
5854625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * gl_Color, and their Secondary versions.  First there are (up to)
5864625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * two outputs for one input, so we tuck the information in a
5874625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * specific array.  Second if they don't have qualifiers, the
5884625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * default value has to be picked from the global shade mode.
589b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert    *
590b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert    * Of course, if we don't have a fragment shader in the first
591b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert    * place, defaults should be used.
5924625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    */
59382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
5944625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   /* First pick up the interpolation mode for
5954625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * gl_Color/gl_SecondaryColor, with the correct default.
5964625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    */
5974625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   int indexed_interp[2];
5984625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   indexed_interp[0] = indexed_interp[1] = stage->draw->rasterizer->flatshade ?
5994625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
6004625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert
601b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert   if (fs) {
602b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert      for (i = 0; i < fs->info.num_inputs; i++) {
603b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert         if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
604b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert            if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
605b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert               indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
606b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert         }
6074625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      }
6084625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   }
60982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
6104625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   /* Then resolve the interpolation mode for every output attribute.
6114625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    *
6124625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * Given how the rest of the code, the most efficient way is to
6134625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * have a vector of flat-mode attributes, and a mask for
6144625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    * noperspective attributes.
6154625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert    */
6164625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert
6174625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   clipper->num_flat_attribs = 0;
6184625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs));
6194625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert   for (i = 0; i < vs->info.num_outputs; i++) {
6204625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      /* Find the interpolation mode for a specific attribute
6214625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert       */
6224625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      int interp;
6234625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert
6244625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      /* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
6254625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert       * from the array we've filled before. */
6264625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
6274625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert          vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
6284625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         interp = indexed_interp[vs->info.output_semantic_index[i]];
6294625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      } else {
6304625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         /* Otherwise, search in the FS inputs, with a decent default
6314625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert          * if we don't find it.
6324625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert          */
6334625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         uint j;
6344625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         interp = TGSI_INTERPOLATE_PERSPECTIVE;
635b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert         if (fs) {
636b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert            for (j = 0; j < fs->info.num_inputs; j++) {
637b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert               if (vs->info.output_semantic_name[i] == fs->info.input_semantic_name[j] &&
638b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert                   vs->info.output_semantic_index[i] == fs->info.input_semantic_index[j]) {
639b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert                  interp = fs->info.input_interpolate[j];
640b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert                  break;
641b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert               }
642b8068afafacc3071cacfbaf71f176a2943341382Olivier Galibert            }
6434625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         }
64482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      }
6454625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert
6464625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      /* If it's flat, add it to the flat vector.  Otherwise update
6474625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert       * the noperspective mask.
6484625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert       */
6494625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      if (interp == TGSI_INTERPOLATE_CONSTANT) {
6504625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         clipper->flat_attribs[clipper->num_flat_attribs] = i;
6514625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         clipper->num_flat_attribs++;
6524625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert      } else
6534625a9b1adf7a30c56e2bbeb41573fbba4465851Olivier Galibert         clipper->noperspective_attribs[i] = interp == TGSI_INTERPOLATE_LINEAR;
65482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
65582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
65682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->tri = clip_tri;
65782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->line = clip_line;
65882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
65982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
66082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
66182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
66282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void clip_first_tri( struct draw_stage *stage,
66382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			    struct prim_header *header )
66482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
66582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clip_init_state( stage );
66682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->tri( stage, header );
66782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
66882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
66982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void clip_first_line( struct draw_stage *stage,
67082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			     struct prim_header *header )
67182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
67282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clip_init_state( stage );
67382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->line( stage, header );
67482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
67582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
67682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
67782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void clip_flush( struct draw_stage *stage,
67882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			     unsigned flags )
6798e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
68082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->tri = clip_first_tri;
68182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->line = clip_first_line;
6820bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->next->flush( stage->next, flags );
6838e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
6848e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
6858e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
6860360b49afbcd839f99ba0745d01cf9dc5be4d122Brianstatic void clip_reset_stipple_counter( struct draw_stage *stage )
6870360b49afbcd839f99ba0745d01cf9dc5be4d122Brian{
6880360b49afbcd839f99ba0745d01cf9dc5be4d122Brian   stage->next->reset_stipple_counter( stage->next );
6890360b49afbcd839f99ba0745d01cf9dc5be4d122Brian}
6900360b49afbcd839f99ba0745d01cf9dc5be4d122Brian
6910360b49afbcd839f99ba0745d01cf9dc5be4d122Brian
692d75454840672f462de933724daae24a839aac48eMichalstatic void clip_destroy( struct draw_stage *stage )
693d75454840672f462de933724daae24a839aac48eMichal{
694b08102a8f3ef558743f5f952c726ba2c28b6e82eBrian   draw_free_temp_verts( stage );
695d75454840672f462de933724daae24a839aac48eMichal   FREE( stage );
696d75454840672f462de933724daae24a839aac48eMichal}
697d75454840672f462de933724daae24a839aac48eMichal
698d75454840672f462de933724daae24a839aac48eMichal
699279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian/**
700279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian * Allocate a new clipper stage.
701279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian * \return pointer to new stage object
702279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian */
703ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstruct draw_stage *draw_clip_stage( struct draw_context *draw )
7048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
705bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   struct clip_stage *clipper = CALLOC_STRUCT(clip_stage);
7060d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (clipper == NULL)
7070d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      goto fail;
7088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
709279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian   clipper->stage.draw = draw;
710eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   clipper->stage.name = "clipper";
7118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   clipper->stage.point = clip_point;
71282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clipper->stage.line = clip_first_line;
71382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clipper->stage.tri = clip_first_tri;
7140bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   clipper->stage.flush = clip_flush;
7150360b49afbcd839f99ba0745d01cf9dc5be4d122Brian   clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
716d75454840672f462de933724daae24a839aac48eMichal   clipper->stage.destroy = clip_destroy;
7178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
718279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian   clipper->plane = draw->plane;
719279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian
7201c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane   if (!draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ))
7211c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane      goto fail;
7221c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane
7238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   return &clipper->stage;
7240d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell
7250d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell fail:
7260d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (clipper)
7270d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      clipper->stage.destroy( &clipper->stage );
7280d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell
7290d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   return NULL;
7308e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
731