[Mesa-dev] [PATCH] gallium: allow setting of the internal stream output offset

Marek Olšák maraeo at gmail.com
Sun Mar 9 11:42:38 PDT 2014


Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Fri, Mar 7, 2014 at 4:09 AM, Zack Rusin <zackr at vmware.com> wrote:
> (This version includes comments from Roland.)
>
> D3D10 allows setting of the internal offset of a buffer, which is
> in general only incremented via actual stream output writes. By
> allowing setting of the internal offset draw_auto is capable
> of rendering from buffers which have not been actually streamed
> out to. Our interface didn't allow. This change functionally
> shouldn't make any difference to OpenGL where instead of an
> append_bitmask you just get a real array where -1 means append
> (like in D3D) and 0 means do not append.
>
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
>  src/gallium/auxiliary/cso_cache/cso_context.c | 13 ++++++++-----
>  src/gallium/auxiliary/cso_cache/cso_context.h |  2 +-
>  src/gallium/auxiliary/draw/draw_context.h     |  3 +--
>  src/gallium/auxiliary/draw/draw_pt.c          |  8 +++++---
>  src/gallium/auxiliary/draw/draw_pt_so_emit.c  |  3 +--
>  src/gallium/auxiliary/hud/hud_context.c       |  2 +-
>  src/gallium/auxiliary/postprocess/pp_run.c    |  2 +-
>  src/gallium/auxiliary/util/u_blit.c           |  2 +-
>  src/gallium/auxiliary/util/u_blitter.c        | 13 +++++++++----
>  src/gallium/auxiliary/util/u_gen_mipmap.c     |  2 +-
>  src/gallium/docs/source/context.rst           |  9 +++++----
>  src/gallium/drivers/galahad/glhd_context.c    |  4 ++--
>  src/gallium/drivers/ilo/ilo_state.c           |  8 ++++++--
>  src/gallium/drivers/llvmpipe/lp_state_so.c    | 12 ++++++------
>  src/gallium/drivers/noop/noop_state.c         |  2 +-
>  src/gallium/drivers/nouveau/nv50/nv50_state.c |  7 ++++---
>  src/gallium/drivers/nouveau/nvc0/nvc0_state.c |  7 ++++---
>  src/gallium/drivers/radeon/r600_pipe_common.h |  2 +-
>  src/gallium/drivers/radeon/r600_streamout.c   |  5 ++++-
>  src/gallium/drivers/radeonsi/si_descriptors.c |  4 ++--
>  src/gallium/drivers/softpipe/sp_state_so.c    |  2 +-
>  src/gallium/drivers/trace/tr_context.c        |  6 +++---
>  src/gallium/include/pipe/p_context.h          |  2 +-
>  src/gallium/tools/trace/dump_state.py         |  4 ++--
>  src/mesa/state_tracker/st_cb_bitmap.c         |  2 +-
>  src/mesa/state_tracker/st_cb_clear.c          |  2 +-
>  src/mesa/state_tracker/st_cb_drawpixels.c     |  2 +-
>  src/mesa/state_tracker/st_cb_drawtex.c        |  2 +-
>  src/mesa/state_tracker/st_cb_xformfb.c        | 20 +++++++++++++-------
>  29 files changed, 88 insertions(+), 64 deletions(-)
>
> diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
> index 2dcf01d..9146684 100644
> --- a/src/gallium/auxiliary/cso_cache/cso_context.c
> +++ b/src/gallium/auxiliary/cso_cache/cso_context.c
> @@ -332,7 +332,7 @@ void cso_release_all( struct cso_context *ctx )
>        ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
>
>        if (ctx->pipe->set_stream_output_targets)
> -         ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, 0);
> +         ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, NULL);
>     }
>
>     /* free fragment sampler views */
> @@ -1241,7 +1241,7 @@ void
>  cso_set_stream_outputs(struct cso_context *ctx,
>                         unsigned num_targets,
>                         struct pipe_stream_output_target **targets,
> -                       unsigned append_bitmask)
> +                       const unsigned *offsets)
>  {
>     struct pipe_context *pipe = ctx->pipe;
>     uint i;
> @@ -1266,7 +1266,7 @@ cso_set_stream_outputs(struct cso_context *ctx,
>     }
>
>     pipe->set_stream_output_targets(pipe, num_targets, targets,
> -                                   append_bitmask);
> +                                   offsets);
>     ctx->nr_so_targets = num_targets;
>  }
>
> @@ -1292,6 +1292,7 @@ cso_restore_stream_outputs(struct cso_context *ctx)
>  {
>     struct pipe_context *pipe = ctx->pipe;
>     uint i;
> +   unsigned offset[PIPE_MAX_SO_BUFFERS];
>
>     if (!ctx->has_streamout) {
>        return;
> @@ -1302,19 +1303,21 @@ cso_restore_stream_outputs(struct cso_context *ctx)
>        return;
>     }
>
> +   assert(ctx->nr_so_targets_saved <= PIPE_MAX_SO_BUFFERS);
>     for (i = 0; i < ctx->nr_so_targets_saved; i++) {
>        pipe_so_target_reference(&ctx->so_targets[i], NULL);
>        /* move the reference from one pointer to another */
>        ctx->so_targets[i] = ctx->so_targets_saved[i];
>        ctx->so_targets_saved[i] = NULL;
> +      /* -1 means append */
> +      offset[i] = (unsigned)-1;
>     }
>     for (; i < ctx->nr_so_targets; i++) {
>        pipe_so_target_reference(&ctx->so_targets[i], NULL);
>     }
>
> -   /* ~0 means append */
>     pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved,
> -                                   ctx->so_targets, ~0);
> +                                   ctx->so_targets, offset);
>
>     ctx->nr_so_targets = ctx->nr_so_targets_saved;
>     ctx->nr_so_targets_saved = 0;
> diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
> index 822e2df..1aa9998 100644
> --- a/src/gallium/auxiliary/cso_cache/cso_context.h
> +++ b/src/gallium/auxiliary/cso_cache/cso_context.h
> @@ -115,7 +115,7 @@ unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx);
>  void cso_set_stream_outputs(struct cso_context *ctx,
>                              unsigned num_targets,
>                              struct pipe_stream_output_target **targets,
> -                            unsigned append_bitmask);
> +                            const unsigned *offsets);
>  void cso_save_stream_outputs(struct cso_context *ctx);
>  void cso_restore_stream_outputs(struct cso_context *ctx);
>
> diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
> index c9f933c..f114f50 100644
> --- a/src/gallium/auxiliary/draw/draw_context.h
> +++ b/src/gallium/auxiliary/draw/draw_context.h
> @@ -53,14 +53,13 @@ struct tgsi_sampler;
>   * structure to contain driver internal information
>   * for stream out support. mapping stores the pointer
>   * to the buffer contents, and internal offset stores
> - * stores an internal counter to how much of the stream
> + * an internal counter to how much of the stream
>   * out buffer is used (in bytes).
>   */
>  struct draw_so_target {
>     struct pipe_stream_output_target target;
>     void *mapping;
>     int internal_offset;
> -   int emitted_vertices;
>  };
>
>  struct draw_context *draw_create( struct pipe_context *pipe );
> diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
> index e2ff7f9..3236e52 100644
> --- a/src/gallium/auxiliary/draw/draw_pt.c
> +++ b/src/gallium/auxiliary/draw/draw_pt.c
> @@ -431,14 +431,16 @@ draw_pt_arrays_restart(struct draw_context *draw,
>   */
>  static void
>  resolve_draw_info(const struct pipe_draw_info *raw_info,
> -                  struct pipe_draw_info *info)
> +                  struct pipe_draw_info *info,
> +                  struct pipe_vertex_buffer *vertex_buffer)
>  {
>     memcpy(info, raw_info, sizeof(struct pipe_draw_info));
>
>     if (raw_info->count_from_stream_output) {
>        struct draw_so_target *target =
>           (struct draw_so_target *)info->count_from_stream_output;
> -      info->count = target->emitted_vertices;
> +      assert(vertex_buffer != NULL);
> +      info->count = target->internal_offset / vertex_buffer->stride;
>
>        /* Stream output draw can not be indexed */
>        debug_assert(!info->indexed);
> @@ -467,7 +469,7 @@ draw_vbo(struct draw_context *draw,
>      */
>     util_fpstate_set_denorms_to_zero(fpstate);
>
> -   resolve_draw_info(info, &resolved_info);
> +   resolve_draw_info(info, &resolved_info, &(draw->pt.vertex_buffer[0]));
>     info = &resolved_info;
>
>     assert(info->instance_count > 0);
> diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
> index 7cef17c..bd49d0a 100644
> --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
> +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
> @@ -194,7 +194,7 @@ static void so_emit_prim(struct pt_so_emit *so,
>           {
>              int j;
>              debug_printf("VERT[%d], offset = %d, slot[%d] sc = %d, num_c = %d, idx = %d = [",
> -                         i + draw->so.targets[ob]->emitted_vertices,
> +                         i,
>                           draw->so.targets[ob]->internal_offset,
>                           slot, start_comp, num_comps, idx);
>              for (j = 0; j < num_comps; ++j) {
> @@ -209,7 +209,6 @@ static void so_emit_prim(struct pt_so_emit *so,
>           struct draw_so_target *target = draw->so.targets[ob];
>           if (target && buffer_written[ob]) {
>              target->internal_offset += state->stride[ob] * sizeof(float);
> -            target->emitted_vertices += 1;
>           }
>        }
>     }
> diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
> index 465013c..ccf020b 100644
> --- a/src/gallium/auxiliary/hud/hud_context.c
> +++ b/src/gallium/auxiliary/hud/hud_context.c
> @@ -454,7 +454,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
>     cso_set_depth_stencil_alpha(cso, &hud->dsa);
>     cso_set_rasterizer(cso, &hud->rasterizer);
>     cso_set_viewport(cso, &viewport);
> -   cso_set_stream_outputs(cso, 0, NULL, 0);
> +   cso_set_stream_outputs(cso, 0, NULL, NULL);
>     cso_set_geometry_shader_handle(cso, NULL);
>     cso_set_vertex_shader_handle(cso, hud->vs);
>     cso_set_vertex_elements(cso, 2, hud->velems);
> diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
> index a4dc75d..7d9330c 100644
> --- a/src/gallium/auxiliary/postprocess/pp_run.c
> +++ b/src/gallium/auxiliary/postprocess/pp_run.c
> @@ -136,7 +136,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
>
>     /* set default state */
>     cso_set_sample_mask(cso, ~0);
> -   cso_set_stream_outputs(cso, 0, NULL, 0);
> +   cso_set_stream_outputs(cso, 0, NULL, NULL);
>     cso_set_geometry_shader_handle(cso, NULL);
>     cso_set_render_condition(cso, NULL, FALSE, 0);
>
> diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
> index dd33eb0..4b25b93 100644
> --- a/src/gallium/auxiliary/util/u_blit.c
> +++ b/src/gallium/auxiliary/util/u_blit.c
> @@ -537,7 +537,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
>     cso_set_sample_mask(ctx->cso, ~0);
>     cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
>     cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
> -   cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
> +   cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);
>
>     /* sampler */
>     ctx->sampler.normalized_coords = normalized;
> diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
> index 66b511e..1e7f374 100644
> --- a/src/gallium/auxiliary/util/u_blitter.c
> +++ b/src/gallium/auxiliary/util/u_blitter.c
> @@ -472,9 +472,12 @@ static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
>
>     /* Stream outputs. */
>     if (ctx->has_stream_out) {
> +      unsigned offsets[PIPE_MAX_SO_BUFFERS];
> +      for (i = 0; i < ctx->base.saved_num_so_targets; i++)
> +         offsets[i] = (unsigned)-1;
>        pipe->set_stream_output_targets(pipe,
>                                        ctx->base.saved_num_so_targets,
> -                                      ctx->base.saved_so_targets, ~0);
> +                                      ctx->base.saved_so_targets, offsets);
>
>        for (i = 0; i < ctx->base.saved_num_so_targets; i++)
>           pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
> @@ -1013,7 +1016,7 @@ static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
>     if (ctx->has_geometry_shader)
>        pipe->bind_gs_state(pipe, NULL);
>     if (ctx->has_stream_out)
> -      pipe->set_stream_output_targets(pipe, 0, NULL, 0);
> +      pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
>  }
>
>  static void blitter_draw(struct blitter_context_priv *ctx,
> @@ -1806,6 +1809,7 @@ void util_blitter_copy_buffer(struct blitter_context *blitter,
>     struct pipe_context *pipe = ctx->base.pipe;
>     struct pipe_vertex_buffer vb;
>     struct pipe_stream_output_target *so_target;
> +   unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
>
>     if (srcx >= src->width0 ||
>         dstx >= dst->width0) {
> @@ -1847,7 +1851,7 @@ void util_blitter_copy_buffer(struct blitter_context *blitter,
>     pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
>
>     so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
> -   pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
> +   pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
>
>     util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
>
> @@ -1867,6 +1871,7 @@ void util_blitter_clear_buffer(struct blitter_context *blitter,
>     struct pipe_context *pipe = ctx->base.pipe;
>     struct pipe_vertex_buffer vb = {0};
>     struct pipe_stream_output_target *so_target;
> +   unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
>
>     assert(num_channels >= 1);
>     assert(num_channels <= 4);
> @@ -1906,7 +1911,7 @@ void util_blitter_clear_buffer(struct blitter_context *blitter,
>     pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
>
>     so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
> -   pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
> +   pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
>
>     util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
>
> diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
> index d3401a6..dad3ad2 100644
> --- a/src/gallium/auxiliary/util/u_gen_mipmap.c
> +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
> @@ -1578,7 +1578,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
>     cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
>     cso_set_sample_mask(ctx->cso, ~0);
>     cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
> -   cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
> +   cso_set_stream_outputs(ctx->cso, 0, NULL, NULL);
>     cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
>
>     set_fragment_shader(ctx, type, is_depth);
> diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
> index 64df0ac..8e14522 100644
> --- a/src/gallium/docs/source/context.rst
> +++ b/src/gallium/docs/source/context.rst
> @@ -182,10 +182,11 @@ discussed above.
>    use pipe_so_target_reference instead.
>
>  * ``set_stream_output_targets`` binds stream output targets. The parameter
> -  append_bitmask is a bitmask, where the i-th bit specifies whether new
> -  primitives should be appended to the i-th buffer (writing starts at
> -  the internal offset), or whether writing should start at the beginning
> -  (the internal offset is effectively set to 0).
> +  offset is an array which specifies the internal offset of the buffer. The
> +  internal offset is, besides writing, used for reading the data during the
> +  draw_auto stage, i.e. it specifies how much data there is in the buffer
> +  for the purposes of the draw_auto stage. -1 means the buffer should
> +  be appended to, and everything else sets the internal offset.
>
>  NOTE: The currently-bound vertex or geometry shader must be compiled with
>  the properly-filled-in structure pipe_stream_output_info describing which
> diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
> index fa743bd..2e61e59 100644
> --- a/src/gallium/drivers/galahad/glhd_context.c
> +++ b/src/gallium/drivers/galahad/glhd_context.c
> @@ -613,12 +613,12 @@ static INLINE void
>  galahad_context_set_stream_output_targets(struct pipe_context *_pipe,
>                                            unsigned num_targets,
>                                            struct pipe_stream_output_target **tgs,
> -                                          unsigned append_bitmask)
> +                                          const unsigned *offsets)
>  {
>     struct galahad_context *glhd_pipe = galahad_context(_pipe);
>     struct pipe_context *pipe = glhd_pipe->pipe;
>
> -   pipe->set_stream_output_targets(pipe, num_targets, tgs, append_bitmask);
> +   pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
>  }
>
>  static void
> diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
> index 43dc347..1b97eaa 100644
> --- a/src/gallium/drivers/ilo/ilo_state.c
> +++ b/src/gallium/drivers/ilo/ilo_state.c
> @@ -856,10 +856,11 @@ static void
>  ilo_set_stream_output_targets(struct pipe_context *pipe,
>                                unsigned num_targets,
>                                struct pipe_stream_output_target **targets,
> -                              unsigned append_bitmask)
> +                              const unsigned *offset)
>  {
>     struct ilo_context *ilo = ilo_context(pipe);
>     unsigned i;
> +   unsigned append_bitmask = 0;
>
>     if (!targets)
>        num_targets = 0;
> @@ -868,8 +869,11 @@ ilo_set_stream_output_targets(struct pipe_context *pipe,
>     if (!ilo->so.count && !num_targets)
>        return;
>
> -   for (i = 0; i < num_targets; i++)
> +   for (i = 0; i < num_targets; i++) {
>        pipe_so_target_reference(&ilo->so.states[i], targets[i]);
> +      if (offset[i] == (unsigned)-1)
> +         append_bitmask |= 1 << i;
> +   }
>
>     for (; i < ilo->so.count; i++)
>        pipe_so_target_reference(&ilo->so.states[i], NULL);
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c b/src/gallium/drivers/llvmpipe/lp_state_so.c
> index fa58f79..2af04cd 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_so.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_so.c
> @@ -64,17 +64,17 @@ static void
>  llvmpipe_set_so_targets(struct pipe_context *pipe,
>                          unsigned num_targets,
>                          struct pipe_stream_output_target **targets,
> -                        unsigned append_bitmask)
> +                        const unsigned *offsets)
>  {
>     struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
>     int i;
>     for (i = 0; i < num_targets; i++) {
> +      const boolean append = (offsets[i] == (unsigned)-1);
>        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;
> +      /* If we're not appending then lets set the internal
> +         offset to what was requested */
> +      if (!append && llvmpipe->so_targets[i]) {
> +         llvmpipe->so_targets[i]->internal_offset = offsets[i];
>        }
>     }
>
> diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c
> index 9c62c27..5cb37b6 100644
> --- a/src/gallium/drivers/noop/noop_state.c
> +++ b/src/gallium/drivers/noop/noop_state.c
> @@ -274,7 +274,7 @@ static void noop_stream_output_target_destroy(struct pipe_context *ctx,
>  static void noop_set_stream_output_targets(struct pipe_context *ctx,
>                             unsigned num_targets,
>                             struct pipe_stream_output_target **targets,
> -                           unsigned append_bitmask)
> +                           const unsigned *offsets)
>  {
>  }
>
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c
> index 288ba46..065e10c 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c
> @@ -1051,7 +1051,7 @@ static void
>  nv50_set_stream_output_targets(struct pipe_context *pipe,
>                                 unsigned num_targets,
>                                 struct pipe_stream_output_target **targets,
> -                               unsigned append_mask)
> +                               const unsigned *offsets)
>  {
>     struct nv50_context *nv50 = nv50_context(pipe);
>     unsigned i;
> @@ -1062,7 +1062,8 @@ nv50_set_stream_output_targets(struct pipe_context *pipe,
>
>     for (i = 0; i < num_targets; ++i) {
>        const boolean changed = nv50->so_target[i] != targets[i];
> -      if (!changed && (append_mask & (1 << i)))
> +      const boolean append = (offsets[i] == (unsigned)-1);
> +      if (!changed && append)
>           continue;
>        nv50->so_targets_dirty |= 1 << i;
>
> @@ -1071,7 +1072,7 @@ nv50_set_stream_output_targets(struct pipe_context *pipe,
>           serialize = FALSE;
>        }
>
> -      if (targets[i] && !(append_mask & (1 << i)))
> +      if (targets[i] && !append)
>           nv50_so_target(targets[i])->clean = TRUE;
>
>        pipe_so_target_reference(&nv50->so_target[i], targets[i]);
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
> index 0213a8e..8fcff01 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
> @@ -1027,7 +1027,7 @@ static void
>  nvc0_set_transform_feedback_targets(struct pipe_context *pipe,
>                                      unsigned num_targets,
>                                      struct pipe_stream_output_target **targets,
> -                                    unsigned append_mask)
> +                                    unsigned *offsets)
>  {
>     struct nvc0_context *nvc0 = nvc0_context(pipe);
>     unsigned i;
> @@ -1036,14 +1036,15 @@ nvc0_set_transform_feedback_targets(struct pipe_context *pipe,
>     assert(num_targets <= 4);
>
>     for (i = 0; i < num_targets; ++i) {
> -      if (nvc0->tfbbuf[i] == targets[i] && (append_mask & (1 << i)))
> +      boolean append = (offsets[i] == ((unsigned)-1));
> +      if (nvc0->tfbbuf[i] == targets[i] && append)
>           continue;
>        nvc0->tfbbuf_dirty |= 1 << i;
>
>        if (nvc0->tfbbuf[i] && nvc0->tfbbuf[i] != targets[i])
>           nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize);
>
> -      if (targets[i] && !(append_mask & (1 << i)))
> +      if (targets[i] && !append)
>           nvc0_so_target(targets[i])->clean = TRUE;
>
>        pipe_so_target_reference(&nvc0->tfbbuf[i], targets[i]);
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index cf5aa08..b0000a0 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -397,7 +397,7 @@ void r600_streamout_buffers_dirty(struct r600_common_context *rctx);
>  void r600_set_streamout_targets(struct pipe_context *ctx,
>                                 unsigned num_targets,
>                                 struct pipe_stream_output_target **targets,
> -                               unsigned append_bitmask);
> +                               unsigned *offset);
>  void r600_emit_streamout_end(struct r600_common_context *rctx);
>  void r600_streamout_init(struct r600_common_context *rctx);
>
> diff --git a/src/gallium/drivers/radeon/r600_streamout.c b/src/gallium/drivers/radeon/r600_streamout.c
> index adc11e0..b6cf858 100644
> --- a/src/gallium/drivers/radeon/r600_streamout.c
> +++ b/src/gallium/drivers/radeon/r600_streamout.c
> @@ -108,10 +108,11 @@ void r600_streamout_buffers_dirty(struct r600_common_context *rctx)
>  void r600_set_streamout_targets(struct pipe_context *ctx,
>                                 unsigned num_targets,
>                                 struct pipe_stream_output_target **targets,
> -                               unsigned append_bitmask)
> +                               const unsigned *offsets)
>  {
>         struct r600_common_context *rctx = (struct r600_common_context *)ctx;
>         unsigned i;
> +        unsigned append_bitmask = 0;
>
>         /* Stop streamout. */
>         if (rctx->streamout.num_targets && rctx->streamout.begin_emitted) {
> @@ -122,6 +123,8 @@ void r600_set_streamout_targets(struct pipe_context *ctx,
>         for (i = 0; i < num_targets; i++) {
>                 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], targets[i]);
>                 r600_context_add_resource_size(ctx, targets[i]->buffer);
> +               if (offsets[i] == ((unsigned)-1))
> +                       append_bitmask |=  1 << i;
>         }
>         for (; i < rctx->streamout.num_targets; i++) {
>                 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], NULL);
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index 9b10d01..4925bef 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -605,7 +605,7 @@ void si_set_ring_buffer(struct pipe_context *ctx, uint shader, uint slot,
>  static void si_set_streamout_targets(struct pipe_context *ctx,
>                                      unsigned num_targets,
>                                      struct pipe_stream_output_target **targets,
> -                                    unsigned append_bitmask)
> +                                    const unsigned *offsets)
>  {
>         struct si_context *sctx = (struct si_context *)ctx;
>         struct si_buffer_resources *buffers = &sctx->rw_buffers[PIPE_SHADER_VERTEX];
> @@ -618,7 +618,7 @@ static void si_set_streamout_targets(struct pipe_context *ctx,
>          */
>
>         /* Set the VGT regs. */
> -       r600_set_streamout_targets(ctx, num_targets, targets, append_bitmask);
> +       r600_set_streamout_targets(ctx, num_targets, targets, offsets);
>
>         /* Set the shader resources.*/
>         for (i = 0; i < num_targets; i++) {
> diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
> index f456237..3878e4a 100644
> --- a/src/gallium/drivers/softpipe/sp_state_so.c
> +++ b/src/gallium/drivers/softpipe/sp_state_so.c
> @@ -63,7 +63,7 @@ static void
>  softpipe_set_so_targets(struct pipe_context *pipe,
>                          unsigned num_targets,
>                          struct pipe_stream_output_target **targets,
> -                        unsigned append_bitmask)
> +                        const unsigned *offsets)
>  {
>     struct softpipe_context *softpipe = softpipe_context(pipe);
>     unsigned i;
> diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
> index c10e010..3e99598 100644
> --- a/src/gallium/drivers/trace/tr_context.c
> +++ b/src/gallium/drivers/trace/tr_context.c
> @@ -1080,7 +1080,7 @@ static INLINE void
>  trace_context_set_stream_output_targets(struct pipe_context *_pipe,
>                                          unsigned num_targets,
>                                          struct pipe_stream_output_target **tgs,
> -                                        unsigned append_bitmask)
> +                                        const unsigned *offsets)
>  {
>     struct trace_context *tr_ctx = trace_context(_pipe);
>     struct pipe_context *pipe = tr_ctx->pipe;
> @@ -1090,9 +1090,9 @@ trace_context_set_stream_output_targets(struct pipe_context *_pipe,
>     trace_dump_arg(ptr, pipe);
>     trace_dump_arg(uint, num_targets);
>     trace_dump_arg_array(ptr, tgs, num_targets);
> -   trace_dump_arg(uint, append_bitmask);
> +   trace_dump_arg_array(uint, offsets, num_targets);
>
> -   pipe->set_stream_output_targets(pipe, num_targets, tgs, append_bitmask);
> +   pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
>
>     trace_dump_call_end();
>  }
> diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
> index 0702729..fe3045a 100644
> --- a/src/gallium/include/pipe/p_context.h
> +++ b/src/gallium/include/pipe/p_context.h
> @@ -260,7 +260,7 @@ struct pipe_context {
>     void (*set_stream_output_targets)(struct pipe_context *,
>                                unsigned num_targets,
>                                struct pipe_stream_output_target **targets,
> -                              unsigned append_bitmask);
> +                              const unsigned *offsets);
>
>     /*@}*/
>
> diff --git a/src/gallium/tools/trace/dump_state.py b/src/gallium/tools/trace/dump_state.py
> index bde00ec..8bb29e7 100755
> --- a/src/gallium/tools/trace/dump_state.py
> +++ b/src/gallium/tools/trace/dump_state.py
> @@ -536,9 +536,9 @@ class Context(Dispatcher):
>          self._state.render_condition_condition = condition
>          self._state.render_condition_mode = mode
>
> -    def set_stream_output_targets(self, num_targets, tgs, append_bitmask):
> +    def set_stream_output_targets(self, num_targets, tgs, offsets):
>          self._state.so_targets = tgs
> -        self._state.so_append_bitmask = append_bitmask
> +        self._state.offsets = offsets
>
>      def draw_vbo(self, info):
>          self._draw_no += 1
> diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
> index 874ff77..e3ba5a8 100644
> --- a/src/mesa/state_tracker/st_cb_bitmap.c
> +++ b/src/mesa/state_tracker/st_cb_bitmap.c
> @@ -513,7 +513,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
>     }
>
>     cso_set_vertex_elements(cso, 3, st->velems_util_draw);
> -   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
> +   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>
>     /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
>     z = z * 2.0f - 1.0f;
> diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
> index 97cc5a2..fcd7e13 100644
> --- a/src/mesa/state_tracker/st_cb_clear.c
> +++ b/src/mesa/state_tracker/st_cb_clear.c
> @@ -307,7 +307,7 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
>     }
>
>     cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
> -   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
> +   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>     cso_set_sample_mask(st->cso_context, ~0);
>     cso_set_rasterizer(st->cso_context, &st->clear.raster);
>
> diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
> index 90f34e3..2b36361 100644
> --- a/src/mesa/state_tracker/st_cb_drawpixels.c
> +++ b/src/mesa/state_tracker/st_cb_drawpixels.c
> @@ -788,7 +788,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
>     }
>
>     cso_set_vertex_elements(cso, 3, st->velems_util_draw);
> -   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
> +   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>
>     /* texture state: */
>     cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
> diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c
> index 047cf47..b0a44fd 100644
> --- a/src/mesa/state_tracker/st_cb_drawtex.c
> +++ b/src/mesa/state_tracker/st_cb_drawtex.c
> @@ -244,7 +244,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
>        velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
>     }
>     cso_set_vertex_elements(cso, numAttribs, velements);
> -   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
> +   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>
>     /* viewport state: viewport matching window dims */
>     {
> diff --git a/src/mesa/state_tracker/st_cb_xformfb.c b/src/mesa/state_tracker/st_cb_xformfb.c
> index e824fe9..8f75eda 100644
> --- a/src/mesa/state_tracker/st_cb_xformfb.c
> +++ b/src/mesa/state_tracker/st_cb_xformfb.c
> @@ -113,6 +113,7 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
>     struct st_transform_feedback_object *sobj =
>           st_transform_feedback_object(obj);
>     unsigned i, max_num_targets;
> +   unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
>
>     max_num_targets = MIN2(Elements(sobj->base.Buffers),
>                            Elements(sobj->targets));
> @@ -145,8 +146,8 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
>     }
>
>     /* Start writing at the beginning of each target. */
> -   cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
> -                          0);
> +   cso_set_stream_outputs(st->cso_context, sobj->num_targets,
> +                          sobj->targets, offsets);
>  }
>
>
> @@ -155,7 +156,7 @@ st_pause_transform_feedback(struct gl_context *ctx,
>                             struct gl_transform_feedback_object *obj)
>  {
>     struct st_context *st = st_context(ctx);
> -   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
> +   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>  }
>
>
> @@ -165,10 +166,15 @@ st_resume_transform_feedback(struct gl_context *ctx,
>  {
>     struct st_context *st = st_context(ctx);
>     struct st_transform_feedback_object *sobj =
> -         st_transform_feedback_object(obj);
> +      st_transform_feedback_object(obj);
> +   unsigned offsets[PIPE_MAX_SO_BUFFERS];
> +   unsigned i;
> +
> +   for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++)
> +      offsets[i] = (unsigned)-1;
>
> -   cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
> -                          ~0);
> +   cso_set_stream_outputs(st->cso_context, sobj->num_targets,
> +                          sobj->targets, offsets);
>  }
>
>
> @@ -198,7 +204,7 @@ st_end_transform_feedback(struct gl_context *ctx,
>     struct st_transform_feedback_object *sobj =
>           st_transform_feedback_object(obj);
>
> -   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
> +   cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
>
>     pipe_so_target_reference(&sobj->draw_count,
>                              st_transform_feedback_get_draw_target(obj));
> --
> 1.8.3.2
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list