00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "util/u_math.h"
00032 #include "util/u_memory.h"
00033
00034 #include "pipe/p_shader_tokens.h"
00035 #include "draw_vs.h"
00036 #include "draw_pipe.h"
00037
00038
00040 struct flat_stage
00041 {
00042 struct draw_stage stage;
00043
00044 uint num_color_attribs;
00045 uint color_attribs[2];
00046
00047 uint num_spec_attribs;
00048 uint spec_attribs[2];
00049 };
00050
00051 #define COPY_3FV( DST, SRC ) \
00052 do { \
00053 (DST)[0] = (SRC)[0]; \
00054 (DST)[1] = (SRC)[1]; \
00055 (DST)[2] = (SRC)[2]; \
00056 } while (0)
00057
00058
00059 static INLINE struct flat_stage *
00060 flat_stage(struct draw_stage *stage)
00061 {
00062 return (struct flat_stage *) stage;
00063 }
00064
00065
00067 static INLINE void copy_colors( struct draw_stage *stage,
00068 struct vertex_header *dst,
00069 const struct vertex_header *src )
00070 {
00071 const struct flat_stage *flat = flat_stage(stage);
00072 uint i;
00073
00074 for (i = 0; i < flat->num_color_attribs; i++) {
00075 const uint attr = flat->color_attribs[i];
00076 COPY_4FV(dst->data[attr], src->data[attr]);
00077 }
00078
00079 for (i = 0; i < flat->num_spec_attribs; i++) {
00080 const uint attr = flat->spec_attribs[i];
00081 COPY_3FV(dst->data[attr], src->data[attr]);
00082 }
00083 }
00084
00085
00087 static INLINE void copy_colors2( struct draw_stage *stage,
00088 struct vertex_header *dst0,
00089 struct vertex_header *dst1,
00090 const struct vertex_header *src )
00091 {
00092 const struct flat_stage *flat = flat_stage(stage);
00093 uint i;
00094 for (i = 0; i < flat->num_color_attribs; i++) {
00095 const uint attr = flat->color_attribs[i];
00096 COPY_4FV(dst0->data[attr], src->data[attr]);
00097 COPY_4FV(dst1->data[attr], src->data[attr]);
00098 }
00099
00100 for (i = 0; i < flat->num_spec_attribs; i++) {
00101 const uint attr = flat->spec_attribs[i];
00102 COPY_3FV(dst0->data[attr], src->data[attr]);
00103 COPY_3FV(dst1->data[attr], src->data[attr]);
00104 }
00105 }
00106
00107
00112 static void flatshade_tri_0( struct draw_stage *stage,
00113 struct prim_header *header )
00114 {
00115 struct prim_header tmp;
00116
00117 tmp.det = header->det;
00118 tmp.flags = header->flags;
00119 tmp.pad = header->pad;
00120 tmp.v[0] = header->v[0];
00121 tmp.v[1] = dup_vert(stage, header->v[1], 0);
00122 tmp.v[2] = dup_vert(stage, header->v[2], 1);
00123
00124 copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]);
00125
00126 stage->next->tri( stage->next, &tmp );
00127 }
00128
00129
00130 static void flatshade_tri_2( struct draw_stage *stage,
00131 struct prim_header *header )
00132 {
00133 struct prim_header tmp;
00134
00135 tmp.det = header->det;
00136 tmp.flags = header->flags;
00137 tmp.pad = header->pad;
00138 tmp.v[0] = dup_vert(stage, header->v[0], 0);
00139 tmp.v[1] = dup_vert(stage, header->v[1], 1);
00140 tmp.v[2] = header->v[2];
00141
00142 copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]);
00143
00144 stage->next->tri( stage->next, &tmp );
00145 }
00146
00147
00148
00149
00150
00154 static void flatshade_line_0( struct draw_stage *stage,
00155 struct prim_header *header )
00156 {
00157 struct prim_header tmp;
00158
00159 tmp.v[0] = header->v[0];
00160 tmp.v[1] = dup_vert(stage, header->v[1], 0);
00161
00162 copy_colors(stage, tmp.v[1], tmp.v[0]);
00163
00164 stage->next->line( stage->next, &tmp );
00165 }
00166
00167 static void flatshade_line_1( struct draw_stage *stage,
00168 struct prim_header *header )
00169 {
00170 struct prim_header tmp;
00171
00172 tmp.v[0] = dup_vert(stage, header->v[0], 0);
00173 tmp.v[1] = header->v[1];
00174
00175 copy_colors(stage, tmp.v[0], tmp.v[1]);
00176
00177 stage->next->line( stage->next, &tmp );
00178 }
00179
00180
00181
00182
00183 static void flatshade_init_state( struct draw_stage *stage )
00184 {
00185 struct flat_stage *flat = flat_stage(stage);
00186 const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
00187 uint i;
00188
00189
00190 flat->num_color_attribs = 0;
00191 flat->num_spec_attribs = 0;
00192 for (i = 0; i < vs->info.num_outputs; i++) {
00193 if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
00194 vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
00195 if (vs->info.output_semantic_index[i] == 0)
00196 flat->color_attribs[flat->num_color_attribs++] = i;
00197 else
00198 flat->spec_attribs[flat->num_spec_attribs++] = i;
00199 }
00200 }
00201
00202
00203
00204 if (stage->draw->rasterizer->flatshade_first) {
00205 stage->line = flatshade_line_0;
00206 stage->tri = flatshade_tri_0;
00207 }
00208 else {
00209 stage->line = flatshade_line_1;
00210 stage->tri = flatshade_tri_2;
00211 }
00212 }
00213
00214 static void flatshade_first_tri( struct draw_stage *stage,
00215 struct prim_header *header )
00216 {
00217 flatshade_init_state( stage );
00218 stage->tri( stage, header );
00219 }
00220
00221 static void flatshade_first_line( struct draw_stage *stage,
00222 struct prim_header *header )
00223 {
00224 flatshade_init_state( stage );
00225 stage->line( stage, header );
00226 }
00227
00228
00229 static void flatshade_flush( struct draw_stage *stage,
00230 unsigned flags )
00231 {
00232 stage->tri = flatshade_first_tri;
00233 stage->line = flatshade_first_line;
00234 stage->next->flush( stage->next, flags );
00235 }
00236
00237
00238 static void flatshade_reset_stipple_counter( struct draw_stage *stage )
00239 {
00240 stage->next->reset_stipple_counter( stage->next );
00241 }
00242
00243
00244 static void flatshade_destroy( struct draw_stage *stage )
00245 {
00246 draw_free_temp_verts( stage );
00247 FREE( stage );
00248 }
00249
00250
00254 struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
00255 {
00256 struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
00257 if (flatshade == NULL)
00258 goto fail;
00259
00260 if (!draw_alloc_temp_verts( &flatshade->stage, 2 ))
00261 goto fail;
00262
00263 flatshade->stage.draw = draw;
00264 flatshade->stage.next = NULL;
00265 flatshade->stage.point = draw_pipe_passthrough_point;
00266 flatshade->stage.line = flatshade_first_line;
00267 flatshade->stage.tri = flatshade_first_tri;
00268 flatshade->stage.flush = flatshade_flush;
00269 flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
00270 flatshade->stage.destroy = flatshade_destroy;
00271
00272 return &flatshade->stage;
00273
00274 fail:
00275 if (flatshade)
00276 flatshade->stage.destroy( &flatshade->stage );
00277
00278 return NULL;
00279 }
00280
00281