1 /************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* Authors: Keith Whitwell <keithw (at) vmware.com> 29 */ 30 31 #include "util/u_memory.h" 32 #include "util/u_math.h" 33 #include "util/u_prim.h" 34 #include "pipe/p_defines.h" 35 #include "draw_private.h" 36 #include "draw_pipe.h" 37 #include "draw_context.h" 38 #include "draw_vbuf.h" 39 40 41 /** 42 * Default version of a function to check if we need any special 43 * pipeline stages, or whether prims/verts can go through untouched. 44 * Don't test for bypass clipping or vs modes, this function is just 45 * about the primitive pipeline stages. 46 * 47 * This can be overridden by the driver. 48 */ 49 boolean 50 draw_need_pipeline(const struct draw_context *draw, 51 const struct pipe_rasterizer_state *rasterizer, 52 unsigned int prim ) 53 { 54 unsigned reduced_prim = u_reduced_prim(prim); 55 56 /* If the driver has overridden this, use that version: 57 */ 58 if (draw->render && 59 draw->render->need_pipeline) 60 { 61 return draw->render->need_pipeline( draw->render, 62 rasterizer, 63 prim ); 64 } 65 66 /* Don't have to worry about triangles turning into lines/points 67 * and triggering the pipeline, because we have to trigger the 68 * pipeline *anyway* if unfilled mode is active. 69 */ 70 if (reduced_prim == PIPE_PRIM_LINES) { 71 /* line stipple */ 72 if (rasterizer->line_stipple_enable && draw->pipeline.line_stipple) 73 return TRUE; 74 75 /* wide lines */ 76 if (roundf(rasterizer->line_width) > draw->pipeline.wide_line_threshold) 77 return TRUE; 78 79 /* AA lines */ 80 if (rasterizer->line_smooth && draw->pipeline.aaline) 81 return TRUE; 82 83 if (draw_current_shader_num_written_culldistances(draw)) 84 return TRUE; 85 } 86 else if (reduced_prim == PIPE_PRIM_POINTS) { 87 /* large points */ 88 if (rasterizer->point_size > draw->pipeline.wide_point_threshold) 89 return TRUE; 90 91 /* sprite points */ 92 if (rasterizer->point_quad_rasterization 93 && draw->pipeline.wide_point_sprites) 94 return TRUE; 95 96 /* AA points */ 97 if (rasterizer->point_smooth && draw->pipeline.aapoint) 98 return TRUE; 99 100 /* point sprites */ 101 if (rasterizer->sprite_coord_enable && draw->pipeline.point_sprite) 102 return TRUE; 103 } 104 else if (reduced_prim == PIPE_PRIM_TRIANGLES) { 105 /* polygon stipple */ 106 if (rasterizer->poly_stipple_enable && draw->pipeline.pstipple) 107 return TRUE; 108 109 /* unfilled polygons */ 110 if (rasterizer->fill_front != PIPE_POLYGON_MODE_FILL || 111 rasterizer->fill_back != PIPE_POLYGON_MODE_FILL) 112 return TRUE; 113 114 /* polygon offset */ 115 if (rasterizer->offset_point || 116 rasterizer->offset_line || 117 rasterizer->offset_tri) 118 return TRUE; 119 120 /* two-side lighting */ 121 if (rasterizer->light_twoside) 122 return TRUE; 123 124 if (draw_current_shader_num_written_culldistances(draw)) 125 return TRUE; 126 } 127 128 /* polygon cull - this is difficult - hardware can cull just fine 129 * most of the time (though sometimes CULL_NEITHER is unsupported. 130 * 131 * Generally this isn't a reason to require the pipeline, though. 132 * 133 if (rasterizer->cull_mode) 134 return TRUE; 135 */ 136 137 return FALSE; 138 } 139 140 141 142 /** 143 * Rebuild the rendering pipeline. 144 */ 145 static struct draw_stage *validate_pipeline( struct draw_stage *stage ) 146 { 147 struct draw_context *draw = stage->draw; 148 struct draw_stage *next = draw->pipeline.rasterize; 149 boolean need_det = FALSE; 150 boolean precalc_flat = FALSE; 151 boolean wide_lines, wide_points; 152 const struct pipe_rasterizer_state *rast = draw->rasterizer; 153 154 /* Set the validate's next stage to the rasterize stage, so that it 155 * can be found later if needed for flushing. 156 */ 157 stage->next = next; 158 159 /* drawing wide lines? */ 160 wide_lines = (roundf(rast->line_width) > draw->pipeline.wide_line_threshold 161 && !rast->line_smooth); 162 163 /* drawing large/sprite points (but not AA points)? */ 164 if (rast->sprite_coord_enable && draw->pipeline.point_sprite) 165 wide_points = TRUE; 166 else if (rast->point_smooth && draw->pipeline.aapoint) 167 wide_points = FALSE; 168 else if (rast->point_size > draw->pipeline.wide_point_threshold) 169 wide_points = TRUE; 170 else if (rast->point_quad_rasterization && draw->pipeline.wide_point_sprites) 171 wide_points = TRUE; 172 else 173 wide_points = FALSE; 174 175 /* 176 * NOTE: we build up the pipeline in end-to-start order. 177 * 178 * TODO: make the current primitive part of the state and build 179 * shorter pipelines for lines & points. 180 */ 181 182 if (rast->line_smooth && draw->pipeline.aaline) { 183 draw->pipeline.aaline->next = next; 184 next = draw->pipeline.aaline; 185 precalc_flat = TRUE; 186 } 187 188 if (rast->point_smooth && draw->pipeline.aapoint) { 189 draw->pipeline.aapoint->next = next; 190 next = draw->pipeline.aapoint; 191 } 192 193 if (wide_lines) { 194 draw->pipeline.wide_line->next = next; 195 next = draw->pipeline.wide_line; 196 precalc_flat = TRUE; 197 } 198 199 if (wide_points) { 200 draw->pipeline.wide_point->next = next; 201 next = draw->pipeline.wide_point; 202 } 203 204 if (rast->line_stipple_enable && draw->pipeline.line_stipple) { 205 draw->pipeline.stipple->next = next; 206 next = draw->pipeline.stipple; 207 precalc_flat = TRUE; /* only needed for lines really */ 208 } 209 210 if (rast->poly_stipple_enable 211 && draw->pipeline.pstipple) { 212 draw->pipeline.pstipple->next = next; 213 next = draw->pipeline.pstipple; 214 } 215 216 if (rast->fill_front != PIPE_POLYGON_MODE_FILL || 217 rast->fill_back != PIPE_POLYGON_MODE_FILL) { 218 draw->pipeline.unfilled->next = next; 219 next = draw->pipeline.unfilled; 220 precalc_flat = TRUE; /* only needed for triangles really */ 221 need_det = TRUE; 222 } 223 224 if (precalc_flat) { 225 /* 226 * could only run the stage if either rast->flatshade is true 227 * or there's constant interpolated values. 228 */ 229 draw->pipeline.flatshade->next = next; 230 next = draw->pipeline.flatshade; 231 } 232 233 if (rast->offset_point || 234 rast->offset_line || 235 rast->offset_tri) { 236 draw->pipeline.offset->next = next; 237 next = draw->pipeline.offset; 238 need_det = TRUE; 239 } 240 241 if (rast->light_twoside) { 242 draw->pipeline.twoside->next = next; 243 next = draw->pipeline.twoside; 244 need_det = TRUE; 245 } 246 247 /* Always run the cull stage as we calculate determinant there 248 * also. 249 * 250 * This can actually be a win as culling out the triangles can lead 251 * to less work emitting vertices, smaller vertex buffers, etc. 252 * It's difficult to say whether this will be true in general. 253 */ 254 if (need_det || rast->cull_face != PIPE_FACE_NONE || 255 draw_current_shader_num_written_culldistances(draw)) { 256 draw->pipeline.cull->next = next; 257 next = draw->pipeline.cull; 258 } 259 260 /* Clip stage 261 */ 262 if (draw->clip_xy || draw->clip_z || draw->clip_user) 263 { 264 draw->pipeline.clip->next = next; 265 next = draw->pipeline.clip; 266 } 267 268 draw->pipeline.first = next; 269 270 if (0) { 271 debug_printf("draw pipeline:\n"); 272 for (next = draw->pipeline.first; next ; next = next->next ) 273 debug_printf(" %s\n", next->name); 274 debug_printf("\n"); 275 } 276 277 return draw->pipeline.first; 278 } 279 280 static void validate_tri( struct draw_stage *stage, 281 struct prim_header *header ) 282 { 283 struct draw_stage *pipeline = validate_pipeline( stage ); 284 pipeline->tri( pipeline, header ); 285 } 286 287 static void validate_line( struct draw_stage *stage, 288 struct prim_header *header ) 289 { 290 struct draw_stage *pipeline = validate_pipeline( stage ); 291 pipeline->line( pipeline, header ); 292 } 293 294 static void validate_point( struct draw_stage *stage, 295 struct prim_header *header ) 296 { 297 struct draw_stage *pipeline = validate_pipeline( stage ); 298 pipeline->point( pipeline, header ); 299 } 300 301 static void validate_reset_stipple_counter( struct draw_stage *stage ) 302 { 303 struct draw_stage *pipeline = validate_pipeline( stage ); 304 pipeline->reset_stipple_counter( pipeline ); 305 } 306 307 static void validate_flush( struct draw_stage *stage, 308 unsigned flags ) 309 { 310 /* May need to pass a backend flush on to the rasterize stage. 311 */ 312 if (stage->next) 313 stage->next->flush( stage->next, flags ); 314 } 315 316 317 static void validate_destroy( struct draw_stage *stage ) 318 { 319 FREE( stage ); 320 } 321 322 323 /** 324 * Create validate pipeline stage. 325 */ 326 struct draw_stage *draw_validate_stage( struct draw_context *draw ) 327 { 328 struct draw_stage *stage = CALLOC_STRUCT(draw_stage); 329 if (!stage) 330 return NULL; 331 332 stage->draw = draw; 333 stage->name = "validate"; 334 stage->next = NULL; 335 stage->point = validate_point; 336 stage->line = validate_line; 337 stage->tri = validate_tri; 338 stage->flush = validate_flush; 339 stage->reset_stipple_counter = validate_reset_stipple_counter; 340 stage->destroy = validate_destroy; 341 342 return stage; 343 } 344