108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/**************************************************************************
208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell *
308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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.
2108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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
2808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
2908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell */
3008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
314f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
324586e6c8cb5b391536a370faa0c419c3fd541693José Fonseca#include "util/u_math.h"
3308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell#include "pipe/p_defines.h"
3408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell#include "draw_private.h"
35507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h"
360588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell#include "draw_context.h"
37f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell#include "draw_vbuf.h"
3808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
394505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwellstatic boolean points( unsigned prim )
404505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell{
414505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   return (prim == PIPE_PRIM_POINTS);
424505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell}
434505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
444505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwellstatic boolean lines( unsigned prim )
454505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell{
464505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   return (prim == PIPE_PRIM_LINES ||
474505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell           prim == PIPE_PRIM_LINE_STRIP ||
484505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell           prim == PIPE_PRIM_LINE_LOOP);
494505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell}
504505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
514505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwellstatic boolean triangles( unsigned prim )
524505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell{
534505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   return prim >= PIPE_PRIM_TRIANGLES;
544505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell}
5508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
563faf6230ff4b63833c072ac7afeb43c25d3cba22Brian/**
57f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * Default version of a function to check if we need any special
58f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * pipeline stages, or whether prims/verts can go through untouched.
59f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * Don't test for bypass clipping or vs modes, this function is just
60f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * about the primitive pipeline stages.
61f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell *
62f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell * This can be overridden by the driver.
633faf6230ff4b63833c072ac7afeb43c25d3cba22Brian */
643faf6230ff4b63833c072ac7afeb43c25d3cba22Brianboolean
650588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwelldraw_need_pipeline(const struct draw_context *draw,
660588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell                   const struct pipe_rasterizer_state *rasterizer,
674505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell                   unsigned int prim )
683faf6230ff4b63833c072ac7afeb43c25d3cba22Brian{
69f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   /* If the driver has overridden this, use that version:
70f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell    */
71f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   if (draw->render &&
72f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell       draw->render->need_pipeline)
73f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   {
74f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell      return draw->render->need_pipeline( draw->render,
75f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell                                          rasterizer,
76f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell                                          prim );
77f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell   }
78f5d4274b4a8effc70c238060c3728aea629663dfKeith Whitwell
794505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   /* Don't have to worry about triangles turning into lines/points
804505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell    * and triggering the pipeline, because we have to trigger the
814505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell    * pipeline *anyway* if unfilled mode is active.
824505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell    */
834505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   if (lines(prim))
844505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   {
854505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* line stipple */
860588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->line_stipple_enable && draw->pipeline.line_stipple)
874505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
884505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
894505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* wide lines */
904586e6c8cb5b391536a370faa0c419c3fd541693José Fonseca      if (roundf(rasterizer->line_width) > draw->pipeline.wide_line_threshold)
914505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
924505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
934505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* AA lines */
940588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->line_smooth && draw->pipeline.aaline)
954505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
964505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   }
974505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
984505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   if (points(prim))
994505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   {
1004505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* large points */
1010588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->point_size > draw->pipeline.wide_point_threshold)
1024505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1034505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1048cb223eb020560d59c8f73e09b832cef477933b7Brian Paul      /* sprite points */
1058cb223eb020560d59c8f73e09b832cef477933b7Brian Paul      if (rasterizer->point_quad_rasterization
1068cb223eb020560d59c8f73e09b832cef477933b7Brian Paul          && draw->pipeline.wide_point_sprites)
1078cb223eb020560d59c8f73e09b832cef477933b7Brian Paul         return TRUE;
1088cb223eb020560d59c8f73e09b832cef477933b7Brian Paul
1094505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* AA points */
1100588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->point_smooth && draw->pipeline.aapoint)
1114505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1124505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1134505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* point sprites */
1144a4daa75a85db22cd37ebd533ebbccb427e07077Roland Scheidegger      if (rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)
1154505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1164505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   }
1174505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1184505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1194505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   if (triangles(prim))
1204505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   {
1214505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* polygon stipple */
1220588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
1234505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1244505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1254505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* unfilled polygons */
1260bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      if (rasterizer->fill_front != PIPE_POLYGON_MODE_FILL ||
1277813d12e05e654d12e2cf6c47a7e73eb0310493cKeith Whitwell          rasterizer->fill_back != PIPE_POLYGON_MODE_FILL)
1284505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1294505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1304505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* polygon offset */
1310bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      if (rasterizer->offset_point ||
1320bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell          rasterizer->offset_line ||
1330bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell          rasterizer->offset_tri)
1344505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1354505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell
1364505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell      /* two-side lighting */
1370588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell      if (rasterizer->light_twoside)
1384505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell         return TRUE;
1394505acf3b28f0b88bf97838ed7898f10e9200b93Keith Whitwell   }
1403faf6230ff4b63833c072ac7afeb43c25d3cba22Brian
1413e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell   /* polygon cull - this is difficult - hardware can cull just fine
1423e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    * most of the time (though sometimes CULL_NEITHER is unsupported.
1433e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    *
1443e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    * Generally this isn't a reason to require the pipeline, though.
1453e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    *
1460588858702d1a5c9c08573ea6817e2e149473cf6Keith Whitwell   if (rasterizer->cull_mode)
1473faf6230ff4b63833c072ac7afeb43c25d3cba22Brian      return TRUE;
1483e9b1bc1009ca1a2923f844d00bf478dc9d24644Keith Whitwell    */
1493faf6230ff4b63833c072ac7afeb43c25d3cba22Brian
1503faf6230ff4b63833c072ac7afeb43c25d3cba22Brian   return FALSE;
1513faf6230ff4b63833c072ac7afeb43c25d3cba22Brian}
15208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
15308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
15408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
15508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/**
15608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * Rebuild the rendering pipeline.
15708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell */
1580bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic struct draw_stage *validate_pipeline( struct draw_stage *stage )
15908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell{
16008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   struct draw_context *draw = stage->draw;
16108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   struct draw_stage *next = draw->pipeline.rasterize;
1623c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul   boolean need_det = FALSE;
1633c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul   boolean precalc_flat = FALSE;
164e9276efafe43219d7af548ce7f5d2440e19836b0Brian   boolean wide_lines, wide_points;
165d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   const struct pipe_rasterizer_state *rast = draw->rasterizer;
1661603a33fb276d7e78a2e872dfa05aa0093d1329aBrian
1671603a33fb276d7e78a2e872dfa05aa0093d1329aBrian   /* Set the validate's next stage to the rasterize stage, so that it
1681603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    * can be found later if needed for flushing.
1691603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    */
1701603a33fb276d7e78a2e872dfa05aa0093d1329aBrian   stage->next = next;
17108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
1725e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian   /* drawing wide lines? */
1734586e6c8cb5b391536a370faa0c419c3fd541693José Fonseca   wide_lines = (roundf(rast->line_width) > draw->pipeline.wide_line_threshold
174d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul                 && !rast->line_smooth);
1755e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian
176a7ea4d11fb5a2a39daaad8752706291ac93013f7Brian Paul   /* drawing large/sprite points (but not AA points)? */
177d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->sprite_coord_enable && draw->pipeline.point_sprite)
1785a09ad8248ce452136ed96a3d46532b03c877618Brian      wide_points = TRUE;
179d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   else if (rast->point_smooth && draw->pipeline.aapoint)
1805e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian      wide_points = FALSE;
181d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   else if (rast->point_size > draw->pipeline.wide_point_threshold)
1825e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian      wide_points = TRUE;
1838cb223eb020560d59c8f73e09b832cef477933b7Brian Paul   else if (rast->point_quad_rasterization && draw->pipeline.wide_point_sprites)
1848cb223eb020560d59c8f73e09b832cef477933b7Brian Paul      wide_points = TRUE;
1855e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian   else
1865e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian      wide_points = FALSE;
1875e29aab1752c3e07ae2ebde4cb00e6550dab0eb2Brian
18808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   /*
18908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    * NOTE: we build up the pipeline in end-to-start order.
19008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    *
19108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    * TODO: make the current primitive part of the state and build
19208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    * shorter pipelines for lines & points.
19308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    */
19408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
195d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->line_smooth && draw->pipeline.aaline) {
196aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      draw->pipeline.aaline->next = next;
197aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      next = draw->pipeline.aaline;
1989ae069dbbd6814fc86ad371e439b7750b938408aBrian Paul      precalc_flat = TRUE;
199aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
200aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
201d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->point_smooth && draw->pipeline.aapoint) {
202eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      draw->pipeline.aapoint->next = next;
203eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      next = draw->pipeline.aapoint;
204eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
205eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
206a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul   if (wide_lines) {
207a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      draw->pipeline.wide_line->next = next;
208a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      next = draw->pipeline.wide_line;
2093c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      precalc_flat = TRUE;
210a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul   }
211a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul
212a7ea4d11fb5a2a39daaad8752706291ac93013f7Brian Paul   if (wide_points) {
213a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      draw->pipeline.wide_point->next = next;
214a1a13954885cd469faab49633b5386e5c889e3dfBrian Paul      next = draw->pipeline.wide_point;
215e3444deec5a369e4ffabfeb9f6c257dd6b8e5a30Brian   }
216e3444deec5a369e4ffabfeb9f6c257dd6b8e5a30Brian
217d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->line_stipple_enable && draw->pipeline.line_stipple) {
218329a8479b69a800b5fc6485767fb676c3eae26dbBrian      draw->pipeline.stipple->next = next;
219329a8479b69a800b5fc6485767fb676c3eae26dbBrian      next = draw->pipeline.stipple;
2203c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      precalc_flat = TRUE;		/* only needed for lines really */
221329a8479b69a800b5fc6485767fb676c3eae26dbBrian   }
222329a8479b69a800b5fc6485767fb676c3eae26dbBrian
223d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->poly_stipple_enable
224446bfc32a83008e0865ec869bc80b920c907f10fBrian       && draw->pipeline.pstipple) {
225446bfc32a83008e0865ec869bc80b920c907f10fBrian      draw->pipeline.pstipple->next = next;
226446bfc32a83008e0865ec869bc80b920c907f10fBrian      next = draw->pipeline.pstipple;
227446bfc32a83008e0865ec869bc80b920c907f10fBrian   }
228446bfc32a83008e0865ec869bc80b920c907f10fBrian
2290bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
2300bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell       rast->fill_back != PIPE_POLYGON_MODE_FILL) {
23108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.unfilled->next = next;
23208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.unfilled;
2333c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      precalc_flat = TRUE;		/* only needed for triangles really */
2343c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      need_det = TRUE;
23508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
23682d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell
237d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->flatshade && precalc_flat) {
23882d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      draw->pipeline.flatshade->next = next;
23982d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell      next = draw->pipeline.flatshade;
24082d9063708539d53c7670b2ab732bed24230b94dKeith Whitwell   }
24108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
2420bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (rast->offset_point ||
2430bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell       rast->offset_line ||
2440bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell       rast->offset_tri) {
24508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.offset->next = next;
24608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.offset;
2473c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      need_det = TRUE;
24808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
24908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
250d30ab4394e7c6b1f3508eb68d673fbf315907781Brian Paul   if (rast->light_twoside) {
25108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.twoside->next = next;
25208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.twoside;
2533c31b1b6d15dc5424babd5b4b54cd380d88be84aBrian Paul      need_det = TRUE;
25408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
25508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
25608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   /* Always run the cull stage as we calculate determinant there
2571603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    * also.
2581603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    *
2591603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    * This can actually be a win as culling out the triangles can lead
2601603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    * to less work emitting vertices, smaller vertex buffers, etc.
2611603a33fb276d7e78a2e872dfa05aa0093d1329aBrian    * It's difficult to say whether this will be true in general.
26208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    */
2630bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (need_det || rast->cull_face != PIPE_FACE_NONE) {
26408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.cull->next = next;
26508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.cull;
26608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
26708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
26808589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   /* Clip stage
26908589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell    */
2706c0dc4bafbdbdc0cb4b6e5934fe064226dbd47ecKeith Whitwell   if (draw->clip_xy || draw->clip_z || draw->clip_user)
27108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   {
27208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      draw->pipeline.clip->next = next;
27308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell      next = draw->pipeline.clip;
27408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   }
27508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
2761603a33fb276d7e78a2e872dfa05aa0093d1329aBrian
27708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   draw->pipeline.first = next;
278eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell
279eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   if (0) {
280eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell      debug_printf("draw pipeline:\n");
281eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell      for (next = draw->pipeline.first; next ; next = next->next )
282eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell         debug_printf("   %s\n", next->name);
283eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell      debug_printf("\n");
284eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   }
285eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell
286eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   return draw->pipeline.first;
2870bfd085e2866fbbd40209dcee23f0e6240583fe8Brian}
2880bfd085e2866fbbd40209dcee23f0e6240583fe8Brian
2890bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void validate_tri( struct draw_stage *stage,
2900bfd085e2866fbbd40209dcee23f0e6240583fe8Brian			  struct prim_header *header )
2910bfd085e2866fbbd40209dcee23f0e6240583fe8Brian{
2920bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   struct draw_stage *pipeline = validate_pipeline( stage );
2930bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   pipeline->tri( pipeline, header );
2940bfd085e2866fbbd40209dcee23f0e6240583fe8Brian}
2950bfd085e2866fbbd40209dcee23f0e6240583fe8Brian
2960bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void validate_line( struct draw_stage *stage,
2970bfd085e2866fbbd40209dcee23f0e6240583fe8Brian			   struct prim_header *header )
2980bfd085e2866fbbd40209dcee23f0e6240583fe8Brian{
2990bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   struct draw_stage *pipeline = validate_pipeline( stage );
3000bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   pipeline->line( pipeline, header );
3010bfd085e2866fbbd40209dcee23f0e6240583fe8Brian}
3020bfd085e2866fbbd40209dcee23f0e6240583fe8Brian
3030bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void validate_point( struct draw_stage *stage,
3040bfd085e2866fbbd40209dcee23f0e6240583fe8Brian			    struct prim_header *header )
3050bfd085e2866fbbd40209dcee23f0e6240583fe8Brian{
3060bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   struct draw_stage *pipeline = validate_pipeline( stage );
3070bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   pipeline->point( pipeline, header );
3080bfd085e2866fbbd40209dcee23f0e6240583fe8Brian}
3090bfd085e2866fbbd40209dcee23f0e6240583fe8Brian
3100bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void validate_reset_stipple_counter( struct draw_stage *stage )
3110bfd085e2866fbbd40209dcee23f0e6240583fe8Brian{
3120bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   struct draw_stage *pipeline = validate_pipeline( stage );
3130bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   pipeline->reset_stipple_counter( pipeline );
3140bfd085e2866fbbd40209dcee23f0e6240583fe8Brian}
3150bfd085e2866fbbd40209dcee23f0e6240583fe8Brian
3160bfd085e2866fbbd40209dcee23f0e6240583fe8Brianstatic void validate_flush( struct draw_stage *stage,
3170bfd085e2866fbbd40209dcee23f0e6240583fe8Brian			    unsigned flags )
3180bfd085e2866fbbd40209dcee23f0e6240583fe8Brian{
3190bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   /* May need to pass a backend flush on to the rasterize stage.
3200bfd085e2866fbbd40209dcee23f0e6240583fe8Brian    */
3210bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   if (stage->next)
3220bfd085e2866fbbd40209dcee23f0e6240583fe8Brian      stage->next->flush( stage->next, flags );
32308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell}
32408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
32508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
326d75454840672f462de933724daae24a839aac48eMichalstatic void validate_destroy( struct draw_stage *stage )
327d75454840672f462de933724daae24a839aac48eMichal{
328d75454840672f462de933724daae24a839aac48eMichal   FREE( stage );
329d75454840672f462de933724daae24a839aac48eMichal}
33008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
33108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
33208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell/**
33308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell * Create validate pipeline stage.
33408589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell */
33508589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwellstruct draw_stage *draw_validate_stage( struct draw_context *draw )
33608589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell{
33708589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
3380d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (stage == NULL)
3390d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      return NULL;
34008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
34108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   stage->draw = draw;
342eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   stage->name = "validate";
34308589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   stage->next = NULL;
3440bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->point = validate_point;
3450bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->line = validate_line;
3460bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->tri = validate_tri;
3470bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->flush = validate_flush;
3480bfd085e2866fbbd40209dcee23f0e6240583fe8Brian   stage->reset_stipple_counter = validate_reset_stipple_counter;
349d75454840672f462de933724daae24a839aac48eMichal   stage->destroy = validate_destroy;
35008589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell
35108589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell   return stage;
35208589f71051e588b0bb7d0c8b529976c85398dd1Keith Whitwell}
353