draw_pipe_clip.c revision ca3238f3fce89b4641833d1722d03c5d23b3e081
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"
428e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
437668e53c8c64570d66a626c96302a953164f319eBrian
443fc926f3740da9ec27853d158243055f3cb43d43Brian#ifndef IS_NEGATIVE
453fc926f3740da9ec27853d158243055f3cb43d43Brian#define IS_NEGATIVE(X) ((X) < 0.0)
463fc926f3740da9ec27853d158243055f3cb43d43Brian#endif
473fc926f3740da9ec27853d158243055f3cb43d43Brian
483fc926f3740da9ec27853d158243055f3cb43d43Brian#ifndef DIFFERENT_SIGNS
493fc926f3740da9ec27853d158243055f3cb43d43Brian#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
503fc926f3740da9ec27853d158243055f3cb43d43Brian#endif
513fc926f3740da9ec27853d158243055f3cb43d43Brian
523fc926f3740da9ec27853d158243055f3cb43d43Brian#ifndef MAX_CLIPPED_VERTICES
533fc926f3740da9ec27853d158243055f3cb43d43Brian#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1)
543fc926f3740da9ec27853d158243055f3cb43d43Brian#endif
553fc926f3740da9ec27853d158243055f3cb43d43Brian
568e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
57f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian
58bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paulstruct clip_stage {
59ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brian   struct draw_stage stage;      /**< base class */
608e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
6182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   /* Basically duplicate some of the flatshading logic here:
6282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell    */
6382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   boolean flat;
6482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   uint num_color_attribs;
6582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   uint color_attribs[4];  /* front/back primary/secondary colors */
6682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
673fc926f3740da9ec27853d158243055f3cb43d43Brian   float (*plane)[4];
688e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell};
698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
70279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian
718e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* This is a bit confusing:
728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
73bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paulstatic INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
748e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
75bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   return (struct clip_stage *)stage;
768e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
778e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
788e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
798e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
808e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
818e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
828e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* All attributes are float[4], so this is easy:
838e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
843fc926f3740da9ec27853d158243055f3cb43d43Brianstatic void interp_attr( float *fdst,
853fc926f3740da9ec27853d158243055f3cb43d43Brian			 float t,
863fc926f3740da9ec27853d158243055f3cb43d43Brian			 const float *fin,
873fc926f3740da9ec27853d158243055f3cb43d43Brian			 const float *fout )
888e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
898e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   fdst[0] = LINTERP( t, fout[0], fin[0] );
908e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   fdst[1] = LINTERP( t, fout[1], fin[1] );
918e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   fdst[2] = LINTERP( t, fout[2], fin[2] );
928e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   fdst[3] = LINTERP( t, fout[3], fin[3] );
938e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
948e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
95c87361340352850ba793a481c969081b6ecfc0c6Brian Paul
9682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void copy_colors( struct draw_stage *stage,
9782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			 struct vertex_header *dst,
9882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			 const struct vertex_header *src )
9982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
100bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   const struct clip_stage *clipper = clip_stage(stage);
10182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   uint i;
10282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   for (i = 0; i < clipper->num_color_attribs; i++) {
10382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      const uint attr = clipper->color_attribs[i];
10482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      COPY_4FV(dst->data[attr], src->data[attr]);
10582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
10682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
1078e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1098e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Interpolate between two vertices to produce a third.
1118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
112bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paulstatic void interp( const struct clip_stage *clip,
1138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		    struct vertex_header *dst,
1143fc926f3740da9ec27853d158243055f3cb43d43Brian		    float t,
1158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		    const struct vertex_header *out,
1168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		    const struct vertex_header *in )
1178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
11889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
11989d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
1203fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned j;
1218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Vertex header.
1238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
1248e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   {
1258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      dst->clipmask = 0;
126f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell      dst->edgeflag = 0;        /* will get overwritten later */
1278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      dst->pad = 0;
128c28fdf309607ec2994ef9a1109931a8389854300José Fonseca      dst->vertex_id = UNDEFINED_VERTEX_ID;
1298e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
1308e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1318e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Clip coordinates:  interpolate normally
1328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
1338e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   {
1348e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      interp_attr(dst->clip, t, in->clip, out->clip);
1358e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
1368e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1378e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Do the projective divide and insert window coordinates:
1388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
1398e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   {
1403fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *pos = dst->clip;
1413fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *scale = clip->stage.draw->viewport.scale;
1423fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *trans = clip->stage.draw->viewport.translate;
143eb51761b825018bf89080855d0fa3fcb84b9c215michal      const float oow = 1.0f / pos[3];
1448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1452161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
1462161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1];
1472161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2];
1482161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      dst->data[pos_attr][3] = oow;
1498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
1508e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1518e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Other attributes
1528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
1532161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   for (j = 0; j < nr_attrs; j++) {
1542161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell      if (j != pos_attr)
1552161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell         interp_attr(dst->data[j], t, in->data[j], out->data[j]);
1568e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
1578e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
1588e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
1598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
16074fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul/**
16174fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul * Emit a post-clip polygon to the next pipeline stage.  The polygon
16274fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul * will be convex and the provoking vertex will always be vertex[0].
16374fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul */
164ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstatic void emit_poly( struct draw_stage *stage,
1658e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		       struct vertex_header **inlist,
166aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian		       unsigned n,
16782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell		       const struct prim_header *origPrim)
1688e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
1698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct prim_header header;
1703fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned i;
171cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   ushort edge_first, edge_middle, edge_last;
1728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
173cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   if (stage->draw->rasterizer->flatshade_first) {
174cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_first  = DRAW_PIPE_EDGE_FLAG_0;
175cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_middle = DRAW_PIPE_EDGE_FLAG_1;
176cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_last   = DRAW_PIPE_EDGE_FLAG_2;
177cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   }
178cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   else {
179cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_first  = DRAW_PIPE_EDGE_FLAG_2;
180cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_middle = DRAW_PIPE_EDGE_FLAG_0;
181cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      edge_last   = DRAW_PIPE_EDGE_FLAG_1;
182cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   }
183f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
184aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian   /* later stages may need the determinant, but only the sign matters */
185aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian   header.det = origPrim->det;
186f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell   header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
187f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell   header.pad = 0;
188aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian
18914a13e3767f080a48a4ae01f803dd0bc8754f441Keith Whitwell   for (i = 2; i < n; i++, header.flags = edge_middle) {
19074fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul      /* order the triangle verts to respect the provoking vertex mode */
191ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      if (stage->draw->rasterizer->flatshade_first) {
19274fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul         header.v[0] = inlist[0];  /* the provoking vertex */
193ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[1] = inlist[i-1];
194ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[2] = inlist[i];
195ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
196ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      else {
197ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[0] = inlist[i-1];
198ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca         header.v[1] = inlist[i];
19974fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul         header.v[2] = inlist[0];  /* the provoking vertex */
200ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
201f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
202f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell      if (i == n-1)
203c87361340352850ba793a481c969081b6ecfc0c6Brian Paul         header.flags |= edge_last;
204f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
205f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell      if (0) {
2062f0d1396e4c1626b3b1ac799bd29e86a9530369eKeith Whitwell         const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
207f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell         uint j, k;
20874fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul         debug_printf("Clipped tri: (flat-shade-first = %d)\n",
20974fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul                      stage->draw->rasterizer->flatshade_first);
210f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell         for (j = 0; j < 3; j++) {
211f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell            for (k = 0; k < vs->info.num_outputs; k++) {
212f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell               debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
213f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][0],
214f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][1],
215f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][2],
216f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell                            header.v[j]->data[k][3]);
2175ffc5cce1507fd407399911abefeea988a69394eBrian Paul            }
2185ffc5cce1507fd407399911abefeea988a69394eBrian Paul         }
2198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
220f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell
221f93332da5655a31b6c44a1079629a15360ff999bKeith Whitwell      stage->next->tri( stage->next, &header );
2228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
2238e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
2248e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
225c87361340352850ba793a481c969081b6ecfc0c6Brian Paul
226507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwellstatic INLINE float
227507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwelldot4(const float *a, const float *b)
228507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell{
229c87361340352850ba793a481c969081b6ecfc0c6Brian Paul   return (a[0] * b[0] +
230c87361340352850ba793a481c969081b6ecfc0c6Brian Paul           a[1] * b[1] +
231c87361340352850ba793a481c969081b6ecfc0c6Brian Paul           a[2] * b[2] +
232c87361340352850ba793a481c969081b6ecfc0c6Brian Paul           a[3] * b[3]);
233507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell}
2348e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2358e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2368e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Clip a triangle against the viewport and user clip planes.
2378e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
2388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
239ea470eec86715cd2bc9aa86d36e6ea803d0d4017Briando_clip_tri( struct draw_stage *stage,
2408e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	     struct prim_header *header,
2413fc926f3740da9ec27853d158243055f3cb43d43Brian	     unsigned clipmask )
2428e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
243bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   struct clip_stage *clipper = clip_stage( stage );
2448e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *a[MAX_CLIPPED_VERTICES];
2458e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *b[MAX_CLIPPED_VERTICES];
2468e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header **inlist = a;
2478e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header **outlist = b;
2483fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned tmpnr = 0;
2493fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned n = 3;
2503fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned i;
2518e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   inlist[0] = header->v[0];
2538e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   inlist[1] = header->v[1];
2548e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   inlist[2] = header->v[2];
2558e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2568e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   while (clipmask && n >= 3) {
257f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      const unsigned plane_idx = ffs(clipmask)-1;
2583fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *plane = clipper->plane[plane_idx];
2598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      struct vertex_header *vert_prev = inlist[0];
2603fc926f3740da9ec27853d158243055f3cb43d43Brian      float dp_prev = dot4( vert_prev->clip, plane );
2613fc926f3740da9ec27853d158243055f3cb43d43Brian      unsigned outcount = 0;
2628e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2638e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      clipmask &= ~(1<<plane_idx);
2648e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
265ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul      assert(n < MAX_CLIPPED_VERTICES);
2668e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      inlist[n] = inlist[0]; /* prevent rotation of vertices */
2678e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2688e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      for (i = 1; i <= n; i++) {
2698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 struct vertex_header *vert = inlist[i];
2708e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2713fc926f3740da9ec27853d158243055f3cb43d43Brian	 float dp = dot4( vert->clip, plane );
2728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 if (!IS_NEGATIVE(dp_prev)) {
274ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(outcount < MAX_CLIPPED_VERTICES);
2758e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    outlist[outcount++] = vert_prev;
2768e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 }
2778e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2788e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 if (DIFFERENT_SIGNS(dp, dp_prev)) {
279ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul	    struct vertex_header *new_vert;
280ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul
281ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(tmpnr < MAX_CLIPPED_VERTICES+1);
282ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            new_vert = clipper->stage.tmp[tmpnr++];
283ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul
284ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(outcount < MAX_CLIPPED_VERTICES);
2858e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    outlist[outcount++] = new_vert;
2868e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2878e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    if (IS_NEGATIVE(dp)) {
2888e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Going out of bounds.  Avoid division by zero as we
2898e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		* know dp != dp_prev from DIFFERENT_SIGNS, above.
2908e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
2913fc926f3740da9ec27853d158243055f3cb43d43Brian	       float t = dp / (dp - dp_prev);
2928e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       interp( clipper, new_vert, t, vert, vert_prev );
2938e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
2948e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Force edgeflag true in this case:
2958e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
2968e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       new_vert->edgeflag = 1;
2978e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    } else {
2988e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Coming back in.
2998e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
3003fc926f3740da9ec27853d158243055f3cb43d43Brian	       float t = dp_prev / (dp_prev - dp);
3018e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       interp( clipper, new_vert, t, vert_prev, vert );
3028e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3038e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       /* Copy starting vert's edgeflag:
3048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell		*/
3058e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	       new_vert->edgeflag = vert_prev->edgeflag;
3068e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    }
3078e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 }
3088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3098e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 vert_prev = vert;
3108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 dp_prev = dp;
3118e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
3128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
313c87361340352850ba793a481c969081b6ecfc0c6Brian Paul      /* swap in/out lists */
3148e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      {
3158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 struct vertex_header **tmp = inlist;
3168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 inlist = outlist;
3178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 outlist = tmp;
3188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 n = outcount;
3198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
3208e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
3218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
32274fb08018ac740e8189cee5f9aa8e429d50496e4Brian Paul   /* If flat-shading, copy provoking vertex color to polygon vertex[0]
32382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell    */
324cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   if (clipper->flat) {
325cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (stage->draw->rasterizer->flatshade_first) {
326cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         if (inlist[0] != header->v[0]) {
327ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
328cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
329cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            copy_colors(stage, inlist[0], header->v[0]);
330cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
331ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
332cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
333cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         if (inlist[0] != header->v[2]) {
334ca3238f3fce89b4641833d1722d03c5d23b3e081Brian Paul            assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
335cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
336cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            copy_colors(stage, inlist[0], header->v[2]);
337cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
338ddb0e18f6c5582d4d2cc59ffd16ad9c4639ed059José Fonseca      }
33982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
34082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
3418e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   /* Emit the polygon as triangles to the setup stage:
3428e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell    */
3438e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (n >= 3)
344aaf03b94861cbf5a602863e4542dd1c2e54ba365Brian      emit_poly( stage, inlist, n, header );
3458e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
3468e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3478e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3488e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Clip a line against the viewport and user clip planes.
3498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */
3508e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
351ea470eec86715cd2bc9aa86d36e6ea803d0d4017Briando_clip_line( struct draw_stage *stage,
3528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	      struct prim_header *header,
3533fc926f3740da9ec27853d158243055f3cb43d43Brian	      unsigned clipmask )
3548e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
355bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   const struct clip_stage *clipper = clip_stage( stage );
3568e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *v0 = header->v[0];
3578e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   struct vertex_header *v1 = header->v[1];
3583fc926f3740da9ec27853d158243055f3cb43d43Brian   const float *pos0 = v0->clip;
3593fc926f3740da9ec27853d158243055f3cb43d43Brian   const float *pos1 = v1->clip;
360f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian   float t0 = 0.0F;
361f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian   float t1 = 0.0F;
362a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   struct prim_header newprim;
3638e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3648e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   while (clipmask) {
3653fc926f3740da9ec27853d158243055f3cb43d43Brian      const unsigned plane_idx = ffs(clipmask)-1;
3663fc926f3740da9ec27853d158243055f3cb43d43Brian      const float *plane = clipper->plane[plane_idx];
3673fc926f3740da9ec27853d158243055f3cb43d43Brian      const float dp0 = dot4( pos0, plane );
3683fc926f3740da9ec27853d158243055f3cb43d43Brian      const float dp1 = dot4( pos1, plane );
3698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
370f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      if (dp1 < 0.0F) {
3713fc926f3740da9ec27853d158243055f3cb43d43Brian	 float t = dp1 / (dp1 - dp0);
3725b06424a1507dadad8832d557e79f68a3b68b9c2Brian         t1 = MAX2(t1, t);
3738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
3748e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
375f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      if (dp0 < 0.0F) {
3763fc926f3740da9ec27853d158243055f3cb43d43Brian	 float t = dp0 / (dp0 - dp1);
3775b06424a1507dadad8832d557e79f68a3b68b9c2Brian         t0 = MAX2(t0, t);
3788e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      }
3798e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
380f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian      if (t0 + t1 >= 1.0F)
3818e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	 return; /* discard */
382a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian
383a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
3848e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
3858e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3868e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (v0->clipmask) {
3878e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      interp( clipper, stage->tmp[0], t0, v0, v1 );
38882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
38982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      if (clipper->flat)
39082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell	 copy_colors(stage, stage->tmp[0], v0);
39182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
392a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[0] = stage->tmp[0];
393a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   }
394a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   else {
395a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[0] = v0;
3968e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
3978e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
3988e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (v1->clipmask) {
3998e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      interp( clipper, stage->tmp[1], t1, v1, v0 );
400a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[1] = stage->tmp[1];
401a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   }
402a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   else {
403a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian      newprim.v[1] = v1;
4048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
4058e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
406a49a23efc5e320d8c9aa6f4f39be855632aa5cb8Brian   stage->next->line( stage->next, &newprim );
4078e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
4088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4098e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
411ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianclip_point( struct draw_stage *stage,
4128e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	    struct prim_header *header )
4138e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
414cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin   if (header->v[0]->clipmask == 0)
4158e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      stage->next->point( stage->next, header );
4168e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
4178e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4188e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4198e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
420ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianclip_line( struct draw_stage *stage,
4218e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	   struct prim_header *header )
4228e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
4233fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned clipmask = (header->v[0]->clipmask |
424f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian                        header->v[1]->clipmask);
4258e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4268e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (clipmask == 0) {
427279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian      /* no clipping needed */
4288e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      stage->next->line( stage->next, header );
4298e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
430cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin   else if ((header->v[0]->clipmask &
431cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin             header->v[1]->clipmask) == 0) {
4328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      do_clip_line(stage, header, clipmask);
4338e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
434f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian   /* else, totally clipped */
4358e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
4368e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4378e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4388e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstatic void
439ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianclip_tri( struct draw_stage *stage,
4408e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell	  struct prim_header *header )
4418e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
4423fc926f3740da9ec27853d158243055f3cb43d43Brian   unsigned clipmask = (header->v[0]->clipmask |
443f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian                        header->v[1]->clipmask |
444f9a77a3080598d03c484fa5d04c213b8a06d43d3Brian                        header->v[2]->clipmask);
4458e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
4468e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   if (clipmask == 0) {
447279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian      /* no clipping needed */
4488e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      stage->next->tri( stage->next, header );
4498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
450cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin   else if ((header->v[0]->clipmask &
451cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin             header->v[1]->clipmask &
452cdd38d487a311e6c71b76382d428f5dc26caf067Zack Rusin             header->v[2]->clipmask) == 0) {
4538e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell      do_clip_tri(stage, header, clipmask);
4548e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   }
4558e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
4568e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
457c87361340352850ba793a481c969081b6ecfc0c6Brian Paul
45882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell/* Update state.  Could further delay this until we hit the first
45982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell * primitive that really requires clipping.
46082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell */
46182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void
46282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellclip_init_state( struct draw_stage *stage )
46382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
464bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   struct clip_stage *clipper = clip_stage( stage );
46582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
46617ef840af40c9228ee0f4f7453bc00e318d9e6c4Michal Krol   clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE;
46782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
46882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   if (clipper->flat) {
4692f0d1396e4c1626b3b1ac799bd29e86a9530369eKeith Whitwell      const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
47082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      uint i;
47182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
47282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      clipper->num_color_attribs = 0;
473cddeca51adf0d2b736a223e47b60f6ef3be85bffBrian      for (i = 0; i < vs->info.num_outputs; i++) {
474cddeca51adf0d2b736a223e47b60f6ef3be85bffBrian	 if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
475cddeca51adf0d2b736a223e47b60f6ef3be85bffBrian	     vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
47682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell	    clipper->color_attribs[clipper->num_color_attribs++] = i;
47782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell	 }
47882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      }
47982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
48082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
48182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->tri = clip_tri;
48282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->line = clip_line;
48382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
48482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
48582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
48682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
48782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void clip_first_tri( struct draw_stage *stage,
48882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			    struct prim_header *header )
48982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
49082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clip_init_state( stage );
49182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->tri( stage, header );
49282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
49382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
49482d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void clip_first_line( struct draw_stage *stage,
49582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			     struct prim_header *header )
49682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell{
49782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clip_init_state( stage );
49882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->line( stage, header );
49982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell}
50082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
50182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
50282d9063708539d53c7670b2ab732bed24230b94dKeith Whitwellstatic void clip_flush( struct draw_stage *stage,
50382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell			     unsigned flags )
5048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
50582d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->tri = clip_first_tri;
50682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   stage->line = clip_first_line;
5070bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->next->flush( stage->next, flags );
5088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
5098e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5108e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
5110360b49afbcd839f99ba0745d01cf9dc5be4d122Brianstatic void clip_reset_stipple_counter( struct draw_stage *stage )
5120360b49afbcd839f99ba0745d01cf9dc5be4d122Brian{
5130360b49afbcd839f99ba0745d01cf9dc5be4d122Brian   stage->next->reset_stipple_counter( stage->next );
5140360b49afbcd839f99ba0745d01cf9dc5be4d122Brian}
5150360b49afbcd839f99ba0745d01cf9dc5be4d122Brian
5160360b49afbcd839f99ba0745d01cf9dc5be4d122Brian
517d75454840672f462de933724daae24a839aac48eMichalstatic void clip_destroy( struct draw_stage *stage )
518d75454840672f462de933724daae24a839aac48eMichal{
519b08102a8f3ef558743f5f952c726ba2c28b6e82eBrian   draw_free_temp_verts( stage );
520d75454840672f462de933724daae24a839aac48eMichal   FREE( stage );
521d75454840672f462de933724daae24a839aac48eMichal}
522d75454840672f462de933724daae24a839aac48eMichal
523d75454840672f462de933724daae24a839aac48eMichal
524279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian/**
525279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian * Allocate a new clipper stage.
526279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian * \return pointer to new stage object
527279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian */
528ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstruct draw_stage *draw_clip_stage( struct draw_context *draw )
5298e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{
530bc1b38af71c312d4d109090c51c3fd507b115d81Brian Paul   struct clip_stage *clipper = CALLOC_STRUCT(clip_stage);
5310d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (clipper == NULL)
5320d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      goto fail;
5338e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
534279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian   clipper->stage.draw = draw;
535eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   clipper->stage.name = "clipper";
5368e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   clipper->stage.point = clip_point;
53782d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clipper->stage.line = clip_first_line;
53882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   clipper->stage.tri = clip_first_tri;
5390bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   clipper->stage.flush = clip_flush;
5400360b49afbcd839f99ba0745d01cf9dc5be4d122Brian   clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
541d75454840672f462de933724daae24a839aac48eMichal   clipper->stage.destroy = clip_destroy;
5428e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell
543279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian   clipper->plane = draw->plane;
544279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian
5451c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane   if (!draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ))
5461c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane      goto fail;
5471c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane
5488e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell   return &clipper->stage;
5490d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell
5500d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell fail:
5510d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (clipper)
5520d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      clipper->stage.destroy( &clipper->stage );
5530d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell
5540d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   return NULL;
5558e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}
556