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