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