108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/**************************************************************************
208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2007 VMware, Inc.
408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * All Rights Reserved.
508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell *
608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * copy of this software and associated documentation files (the
808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * "Software"), to deal in the Software without restriction, including
908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
1008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
1108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
1208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * the following conditions:
1308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell *
1408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * The above copyright notice and this permission notice (including the
1508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
1608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * of the Software.
1708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell *
1808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
2208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell *
2608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell **************************************************************************/
2708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
28877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca/* Authors:  Keith Whitwell <keithw@vmware.com>
2908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell */
3008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
314f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
324586e6c8cb5b391536a370faa0c419c3fd541693José Fonseca#include "util/u_math.h"
334e7f1346aefe9d27b67b9f279ce7f1e772b390dfBrian Paul#include "util/u_prim.h"
3408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell#include "pipe/p_defines.h"
3508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell#include "draw_private.h"
36507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h"
370588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell#include "draw_context.h"
38f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell#include "draw_vbuf.h"
3908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
4008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
413faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul/**
42f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * Default version of a function to check if we need any special
43f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * pipeline stages, or whether prims/verts can go through untouched.
44f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * Don't test for bypass clipping or vs modes, this function is just
45f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * about the primitive pipeline stages.
46f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell *
47f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * This can be overridden by the driver.
483faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul */
493faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paulboolean
500588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwelldraw_need_pipeline(const struct draw_context *draw,
510588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell                   const struct pipe_rasterizer_state *rasterizer,
524505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell                   unsigned int prim )
533faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul{
544e7f1346aefe9d27b67b9f279ce7f1e772b390dfBrian Paul   unsigned reduced_prim = u_reduced_prim(prim);
554e7f1346aefe9d27b67b9f279ce7f1e772b390dfBrian Paul
56f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   /* If the driver has overridden this, use that version:
57f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell    */
58f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   if (draw->render &&
59f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell       draw->render->need_pipeline)
60f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   {
61f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell      return draw->render->need_pipeline( draw->render,
62f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell                                          rasterizer,
63f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell                                          prim );
64f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   }
65f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell
664505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   /* Don't have to worry about triangles turning into lines/points
674505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell    * and triggering the pipeline, because we have to trigger the
684505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell    * pipeline *anyway* if unfilled mode is active.
694505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell    */
704e7f1346aefe9d27b67b9f279ce7f1e772b390dfBrian Paul   if (reduced_prim == PIPE_PRIM_LINES) {
714505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* line stipple */
720588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->line_stipple_enable && draw->pipeline.line_stipple)
734505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
744505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
754505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* wide lines */
764586e6c8cb5b391536a370faa0c419c3fd541693José Fonseca      if (roundf(rasterizer->line_width) > draw->pipeline.wide_line_threshold)
774505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
784505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
794505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* AA lines */
800588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->line_smooth && draw->pipeline.aaline)
814505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
82babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin
83babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin      if (draw_current_shader_num_written_culldistances(draw))
84babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin         return TRUE;
854505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   }
864e7f1346aefe9d27b67b9f279ce7f1e772b390dfBrian Paul   else if (reduced_prim == PIPE_PRIM_POINTS) {
874505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* large points */
880588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->point_size > draw->pipeline.wide_point_threshold)
894505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
904505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
918cb223eb020560d59c8f73e09b832cef477933b7Brian Paul      /* sprite points */
928cb223eb020560d59c8f73e09b832cef477933b7Brian Paul      if (rasterizer->point_quad_rasterization
938cb223eb020560d59c8f73e09b832cef477933b7Brian Paul          && draw->pipeline.wide_point_sprites)
948cb223eb020560d59c8f73e09b832cef477933b7Brian Paul         return TRUE;
958cb223eb020560d59c8f73e09b832cef477933b7Brian Paul
964505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* AA points */
970588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->point_smooth && draw->pipeline.aapoint)
984505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
994505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1004505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* point sprites */
1014a4daa75a85db22cd37ebd533ebbccb427e07077Roland Scheidegger      if (rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)
1024505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1034505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   }
1044e7f1346aefe9d27b67b9f279ce7f1e772b390dfBrian Paul   else if (reduced_prim == PIPE_PRIM_TRIANGLES) {
1054505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* polygon stipple */
1060588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
1074505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1084505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1094505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* unfilled polygons */
1100bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      if (rasterizer->fill_front != PIPE_POLYGON_MODE_FILL ||
1117813d12e05e654d12e2cf6c47a7e73eb0310493cKeith Whitwell          rasterizer->fill_back != PIPE_POLYGON_MODE_FILL)
1124505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1134505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1144505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* polygon offset */
1150bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      if (rasterizer->offset_point ||
1160bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell          rasterizer->offset_line ||
1170bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell          rasterizer->offset_tri)
1184505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1194505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1204505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* two-side lighting */
1210588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->light_twoside)
1224505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
123babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin
124babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin      if (draw_current_shader_num_written_culldistances(draw))
125babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin         return TRUE;
1264505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   }
1273faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul
1283e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell   /* polygon cull - this is difficult - hardware can cull just fine
1293e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    * most of the time (though sometimes CULL_NEITHER is unsupported.
1303e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    *
1313e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    * Generally this isn't a reason to require the pipeline, though.
1323e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    *
1330588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell   if (rasterizer->cull_mode)
1343faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul      return TRUE;
135babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin   */
1363faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul
1373faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul   return FALSE;
1383faf6230ff4b63833c072ac7afeb43c25d3cba22Brian Paul}
13908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
14008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
14108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
14208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/**
14308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * Rebuild the rendering pipeline.
14408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell */
1450bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulstatic struct draw_stage *validate_pipeline( struct draw_stage *stage )
14608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell{
14708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   struct draw_context *draw = stage->draw;
14808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   struct draw_stage *next = draw->pipeline.rasterize;
1493c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul   boolean need_det = FALSE;
1503c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul   boolean precalc_flat = FALSE;
151e9276efafe43219d7af548ce7f5d2440e19836b0Brian Paul   boolean wide_lines, wide_points;
152d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   const struct pipe_rasterizer_state *rast = draw->rasterizer;
1531603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul
1541603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul   /* Set the validate's next stage to the rasterize stage, so that it
1551603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    * can be found later if needed for flushing.
1561603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    */
1571603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul   stage->next = next;
15808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
1595e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul   /* drawing wide lines? */
1604586e6c8cb5b391536a370faa0c419c3fd541693José Fonseca   wide_lines = (roundf(rast->line_width) > draw->pipeline.wide_line_threshold
161d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul                 && !rast->line_smooth);
1625e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul
163a7ea4d11fb5a2a39daaad8752706291ac93013f7Brian Paul   /* drawing large/sprite points (but not AA points)? */
164d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->sprite_coord_enable && draw->pipeline.point_sprite)
1655a09ad8248ce452136ed96a3d46532b03c877618Brian Paul      wide_points = TRUE;
166d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   else if (rast->point_smooth && draw->pipeline.aapoint)
1675e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul      wide_points = FALSE;
168d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   else if (rast->point_size > draw->pipeline.wide_point_threshold)
1695e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul      wide_points = TRUE;
1708cb223eb020560d59c8f73e09b832cef477933b7Brian Paul   else if (rast->point_quad_rasterization && draw->pipeline.wide_point_sprites)
1718cb223eb020560d59c8f73e09b832cef477933b7Brian Paul      wide_points = TRUE;
1725e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul   else
1735e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul      wide_points = FALSE;
1745e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian Paul
17508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   /*
17608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    * NOTE: we build up the pipeline in end-to-start order.
17708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    *
17808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    * TODO: make the current primitive part of the state and build
17908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    * shorter pipelines for lines & points.
18008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    */
18108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
182d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->line_smooth && draw->pipeline.aaline) {
183aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian Paul      draw->pipeline.aaline->next = next;
184aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian Paul      next = draw->pipeline.aaline;
185d2c7fe5389e40871a7e339dc0ecaa7f570f851edBrian Paul      precalc_flat = TRUE;
186aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian Paul   }
187aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian Paul
188d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->point_smooth && draw->pipeline.aapoint) {
189eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian Paul      draw->pipeline.aapoint->next = next;
190eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian Paul      next = draw->pipeline.aapoint;
191eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian Paul   }
192eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian Paul
193a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul   if (wide_lines) {
194a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      draw->pipeline.wide_line->next = next;
195a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      next = draw->pipeline.wide_line;
1963c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      precalc_flat = TRUE;
197a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul   }
198a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul
199a7ea4d11fb5a2a39daaad8752706291ac93013f7Brian Paul   if (wide_points) {
200a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      draw->pipeline.wide_point->next = next;
201a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      next = draw->pipeline.wide_point;
202e3444deec5a369e4ffabfeb9f6c257dd6b8e5a30Brian Paul   }
203e3444deec5a369e4ffabfeb9f6c257dd6b8e5a30Brian Paul
204d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->line_stipple_enable && draw->pipeline.line_stipple) {
205329a8479b69a800b5fc6485767fb676c3eae26dbBrian Paul      draw->pipeline.stipple->next = next;
206329a8479b69a800b5fc6485767fb676c3eae26dbBrian Paul      next = draw->pipeline.stipple;
2073c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      precalc_flat = TRUE;		/* only needed for lines really */
208329a8479b69a800b5fc6485767fb676c3eae26dbBrian Paul   }
209329a8479b69a800b5fc6485767fb676c3eae26dbBrian Paul
210d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->poly_stipple_enable
211446bfc32a83008e0865ec869bc80b920c907f10fBrian Paul       && draw->pipeline.pstipple) {
212446bfc32a83008e0865ec869bc80b920c907f10fBrian Paul      draw->pipeline.pstipple->next = next;
213446bfc32a83008e0865ec869bc80b920c907f10fBrian Paul      next = draw->pipeline.pstipple;
214446bfc32a83008e0865ec869bc80b920c907f10fBrian Paul   }
215446bfc32a83008e0865ec869bc80b920c907f10fBrian Paul
2160bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
2170bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell       rast->fill_back != PIPE_POLYGON_MODE_FILL) {
21808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.unfilled->next = next;
21908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.unfilled;
2203c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      precalc_flat = TRUE;		/* only needed for triangles really */
2213c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      need_det = TRUE;
22208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
22382d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
2242b23149206c933aed473d289d79dd2f398f88389Roland Scheidegger   if (precalc_flat) {
2252b23149206c933aed473d289d79dd2f398f88389Roland Scheidegger      /*
2262b23149206c933aed473d289d79dd2f398f88389Roland Scheidegger       * could only run the stage if either rast->flatshade is true
2272b23149206c933aed473d289d79dd2f398f88389Roland Scheidegger       * or there's constant interpolated values.
2282b23149206c933aed473d289d79dd2f398f88389Roland Scheidegger       */
22982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      draw->pipeline.flatshade->next = next;
23082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      next = draw->pipeline.flatshade;
23182d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
23208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
2330bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (rast->offset_point ||
2340bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell       rast->offset_line ||
2350bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell       rast->offset_tri) {
23608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.offset->next = next;
23708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.offset;
2383c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      need_det = TRUE;
23908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
24008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
241d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->light_twoside) {
24208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.twoside->next = next;
24308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.twoside;
2443c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      need_det = TRUE;
24508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
24608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
24708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   /* Always run the cull stage as we calculate determinant there
2481603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    * also.
2491603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    *
2501603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    * This can actually be a win as culling out the triangles can lead
2511603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    * to less work emitting vertices, smaller vertex buffers, etc.
2521603a33fb276d7e78a2e872dfa05aa0093d1329aBrian Paul    * It's difficult to say whether this will be true in general.
25308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    */
254babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin   if (need_det || rast->cull_face != PIPE_FACE_NONE ||
255babe35a067d1610d9032cc28eec8e16b18685621Zack Rusin       draw_current_shader_num_written_culldistances(draw)) {
25608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.cull->next = next;
25708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.cull;
25808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
25908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
26008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   /* Clip stage
26108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    */
2626c0dc4bafbdbdc0cb4b6e5934fe064226dbd47ecKeith Whitwell   if (draw->clip_xy || draw->clip_z || draw->clip_user)
26308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   {
26408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.clip->next = next;
26508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.clip;
26608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
26708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
26808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   draw->pipeline.first = next;
269eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell
270eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   if (0) {
271eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell      debug_printf("draw pipeline:\n");
272eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell      for (next = draw->pipeline.first; next ; next = next->next )
273eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell         debug_printf("   %s\n", next->name);
274eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell      debug_printf("\n");
275eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   }
276eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell
277eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   return draw->pipeline.first;
2780bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul}
2790bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul
2800bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulstatic void validate_tri( struct draw_stage *stage,
2810bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul			  struct prim_header *header )
2820bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul{
2830bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   struct draw_stage *pipeline = validate_pipeline( stage );
2840bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   pipeline->tri( pipeline, header );
2850bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul}
2860bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul
2870bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulstatic void validate_line( struct draw_stage *stage,
2880bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul			   struct prim_header *header )
2890bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul{
2900bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   struct draw_stage *pipeline = validate_pipeline( stage );
2910bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   pipeline->line( pipeline, header );
2920bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul}
2930bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul
2940bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulstatic void validate_point( struct draw_stage *stage,
2950bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul			    struct prim_header *header )
2960bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul{
2970bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   struct draw_stage *pipeline = validate_pipeline( stage );
2980bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   pipeline->point( pipeline, header );
2990bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul}
3000bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul
3010bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulstatic void validate_reset_stipple_counter( struct draw_stage *stage )
3020bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul{
3030bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   struct draw_stage *pipeline = validate_pipeline( stage );
3040bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   pipeline->reset_stipple_counter( pipeline );
3050bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul}
3060bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul
3070bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paulstatic void validate_flush( struct draw_stage *stage,
3080bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul			    unsigned flags )
3090bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul{
3100bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   /* May need to pass a backend flush on to the rasterize stage.
3110bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul    */
3120bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   if (stage->next)
3130bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul      stage->next->flush( stage->next, flags );
31408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell}
31508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
31608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
317d75454840672f462de933724daae24a839aac48eMichal Krolstatic void validate_destroy( struct draw_stage *stage )
318d75454840672f462de933724daae24a839aac48eMichal Krol{
319d75454840672f462de933724daae24a839aac48eMichal Krol   FREE( stage );
320d75454840672f462de933724daae24a839aac48eMichal Krol}
32108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
32208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
32308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/**
32408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * Create validate pipeline stage.
32508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell */
32608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwellstruct draw_stage *draw_validate_stage( struct draw_context *draw )
32708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell{
32808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
329150c289f6067cb1ba4572f9124948a94ef94c839Edward O'Callaghan   if (!stage)
3300d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      return NULL;
33108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
33208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   stage->draw = draw;
333eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   stage->name = "validate";
33408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   stage->next = NULL;
3350bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   stage->point = validate_point;
3360bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   stage->line = validate_line;
3370bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   stage->tri = validate_tri;
3380bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   stage->flush = validate_flush;
3390bfd085e2866fbbd40209dcee23f0e6240583fe8Brian Paul   stage->reset_stipple_counter = validate_reset_stipple_counter;
340d75454840672f462de933724daae24a839aac48eMichal Krol   stage->destroy = validate_destroy;
34108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
34208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   return stage;
34308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell}
344