[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