softpipe: don't abuse the draw vertex_info struct for something different
authorRoland Scheidegger <sroland@vmware.com>
Sat, 19 Dec 2015 02:37:17 +0000 (03:37 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Thu, 7 Jan 2016 00:57:21 +0000 (01:57 +0100)
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.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Edward O'Callaghan <eocallaghan@alterapraxis.com>
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_setup.c
src/gallium/drivers/softpipe/sp_setup.h
src/gallium/drivers/softpipe/sp_state.h
src/gallium/drivers/softpipe/sp_state_derived.c

index 8e5e24217a5213dac45ef63837a24c26961325d6..188cdeaf76f6e6bcf184137e7d07bf4f85b582e9 100644 (file)
@@ -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 */
index ac2d97825ce9c9406b7a22adcbfc8d66ddc92142..28f163b4d8f075a2ce67380479759699b8bf1932 100644 (file)
@@ -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:
index 191494acbb83ca73cc831fb43cd2e2091232f404..8bb50b98fecd96818ddd79407085de1b2b78f76d 100644 (file)
 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,
index c35534c931d398dab780e3f5d7816d42def61e87..16a2897f52663074428f0f0233f3d6ce78b84512 100644 (file)
@@ -174,9 +174,6 @@ void
 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);
 
index 56ecc3b6140882d2407790d3d6c0709589d45485..3fb1daee2c1b5bb9d0375e83371f81c118f03fe5 100644 (file)
@@ -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;
 }