[Mesa-dev] [PATCH] draw: don't clear the so targets until we stream out

Zack Rusin zackr at vmware.com
Thu Jun 13 15:04:15 PDT 2013


Since draw auto fetches the count from the buffers, we can't
just clear them on bind, we need to wait until the actual
stream out is performed. Otherwise the count for draw auto
will be zero. Plus is cleaner to have draw do it rather
than drivers having to mess with draw's internals.

Signed-off-by: Zack Rusin <zackr at vmware.com>
---
 src/gallium/auxiliary/draw/draw_context.c     |    4 +++-
 src/gallium/auxiliary/draw/draw_context.h     |    3 ++-
 src/gallium/auxiliary/draw/draw_private.h     |    1 +
 src/gallium/auxiliary/draw/draw_pt_so_emit.c  |   20 ++++++++++++++++++++
 src/gallium/drivers/llvmpipe/lp_context.h     |    1 +
 src/gallium/drivers/llvmpipe/lp_draw_arrays.c |    4 ++--
 src/gallium/drivers/llvmpipe/lp_state_so.c    |    8 ++------
 src/gallium/drivers/softpipe/sp_context.h     |    1 +
 src/gallium/drivers/softpipe/sp_draw_arrays.c |    4 ++--
 src/gallium/drivers/softpipe/sp_state_so.c    |    1 +
 10 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 4a08765..f463739 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -810,7 +810,8 @@ draw_get_rasterizer_no_cull( struct draw_context *draw,
 void
 draw_set_mapped_so_targets(struct draw_context *draw,
                            int num_targets,
-                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS])
+                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS],
+                           unsigned append_bitmask)
 {
    int i;
 
@@ -820,6 +821,7 @@ draw_set_mapped_so_targets(struct draw_context *draw,
       draw->so.targets[i] = NULL;
 
    draw->so.num_targets = num_targets;
+   draw->so.append_bitmask = append_bitmask;
 }
 
 void
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 4a1b27e..ae63068 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -231,7 +231,8 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,
 void
 draw_set_mapped_so_targets(struct draw_context *draw,
                            int num_targets,
-                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS]);
+                           struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS],
+                           unsigned append_bitmask);
 
 
 /***********************************************************************
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index fd52c2d..4dda90e 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -290,6 +290,7 @@ struct draw_context
    struct {
       struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS];
       uint num_targets;
+      uint append_bitmask;
    } so;
 
    /* Clip derived state:
diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
index d624a99..785aa34 100644
--- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
@@ -77,6 +77,24 @@ draw_has_so(const struct draw_context *draw)
    return FALSE;
 }
 
+static void
+clean_so_buffers(struct pt_so_emit *emit)
+{
+   struct draw_context *draw = emit->draw;
+   unsigned i;
+
+   debug_assert(emit->has_so);
+
+   for (i = 0; i < draw->so.num_targets; i++) {
+      /* if we're not appending then lets reset the internal
+         data of our so target */
+      if (!(draw->so.append_bitmask & (1 << i)) && draw->so.targets[i]) {
+         draw->so.targets[i]->internal_offset = 0;
+         draw->so.targets[i]->emitted_vertices = 0;
+      }
+   }
+}
+
 void draw_pt_so_emit_prepare(struct pt_so_emit *emit, boolean use_pre_clip_pos)
 {
    struct draw_context *draw = emit->draw;
@@ -257,6 +275,8 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
    if (!draw->so.num_targets)
       return;
 
+   clean_so_buffers(emit);
+
    emit->emitted_vertices = 0;
    emit->emitted_primitives = 0;
    emit->generated_primitives = 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index abfe852..0515968 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -91,6 +91,7 @@ struct llvmpipe_context {
 
    struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS];
    int num_so_targets;
+   unsigned so_append_bitmask;
    struct pipe_query_data_so_statistics so_stats;
    unsigned num_primitives_generated;
 
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 4e23904..11b665a 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -104,7 +104,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
       }
    }
    draw_set_mapped_so_targets(draw, lp->num_so_targets,
-                              lp->so_targets);
+                              lp->so_targets, lp->so_append_bitmask);
 
    llvmpipe_prepare_vertex_sampling(lp,
                                     lp->num_sampler_views[PIPE_SHADER_VERTEX],
@@ -134,7 +134,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    if (mapped_indices) {
       draw_set_indexes(draw, NULL, 0, 0);
    }
-   draw_set_mapped_so_targets(draw, 0, NULL);
+   draw_set_mapped_so_targets(draw, 0, NULL, 0);
 
    if (lp->gs && !lp->gs->shader.tokens) {
       /* we have attached stream output to the vs for rendering,
diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c b/src/gallium/drivers/llvmpipe/lp_state_so.c
index fa58f79..c20ff26 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_so.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_so.c
@@ -70,17 +70,13 @@ llvmpipe_set_so_targets(struct pipe_context *pipe,
    int i;
    for (i = 0; i < num_targets; i++) {
       pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], targets[i]);
-      /* if we're not appending then lets reset the internal
-         data of our so target */
-      if (!(append_bitmask & (1 << i)) && llvmpipe->so_targets[i]) {
-         llvmpipe->so_targets[i]->internal_offset = 0;
-         llvmpipe->so_targets[i]->emitted_vertices = 0;
-      }
    }
 
    for (; i < llvmpipe->num_so_targets; i++) {
       pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], NULL);
    }
+
+   llvmpipe->so_append_bitmask = append_bitmask;
    llvmpipe->num_so_targets = num_targets;
 }
 
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 431864a..ea6c0f9 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -88,6 +88,7 @@ struct softpipe_context {
 
    struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS];
    unsigned num_so_targets;
+   unsigned so_append_bitmask;
    
    struct pipe_query_data_so_statistics so_stats;
    unsigned num_primitives_generated;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 45b1390..cde4d51 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -112,7 +112,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
    }
 
    draw_set_mapped_so_targets(draw, sp->num_so_targets,
-                              sp->so_targets);
+                              sp->so_targets, sp->so_append_bitmask);
 
    if (sp->gs && !sp->gs->shader.tokens) {
       /* we have an empty geometry shader with stream output, so
@@ -135,7 +135,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
       draw_set_indexes(draw, NULL, 0, 0);
    }
 
-   draw_set_mapped_so_targets(draw, 0, NULL);
+   draw_set_mapped_so_targets(draw, 0, NULL, 0);
 
    /*
     * TODO: Flush only when a user vertex/index buffer is present
diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
index 3682c6c..96bb6b1 100644
--- a/src/gallium/drivers/softpipe/sp_state_so.c
+++ b/src/gallium/drivers/softpipe/sp_state_so.c
@@ -77,6 +77,7 @@ softpipe_set_so_targets(struct pipe_context *pipe,
    }
 
    softpipe->num_so_targets = num_targets;
+   softpipe->so_append_bitmask = append_bitmask;
 }
 
 void
-- 
1.7.10.4


More information about the mesa-dev mailing list