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