gallium: rework compute_vertex_layout() to intelligently map vs outputs to fs inputs
authorBrian <brian.paul@tungstengraphics.com>
Wed, 23 Jan 2008 21:23:49 +0000 (14:23 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Wed, 23 Jan 2008 21:23:49 +0000 (14:23 -0700)
Some follow-on simplification in prim setup is possible...

src/mesa/pipe/softpipe/sp_prim_setup.c
src/mesa/pipe/softpipe/sp_prim_vbuf.c
src/mesa/pipe/softpipe/sp_state_derived.c

index 9b2f10b..4b6b7a0 100644 (file)
@@ -515,13 +515,22 @@ setup_fragcoord_coeff(struct setup_stage *setup)
  */
 static void setup_tri_coefficients( struct setup_stage *setup )
 {
-   const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
+   const enum interp_mode *interp;
 #define USE_INPUT_MAP 01
 #if USE_INPUT_MAP
    const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
 #endif
    uint fragSlot;
 
+   if (setup->softpipe->vertex_info.format[0] == FORMAT_HEADER) {
+      /* skip header, pos slots */
+      interp = setup->softpipe->vertex_info.interp_mode + 2;
+   }
+   else {
+      /* skip pos slot */
+      interp = setup->softpipe->vertex_info.interp_mode + 1;
+   }
+
    /* z and w are done by linear interpolation:
     */
    tri_linear_coeff(setup, &setup->posCoef, 0, 2);
@@ -557,7 +566,7 @@ static void setup_tri_coefficients( struct setup_stage *setup )
       else {
 #endif
          uint j;
-         switch (interp[vertSlot]) {
+         switch (interp[fragSlot]) {
          case INTERP_CONSTANT:
             for (j = 0; j < NUM_CHANNELS; j++)
                const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
index b76405f..0ab8a55 100644 (file)
@@ -74,6 +74,7 @@ sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
 {
    struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
    /* XXX check for state changes? */
+   assert(!cvbr->softpipe->dirty );
    return &cvbr->softpipe->vertex_info;
 }
 
index 74d34c5..d399868 100644 (file)
 #include "sp_state.h"
 
 
+static int
+find_vs_output(const struct pipe_shader_state *vs,
+               uint semantic_name,
+               uint semantic_index)
+{
+   uint i;
+   for (i = 0; i < vs->num_outputs; i++) {
+      if (vs->output_semantic_name[i] == semantic_name &&
+          vs->output_semantic_index[i] == semantic_index)
+         return i;
+   }
+   return -1;
+}
+
+
+
 /**
  * Determine which post-transform / pre-rasterization vertex attributes
  * we need.
@@ -46,6 +62,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
       = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
    struct vertex_info *vinfo = &softpipe->vertex_info;
    uint i;
+   int src;
 
    memset(vinfo, 0, sizeof(*vinfo));
 
@@ -56,6 +73,11 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
       draw_emit_vertex_attr(vinfo, FORMAT_HEADER, INTERP_LINEAR, 0);
    }
 
+   /* always emit pos for softpipe rasterization */
+   src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+   assert(src >= 0);
+   draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src);
+
    /*
     * XXX I think we need to reconcile the vertex shader outputs with
     * the fragment shader inputs here to make sure the slots line up.
@@ -63,42 +85,36 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
     * Or maybe do that in the state tracker?
     */
 
-   for (i = 0; i < vs->num_outputs; i++) {
-      switch (vs->output_semantic_name[i]) {
+   for (i = 0; i < fs->num_inputs; i++) {
+      switch (fs->input_semantic_name[i]) {
 
       case TGSI_SEMANTIC_POSITION:
-         draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, i);
+         /* handled above */
          break;
 
       case TGSI_SEMANTIC_COLOR:
-         if (vs->output_semantic_index[i] == 0) {
-            draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, i);
-         }
-         else {
-            assert(vs->output_semantic_index[i] == 1);
-            draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, i);
-         }
-         break;
-
-      case TGSI_SEMANTIC_BCOLOR:
-         /* no-op */
+         src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, 
+                              fs->input_semantic_index[i]);
+         assert(src >= 0);
+         draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src);
          break;
 
       case TGSI_SEMANTIC_FOG:
-         draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, i);
-         break;
-
-      case TGSI_SEMANTIC_PSIZE:
-         /* XXX only emit if drawing points or front/back polygon mode
-          * is point mode
-          */
-         softpipe->psize_slot
-            = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, i);
+         src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+#if 1
+         if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
+            src = 0;
+#endif
+         assert(src >= 0);
+         draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src);
          break;
 
       case TGSI_SEMANTIC_GENERIC:
          /* this includes texcoords and varying vars */
-         draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, i);
+         src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
+                              fs->input_semantic_index[i]);
+         assert(src >= 0);
+         draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src);
          break;
 
       default:
@@ -106,6 +122,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
       }
    }
 
+   src = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+   if (src >= 0) {
+      softpipe->psize_slot = src;
+      draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_CONSTANT, src);
+   }
+
+
    draw_compute_vertex_size(vinfo);
 
    softpipe->nr_frag_attrs = fs->num_inputs;
@@ -152,7 +175,7 @@ compute_cliprect(struct softpipe_context *sp)
  */
 void softpipe_update_derived( struct softpipe_context *softpipe )
 {
-   if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS))
+   if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS | SP_NEW_VS))
       calculate_vertex_layout( softpipe );
 
    if (softpipe->dirty & (SP_NEW_SCISSOR |