draw_pipe_flatshade.c revision f93332da5655a31b6c44a1079629a15360ff999b
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 <keith@tungstengraphics.com> 29 */ 30 31#include "pipe/p_util.h" 32#include "pipe/p_shader_tokens.h" 33#include "draw_vs.h" 34#include "draw_pipe.h" 35 36 37/** subclass of draw_stage */ 38struct flat_stage 39{ 40 struct draw_stage stage; 41 42 uint num_color_attribs; 43 uint color_attribs[4]; /* front/back primary/secondary colors */ 44}; 45 46 47static INLINE struct flat_stage * 48flat_stage(struct draw_stage *stage) 49{ 50 return (struct flat_stage *) stage; 51} 52 53 54/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ 55static INLINE void copy_colors( struct draw_stage *stage, 56 struct vertex_header *dst, 57 const struct vertex_header *src ) 58{ 59 const struct flat_stage *flat = flat_stage(stage); 60 uint i; 61 for (i = 0; i < flat->num_color_attribs; i++) { 62 const uint attr = flat->color_attribs[i]; 63 COPY_4FV(dst->data[attr], src->data[attr]); 64 } 65} 66 67 68/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ 69static INLINE void copy_colors2( struct draw_stage *stage, 70 struct vertex_header *dst0, 71 struct vertex_header *dst1, 72 const struct vertex_header *src ) 73{ 74 const struct flat_stage *flat = flat_stage(stage); 75 uint i; 76 for (i = 0; i < flat->num_color_attribs; i++) { 77 const uint attr = flat->color_attribs[i]; 78 COPY_4FV(dst0->data[attr], src->data[attr]); 79 COPY_4FV(dst1->data[attr], src->data[attr]); 80 } 81} 82 83 84/** 85 * Flatshade tri. Required for clipping and when unfilled tris are 86 * active, otherwise handled by hardware. 87 */ 88static void flatshade_tri_0( struct draw_stage *stage, 89 struct prim_header *header ) 90{ 91 struct prim_header tmp; 92 93 tmp.det = header->det; 94 tmp.flags = header->flags; 95 tmp.pad = header->pad; 96 tmp.v[0] = header->v[0]; 97 tmp.v[1] = dup_vert(stage, header->v[1], 0); 98 tmp.v[2] = dup_vert(stage, header->v[2], 1); 99 100 copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]); 101 102 stage->next->tri( stage->next, &tmp ); 103} 104 105 106static void flatshade_tri_2( struct draw_stage *stage, 107 struct prim_header *header ) 108{ 109 struct prim_header tmp; 110 111 tmp.det = header->det; 112 tmp.flags = header->flags; 113 tmp.pad = header->pad; 114 tmp.v[0] = dup_vert(stage, header->v[0], 0); 115 tmp.v[1] = dup_vert(stage, header->v[1], 1); 116 tmp.v[2] = header->v[2]; 117 118 copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); 119 120 stage->next->tri( stage->next, &tmp ); 121} 122 123 124 125 126 127/** 128 * Flatshade line. Required for clipping. 129 */ 130static void flatshade_line_0( struct draw_stage *stage, 131 struct prim_header *header ) 132{ 133 struct prim_header tmp; 134 135 tmp.v[0] = header->v[0]; 136 tmp.v[1] = dup_vert(stage, header->v[1], 0); 137 138 copy_colors(stage, tmp.v[1], tmp.v[0]); 139 140 stage->next->line( stage->next, &tmp ); 141} 142 143static void flatshade_line_1( struct draw_stage *stage, 144 struct prim_header *header ) 145{ 146 struct prim_header tmp; 147 148 tmp.v[0] = dup_vert(stage, header->v[0], 0); 149 tmp.v[1] = header->v[1]; 150 151 copy_colors(stage, tmp.v[0], tmp.v[1]); 152 153 stage->next->line( stage->next, &tmp ); 154} 155 156 157 158 159static void flatshade_init_state( struct draw_stage *stage ) 160{ 161 struct flat_stage *flat = flat_stage(stage); 162 const struct draw_vertex_shader *vs = stage->draw->vertex_shader; 163 uint i; 164 165 /* Find which vertex shader outputs are colors, make a list */ 166 flat->num_color_attribs = 0; 167 for (i = 0; i < vs->info.num_outputs; i++) { 168 if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || 169 vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { 170 flat->color_attribs[flat->num_color_attribs++] = i; 171 } 172 } 173 174 /* Choose flatshade routine according to provoking vertex: 175 */ 176 if (stage->draw->rasterizer->flatshade_first) { 177 stage->line = flatshade_line_0; 178 stage->tri = flatshade_tri_0; 179 } 180 else { 181 stage->line = flatshade_line_1; 182 stage->tri = flatshade_tri_2; 183 } 184} 185 186static void flatshade_first_tri( struct draw_stage *stage, 187 struct prim_header *header ) 188{ 189 flatshade_init_state( stage ); 190 stage->tri( stage, header ); 191} 192 193static void flatshade_first_line( struct draw_stage *stage, 194 struct prim_header *header ) 195{ 196 flatshade_init_state( stage ); 197 stage->line( stage, header ); 198} 199 200 201static void flatshade_flush( struct draw_stage *stage, 202 unsigned flags ) 203{ 204 stage->tri = flatshade_first_tri; 205 stage->line = flatshade_first_line; 206 stage->next->flush( stage->next, flags ); 207} 208 209 210static void flatshade_reset_stipple_counter( struct draw_stage *stage ) 211{ 212 stage->next->reset_stipple_counter( stage->next ); 213} 214 215 216static void flatshade_destroy( struct draw_stage *stage ) 217{ 218 draw_free_temp_verts( stage ); 219 FREE( stage ); 220} 221 222 223/** 224 * Create flatshading drawing stage. 225 */ 226struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) 227{ 228 struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); 229 if (flatshade == NULL) 230 goto fail; 231 232 if (!draw_alloc_temp_verts( &flatshade->stage, 2 )) 233 goto fail; 234 235 flatshade->stage.draw = draw; 236 flatshade->stage.next = NULL; 237 flatshade->stage.point = draw_pipe_passthrough_point; 238 flatshade->stage.line = flatshade_first_line; 239 flatshade->stage.tri = flatshade_first_tri; 240 flatshade->stage.flush = flatshade_flush; 241 flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; 242 flatshade->stage.destroy = flatshade_destroy; 243 244 return &flatshade->stage; 245 246 fail: 247 if (flatshade) 248 flatshade->stage.destroy( &flatshade->stage ); 249 250 return NULL; 251} 252 253 254