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