gallium: rename pipe_buffer_handle to pipe_buffer, rework pipebuffer/ code
[mesa.git] / src / mesa / pipe / draw / draw_flatshade.c
index cf5e762079adbfe94815db95a6d9ec56e56d5d24..8444c53310648749542cce2eff69028965505a42 100644 (file)
 /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "main/imports.h"
+#include "pipe/p_util.h"
+#include "pipe/p_shader_tokens.h"
 #include "draw_private.h"
 
 
-struct flatshade_stage {
+/** subclass of draw_stage */
+struct flat_stage
+{
    struct draw_stage stage;
 
-   const GLuint *lookup;
+   uint num_color_attribs;
+   uint color_attribs[4];  /* front/back primary/secondary colors */
 };
 
 
-
-static INLINE struct flatshade_stage *flatshade_stage( struct draw_stage *stage )
+static INLINE struct flat_stage *
+flat_stage(struct draw_stage *stage)
 {
-   return (struct flatshade_stage *)stage;
+   return (struct flat_stage *) stage;
 }
 
 
 static void flatshade_begin( struct draw_stage *stage )
 {
+   struct flat_stage *flat = flat_stage(stage);
+   const struct pipe_shader_state *vs = stage->draw->vertex_shader->state;
+   uint i;
+
+   /* Find which vertex shader outputs are colors, make a list */
+   flat->num_color_attribs = 0;
+   for (i = 0; i < vs->num_outputs; i++) {
+      if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
+          vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+         flat->color_attribs[flat->num_color_attribs++] = i;
+      }
+   }
+
    stage->next->begin( stage->next );
 }
 
 
-
-static INLINE void copy_attr( GLuint attr,
-                             struct vertex_header *dst, 
-                             const struct vertex_header *src )
+/** Copy all the color attributes from 'src' vertex to 'dst' vertex */
+static INLINE void copy_colors( struct draw_stage *stage,
+                                struct vertex_header *dst,
+                                const struct vertex_header *src )
 {
-   if (attr) {
-      memcpy( dst->data[attr],
-             src->data[attr],
-             sizeof(src->data[0]) );
+   const struct flat_stage *flat = flat_stage(stage);
+   uint i;
+   for (i = 0; i < flat->num_color_attribs; i++) {
+      const uint attr = flat->color_attribs[i];
+      COPY_4FV(dst->data[attr], src->data[attr]);
    }
 }
 
 
-static INLINE void copy_colors( struct draw_stage *stage, 
-                                struct vertex_header *dst, 
-                                const struct vertex_header *src )
+/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */
+static INLINE void copy_colors2( struct draw_stage *stage,
+                                 struct vertex_header *dst0,
+                                 struct vertex_header *dst1,
+                                 const struct vertex_header *src )
 {
-   const struct flatshade_stage *flatshade = flatshade_stage(stage);
-   const GLuint *lookup = flatshade->lookup;
-
-   copy_attr( lookup[VF_ATTRIB_COLOR0], dst, src );
-   copy_attr( lookup[VF_ATTRIB_COLOR1], dst, src );
-   copy_attr( lookup[VF_ATTRIB_BFC0], dst, src );
-   copy_attr( lookup[VF_ATTRIB_BFC1], dst, src );
+   const struct flat_stage *flat = flat_stage(stage);
+   uint i;
+   for (i = 0; i < flat->num_color_attribs; i++) {
+      const uint attr = flat->color_attribs[i];
+      COPY_4FV(dst0->data[attr], src->data[attr]);
+      COPY_4FV(dst1->data[attr], src->data[attr]);
+   }
 }
 
 
@@ -89,12 +109,12 @@ static void flatshade_tri( struct draw_stage *stage,
    struct prim_header tmp;
 
    tmp.det = header->det;
+   tmp.edgeflags = header->edgeflags;
    tmp.v[0] = dup_vert(stage, header->v[0], 0);
    tmp.v[1] = dup_vert(stage, header->v[1], 1);
    tmp.v[2] = header->v[2];
 
-   copy_colors(stage, tmp.v[0], tmp.v[2]);
-   copy_colors(stage, tmp.v[1], tmp.v[2]);
+   copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]);
    
    stage->next->tri( stage->next, &tmp );
 }
@@ -136,12 +156,19 @@ static void flatshade_reset_stipple_counter( struct draw_stage *stage )
 }
 
 
+static void flatshade_destroy( struct draw_stage *stage )
+{
+   draw_free_tmps( stage );
+   FREE( stage );
+}
+
+
 /**
  * Create flatshading drawing stage.
  */
 struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
 {
-   struct flatshade_stage *flatshade = CALLOC_STRUCT(flatshade_stage);
+   struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
 
    draw_alloc_tmps( &flatshade->stage, 2 );
 
@@ -153,8 +180,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
    flatshade->stage.tri = flatshade_tri;
    flatshade->stage.end = flatshade_end;
    flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
-
-   flatshade->lookup = draw->vf_attr_to_slot;
+   flatshade->stage.destroy = flatshade_destroy;
 
    return &flatshade->stage;
 }