Mesa (master): draw: fix incorrect vertex size computation in LLVM drawing code

Brian Paul brianp at kemper.freedesktop.org
Mon Jan 20 18:02:30 UTC 2014


Module: Mesa
Branch: master
Commit: ad814d04ca5d579538885a595331b5b27caefd2a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ad814d04ca5d579538885a595331b5b27caefd2a

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Jan 20 10:57:20 2014 -0800

draw: fix incorrect vertex size computation in LLVM drawing code

We were calling draw_total_vs_outputs() too early.  The call to
draw_pt_emit_prepare() could result in the vertex size changing.
So call draw_total_vs_outputs() after draw_pt_emit_prepare().

This fix would seem to be needed for the non-LLVM code as well,
but it's not obvious.  Instead, I added an assertion there to
try to catch this problem if it were to occur there.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=72926
Cc: 10.0 <mesa-stable at lists.freedesktop.org>
Reviewed-by: José Fonseca <jfonseca at vmware.com>

---

 .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c  |    7 ++--
 .../draw/draw_pt_fetch_shade_pipeline_llvm.c       |   34 ++++++++++++++------
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index a3dc8be..586d696 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -72,8 +72,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
 
    const unsigned gs_out_prim = (gs ? gs->output_primitive :
                                  u_assembled_prim(prim));
-   unsigned nr = MAX2(vs->info.num_inputs,
-                      draw_total_vs_outputs(draw));
+   unsigned nr_vs_outputs = draw_total_vs_outputs(draw);
+   unsigned nr = MAX2(vs->info.num_inputs, nr_vs_outputs);
    unsigned point_clip = draw->rasterizer->fill_front == PIPE_POLYGON_MODE_POINT ||
                          gs_out_prim == PIPE_PRIM_POINTS;
 
@@ -131,6 +131,9 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
    /* No need to prepare the shader.
     */
    vs->prepare(vs, draw);
+
+   /* Make sure that the vertex size didn't change at any point above */
+   assert(nr_vs_outputs == draw_total_vs_outputs(draw));
 }
 
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 65cb26d..49c0d4f 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -141,21 +141,13 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    struct draw_geometry_shader *gs = draw->gs.geometry_shader;
    const unsigned out_prim = gs ? gs->output_primitive :
       u_assembled_prim(in_prim);
-   const unsigned nr = MAX2(vs->info.num_inputs,
-                            draw_total_vs_outputs(draw));
    unsigned point_clip = draw->rasterizer->fill_front == PIPE_POLYGON_MODE_POINT ||
                          out_prim == PIPE_PRIM_POINTS;
+   unsigned nr;
 
    fpme->input_prim = in_prim;
    fpme->opt = opt;
 
-   /* Always leave room for the vertex header whether we need it or
-    * not.  It's hard to get rid of it in particular because of the
-    * viewport code in draw_pt_post_vs.c.
-    */
-   fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
-
-
    draw_pt_post_vs_prepare( fpme->post_vs,
                             draw->clip_xy,
                             draw->clip_z,
@@ -180,6 +172,30 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
       *max_vertices = 4096;
    }
 
+   /* Get the number of float[4] attributes per vertex.
+    * Note: this must be done after draw_pt_emit_prepare() since that
+    * can effect the vertex size.
+    */
+   nr = MAX2(vs->info.num_inputs, draw_total_vs_outputs(draw));
+
+   /* Always leave room for the vertex header whether we need it or
+    * not.  It's hard to get rid of it in particular because of the
+    * viewport code in draw_pt_post_vs.c.
+    */
+   fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
+
+   /* Get the number of float[4] attributes per vertex.
+    * Note: this must be done after draw_pt_emit_prepare() since that
+    * can effect the vertex size.
+    */
+   nr = MAX2(vs->info.num_inputs, draw_total_vs_outputs(draw));
+
+   /* Always leave room for the vertex header whether we need it or
+    * not.  It's hard to get rid of it in particular because of the
+    * viewport code in draw_pt_post_vs.c.
+    */
+   fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
+
    /* return even number */
    *max_vertices = *max_vertices & ~1;
 




More information about the mesa-commit mailing list