> > Though I find stream output very confusing...
> 
> I agree. I was digging a bit more and I think I was correct the first time.
> The D3D spec is very clear that "a buffer cannot be bound as both an input
> and an output at the same time", so I think the current behavior is correct,
> or at least one of the correct options given that the behavior is simply
> undefined. So I think I'm going to skip this patch, especially that is is
> subtly wrong (because it will clear so target buffers on each invocation of
> the stream output stage which isn't correct behavior since the buffers
> should only be cleared when new so targets are set).

Actually I'd just like to commit the attached patch. All it does is move
the clearing of the so targets from the drivers to the draw module. It fixes
a bug in softpipe, because softpipe would never clear the buffers and would
always append.

z
From a4a89e8f39a127474c668cb72a7db24038396731 Mon Sep 17 00:00:00 2001
From: Zack Rusin <za...@vmware.com>
Date: Thu, 13 Jun 2013 17:57:47 -0400
Subject: [PATCH] draw: clear the draw buffers in draw

Moves clearing of the draw so target buffers to the draw
module. They had to be cleared in the drivers before
which was quite messy.

Signed-off-by: Zack Rusin <za...@vmware.com>
---
 src/gallium/auxiliary/draw/draw_context.c     |   12 ++++++++++--
 src/gallium/auxiliary/draw/draw_context.h     |    3 ++-
 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 +
 8 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 22c0e9b..53f515e 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -809,12 +809,20 @@ 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;
 
-   for (i = 0; i < num_targets; i++)
+   for (i = 0; i < num_targets; i++) {
       draw->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)) && draw->so.targets[i]) {
+         draw->so.targets[i]->internal_offset = 0;
+         draw->so.targets[i]->emitted_vertices = 0;
+      }
+   }
    for (i = num_targets; i < PIPE_MAX_SO_BUFFERS; i++)
       draw->so.targets[i] = NULL;
 
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/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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to