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 28720c0eb71db9908c5ecef15263c2ae638d61d07bBrian/** 29720c0eb71db9908c5ecef15263c2ae638d61d07bBrian * \brief Drawing stage for polygon culling 30720c0eb71db9908c5ecef15263c2ae638d61d07bBrian */ 31720c0eb71db9908c5ecef15263c2ae638d61d07bBrian 328e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell/* Authors: Keith Whitwell <keith@tungstengraphics.com> 338e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell */ 348e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 35720c0eb71db9908c5ecef15263c2ae638d61d07bBrian 364f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 37f79c225d9e5adee6287a9bba35f014c3fe00d3f9Brian#include "pipe/p_defines.h" 38507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h" 398e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 408e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 418e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwellstruct cull_stage { 42ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brian struct draw_stage stage; 430bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell unsigned cull_face; /**< which face(s) to cull (one of PIPE_FACE_x) */ 440bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell unsigned front_ccw; 458e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell}; 468e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 478e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 48ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstatic INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) 498e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{ 508e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell return (struct cull_stage *)stage; 518e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell} 528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 538e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 54ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstatic void cull_tri( struct draw_stage *stage, 558e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell struct prim_header *header ) 568e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{ 5789d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin const unsigned pos = draw_current_shader_position_output(stage->draw); 582161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell 598e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell /* Window coords: */ 602161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell const float *v0 = header->v[0]->data[pos]; 612161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell const float *v1 = header->v[1]->data[pos]; 622161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell const float *v2 = header->v[2]->data[pos]; 638e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 645023a7f53f4b11cdea1ed90d7e856b6eda6dd68eBrian Paul /* edge vectors: e = v0 - v2, f = v1 - v2 */ 653fc926f3740da9ec27853d158243055f3cb43d43Brian const float ex = v0[0] - v2[0]; 663fc926f3740da9ec27853d158243055f3cb43d43Brian const float ey = v0[1] - v2[1]; 673fc926f3740da9ec27853d158243055f3cb43d43Brian const float fx = v1[0] - v2[0]; 683fc926f3740da9ec27853d158243055f3cb43d43Brian const float fy = v1[1] - v2[1]; 698e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 706aa9c8ebc19ffa4425669862caeb99b22c079090Brian /* det = cross(e,f).z */ 718e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell header->det = ex * fy - ey * fx; 728e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 738e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell if (header->det != 0) { 745023a7f53f4b11cdea1ed90d7e856b6eda6dd68eBrian Paul /* if det < 0 then Z points toward the camera and the triangle is 75dc313b578386dc07f4916fba98da061af3ab18e5Brian * counter-clockwise winding. 76dc313b578386dc07f4916fba98da061af3ab18e5Brian */ 770bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell unsigned ccw = (header->det < 0); 780bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell unsigned face = ((ccw == cull_stage(stage)->front_ccw) ? 790bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell PIPE_FACE_FRONT : 800bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell PIPE_FACE_BACK); 81f79c225d9e5adee6287a9bba35f014c3fe00d3f9Brian 820bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell if ((face & cull_stage(stage)->cull_face) == 0) { 83279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian /* triangle is not culled, pass to next stage */ 848e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell stage->next->tri( stage->next, header ); 85279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian } 868e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell } 878e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell} 888e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 895023a7f53f4b11cdea1ed90d7e856b6eda6dd68eBrian Paul 900bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void cull_first_tri( struct draw_stage *stage, 910bfd085e2866fbbd40209dcee23f0e6240583fe8Brian struct prim_header *header ) 920bfd085e2866fbbd40209dcee23f0e6240583fe8Brian{ 930bfd085e2866fbbd40209dcee23f0e6240583fe8Brian struct cull_stage *cull = cull_stage(stage); 940bfd085e2866fbbd40209dcee23f0e6240583fe8Brian 950bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell cull->cull_face = stage->draw->rasterizer->cull_face; 960bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell cull->front_ccw = stage->draw->rasterizer->front_ccw; 970bfd085e2866fbbd40209dcee23f0e6240583fe8Brian 980bfd085e2866fbbd40209dcee23f0e6240583fe8Brian stage->tri = cull_tri; 990bfd085e2866fbbd40209dcee23f0e6240583fe8Brian stage->tri( stage, header ); 1000bfd085e2866fbbd40209dcee23f0e6240583fe8Brian} 1010bfd085e2866fbbd40209dcee23f0e6240583fe8Brian 1020bfd085e2866fbbd40209dcee23f0e6240583fe8Brian 1030bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void cull_flush( struct draw_stage *stage, unsigned flags ) 1048e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{ 1050bfd085e2866fbbd40209dcee23f0e6240583fe8Brian stage->tri = cull_first_tri; 1060bfd085e2866fbbd40209dcee23f0e6240583fe8Brian stage->next->flush( stage->next, flags ); 1078e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell} 1088e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 1095023a7f53f4b11cdea1ed90d7e856b6eda6dd68eBrian Paul 1100360b49afbcd839f99ba0745d01cf9dc5be4d122Brianstatic void cull_reset_stipple_counter( struct draw_stage *stage ) 1110360b49afbcd839f99ba0745d01cf9dc5be4d122Brian{ 1120360b49afbcd839f99ba0745d01cf9dc5be4d122Brian stage->next->reset_stipple_counter( stage->next ); 1130360b49afbcd839f99ba0745d01cf9dc5be4d122Brian} 1140360b49afbcd839f99ba0745d01cf9dc5be4d122Brian 115d75454840672f462de933724daae24a839aac48eMichal 116d75454840672f462de933724daae24a839aac48eMichalstatic void cull_destroy( struct draw_stage *stage ) 117d75454840672f462de933724daae24a839aac48eMichal{ 118b08102a8f3ef558743f5f952c726ba2c28b6e82eBrian draw_free_temp_verts( stage ); 119d75454840672f462de933724daae24a839aac48eMichal FREE( stage ); 120d75454840672f462de933724daae24a839aac48eMichal} 121d75454840672f462de933724daae24a839aac48eMichal 122d75454840672f462de933724daae24a839aac48eMichal 123279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian/** 124279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian * Create a new polygon culling stage. 125279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian */ 126ea470eec86715cd2bc9aa86d36e6ea803d0d4017Brianstruct draw_stage *draw_cull_stage( struct draw_context *draw ) 1278e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell{ 1288e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell struct cull_stage *cull = CALLOC_STRUCT(cull_stage); 1290d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell if (cull == NULL) 1300d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell goto fail; 1318e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 132279ffe3f163fd6a5e7bfa108db14c81acbb06eceBrian cull->stage.draw = draw; 133eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell cull->stage.name = "cull"; 1348e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell cull->stage.next = NULL; 135a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell cull->stage.point = draw_pipe_passthrough_point; 136a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell cull->stage.line = draw_pipe_passthrough_line; 1370bfd085e2866fbbd40209dcee23f0e6240583fe8Brian cull->stage.tri = cull_first_tri; 1380bfd085e2866fbbd40209dcee23f0e6240583fe8Brian cull->stage.flush = cull_flush; 1390360b49afbcd839f99ba0745d01cf9dc5be4d122Brian cull->stage.reset_stipple_counter = cull_reset_stipple_counter; 140d75454840672f462de933724daae24a839aac48eMichal cull->stage.destroy = cull_destroy; 1418e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell 1421c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane if (!draw_alloc_temp_verts( &cull->stage, 0 )) 1431c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane goto fail; 1441c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane 1458e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell return &cull->stage; 1460d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell 1475023a7f53f4b11cdea1ed90d7e856b6eda6dd68eBrian Paulfail: 1480d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell if (cull) 1490d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell cull->stage.destroy( &cull->stage ); 1500d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell 1510d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell return NULL; 1528e4a95a93d15a6707a29454cd47e10b08314cda2Keith Whitwell} 153