[Mesa-dev] [PATCH 4/8] softpipe: don't abuse the draw vertex_info struct for something different

sroland at vmware.com sroland at vmware.com
Mon Dec 21 19:00:23 PST 2015


From: Roland Scheidegger <sroland at vmware.com>

softpipe would calculate two "vertex layouts". The second one was however
just used for internal purposes, draw would know nothing about it even though
it looked exactly the same as the other one we tell draw about.
So, store that information separately as this was just confusing.
---
 src/gallium/drivers/softpipe/sp_context.h       |  3 +-
 src/gallium/drivers/softpipe/sp_setup.c         | 27 +++++++++-----
 src/gallium/drivers/softpipe/sp_setup.h         | 16 ++++++--
 src/gallium/drivers/softpipe/sp_state.h         |  3 --
 src/gallium/drivers/softpipe/sp_state_derived.c | 49 +++++++++++--------------
 5 files changed, 53 insertions(+), 45 deletions(-)

diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 8e5e242..188cdea 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -37,6 +37,7 @@
 #include "draw/draw_vertex.h"
 
 #include "sp_quad_pipe.h"
+#include "sp_setup.h"
 
 
 /** Do polygon stipple in the draw module? */
@@ -117,7 +118,7 @@ struct softpipe_context {
    unsigned const_buffer_size[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
 
    /** Vertex format */
-   struct vertex_info vertex_info;
+   struct sp_setup_info setup_info;
    struct vertex_info vertex_info_vbuf;
 
    /** Which vertex shader output slot contains point size */
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index ac2d978..28f163b 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -599,10 +599,12 @@ setup_tri_coefficients(struct setup_context *setup)
 {
    struct softpipe_context *softpipe = setup->softpipe;
    const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info;
-   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
+   const struct sp_setup_info *sinfo = &softpipe->setup_info;
    uint fragSlot;
    float v[3];
 
+   assert(sinfo->valid);
+
    /* z and w are done by linear interpolation:
     */
    v[0] = setup->vmin[0][2];
@@ -618,13 +620,14 @@ setup_tri_coefficients(struct setup_context *setup)
    /* setup interpolation for all the remaining attributes:
     */
    for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) {
-      const uint vertSlot = vinfo->attrib[fragSlot].src_index;
+      const uint vertSlot = sinfo->attrib[fragSlot].src_index;
       uint j;
 
-      switch (vinfo->attrib[fragSlot].interp_mode) {
+      switch (sinfo->attrib[fragSlot].interp) {
       case INTERP_CONSTANT:
-         for (j = 0; j < TGSI_NUM_CHANNELS; j++)
+         for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
+         }
          break;
       case INTERP_LINEAR:
          for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
@@ -966,11 +969,13 @@ setup_line_coefficients(struct setup_context *setup,
 {
    struct softpipe_context *softpipe = setup->softpipe;
    const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info;
-   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
+   const struct sp_setup_info *sinfo = &softpipe->setup_info;
    uint fragSlot;
    float area;
    float v[2];
 
+   assert(sinfo->valid);
+
    /* use setup->vmin, vmax to point to vertices */
    if (softpipe->rasterizer->flatshade_first)
       setup->vprovoke = v0;
@@ -1001,10 +1006,10 @@ setup_line_coefficients(struct setup_context *setup,
    /* setup interpolation for all the remaining attributes:
     */
    for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) {
-      const uint vertSlot = vinfo->attrib[fragSlot].src_index;
+      const uint vertSlot = sinfo->attrib[fragSlot].src_index;
       uint j;
 
-      switch (vinfo->attrib[fragSlot].interp_mode) {
+      switch (sinfo->attrib[fragSlot].interp) {
       case INTERP_CONSTANT:
          for (j = 0; j < TGSI_NUM_CHANNELS; j++)
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
@@ -1236,7 +1241,7 @@ sp_setup_point(struct setup_context *setup,
    const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth;
    const float x = v0[0][0];  /* Note: data[0] is always position */
    const float y = v0[0][1];
-   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
+   const struct sp_setup_info *sinfo = &softpipe->setup_info;
    uint fragSlot;
    uint layer = 0;
    unsigned viewport_index = 0;
@@ -1245,6 +1250,8 @@ sp_setup_point(struct setup_context *setup,
    print_vertex(setup, v0);
 #endif
 
+   assert(sinfo->valid);
+
    if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
       return;
 
@@ -1285,10 +1292,10 @@ sp_setup_point(struct setup_context *setup,
    const_coeff(setup, &setup->posCoef, 0, 3);
 
    for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) {
-      const uint vertSlot = vinfo->attrib[fragSlot].src_index;
+      const uint vertSlot = sinfo->attrib[fragSlot].src_index;
       uint j;
 
-      switch (vinfo->attrib[fragSlot].interp_mode) {
+      switch (sinfo->attrib[fragSlot].interp) {
       case INTERP_CONSTANT:
          /* fall-through */
       case INTERP_LINEAR:
diff --git a/src/gallium/drivers/softpipe/sp_setup.h b/src/gallium/drivers/softpipe/sp_setup.h
index 191494a..8bb50b9 100644
--- a/src/gallium/drivers/softpipe/sp_setup.h
+++ b/src/gallium/drivers/softpipe/sp_setup.h
@@ -30,11 +30,19 @@
 struct setup_context;
 struct softpipe_context;
 
+struct sp_setup_info {
+   unsigned valid;
+   struct {
+      unsigned interp:8;      /**< INTERP_X */
+      unsigned src_index:8;
+   } attrib[PIPE_MAX_SHADER_OUTPUTS];
+};
+
 void 
-sp_setup_tri( struct setup_context *setup,
-	   const float (*v0)[4],
-	   const float (*v1)[4],
-	   const float (*v2)[4] );
+sp_setup_tri(struct setup_context *setup,
+             const float (*v0)[4],
+             const float (*v1)[4],
+             const float (*v2)[4]);
 
 void
 sp_setup_line(struct setup_context *setup,
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index c35534c..16a2897 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -175,9 +175,6 @@ softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
 
 
 struct vertex_info *
-softpipe_get_vertex_info(struct softpipe_context *softpipe);
-
-struct vertex_info *
 softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
 
 
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 56ecc3b..3fb1dae 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -48,7 +48,7 @@
 static void
 invalidate_vertex_layout(struct softpipe_context *softpipe)
 {
-   softpipe->vertex_info.num_attribs =  0;
+   softpipe->setup_info.valid =  0;
 }
 
 
@@ -57,17 +57,16 @@ invalidate_vertex_layout(struct softpipe_context *softpipe)
  * (simple float[][4]) used by the 'draw' module into vertices for
  * rasterization.
  *
- * This function validates the vertex layout and returns a pointer to a
- * vertex_info object.
+ * This function validates the vertex layout.
  */
-struct vertex_info *
-softpipe_get_vertex_info(struct softpipe_context *softpipe)
+static void
+softpipe_compute_vertex_info(struct softpipe_context *softpipe)
 {
-   struct vertex_info *vinfo = &softpipe->vertex_info;
+   struct sp_setup_info *sinfo = &softpipe->setup_info;
    int vs_index;
 
-   if (vinfo->num_attribs == 0) {
-      /* compute vertex layout now */
+   if (sinfo->valid == 0) {
+      /* compute vertex layout for vbuf now */
       const struct tgsi_shader_info *fsInfo = &softpipe->fs_variant->info;
       struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
       const uint num = draw_num_shader_outputs(softpipe->draw);
@@ -91,7 +90,6 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
        * Loop over fragment shader inputs, searching for the matching output
        * from the vertex shader.
        */
-      vinfo->num_attribs = 0;
       for (i = 0; i < fsInfo->num_inputs; i++) {
          int src;
          enum interp_mode interp = INTERP_LINEAR;
@@ -142,7 +140,15 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
                                           TGSI_SEMANTIC_BCOLOR,
                                           fsInfo->input_semantic_index[i]);
 
-         draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
+         sinfo->attrib[i].interp = interp;
+         /*
+          * note src can be -1 if not found. Would need special handling,
+          * (as we don't tell draw anything about it) just force to 0.
+          * It's wrong either way but should be safer...
+          */
+         if (src < 0)
+            src = 0;
+         sinfo->attrib[i].src_index = src;
       }
 
       /* Figure out if we need pointsize as well. */
@@ -151,7 +157,6 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
 
       if (vs_index >= 0) {
          softpipe->psize_slot = vs_index;
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
       }
 
       /* Figure out if we need viewport index */
@@ -160,7 +165,6 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
                                          0);
       if (vs_index >= 0) {
          softpipe->viewport_index_slot = vs_index;
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
       }
 
       /* Figure out if we need layer */
@@ -169,34 +173,25 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
                                          0);
       if (vs_index >= 0) {
          softpipe->layer_slot = vs_index;
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
       }
-
-      draw_compute_vertex_size(vinfo);
+      softpipe->setup_info.valid = 1;
    }
 
-   return vinfo;
+   return;
 }
 
 
 /**
  * Called from vbuf module.
  *
- * Note that there's actually two different vertex layouts in softpipe.
- *
- * The normal one is computed in softpipe_get_vertex_info() above and is
- * used by the point/line/tri "setup" code.
- *
- * The other one (this one) is only used by the vbuf module (which is
- * not normally used by default but used in testing).  For the vbuf module,
- * we basically want to pass-through the draw module's vertex layout as-is.
- * When the softpipe vbuf code begins drawing, the normal vertex layout
- * will come into play again.
+ * Note the vertex layout used for vbuf is simply telling it to pass
+ * through everything as is. The mapping actually used for setup is
+ * stored separately (but calculated here too at the same time).
  */
 struct vertex_info *
 softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
 {
-   (void) softpipe_get_vertex_info(softpipe);
+   softpipe_compute_vertex_info(softpipe);
    return &softpipe->vertex_info_vbuf;
 }
 
-- 
2.1.4



More information about the mesa-dev mailing list