From dfa25ea5cd19d5a050a1c94bd7370a2259b9f007 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 6 Mar 2014 18:43:44 -0500 Subject: [PATCH] gallium: allow setting of the internal stream output offset MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Roland Scheidegger Reviewed-by: Jose Fonseca Reviewed-by: Marek Olšák --- 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 2dcf01d68c4..91466842c2e 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 822e2dfa899..1aa99986f54 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 c9f933c7017..f114f503546 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 e2ff7f9fe9f..3236e523a94 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 7cef17c7cf9..bd49d0adec6 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 465013cb8f2..ccf020bed16 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 a4dc75dd71c..7d9330c745f 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 dd33eb0835b..4b25b93dd17 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 66b511eb536..1e7f374abff 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 d3401a6cd33..dad3ad2ec1d 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 64df0acb645..8e14522667a 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 fa743bd1562..2e61e5924a6 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 43dc34756e9..1b97eaa14c6 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 fa58f79c9c1..2af04cdf1c3 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 9c62c27c0a5..5cb37b656de 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 c03d72922a9..862636b9a78 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_state.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c @@ -1055,7 +1055,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; @@ -1066,7 +1066,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; @@ -1075,7 +1076,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 dec535532d8..88dbaa1113e 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -1031,7 +1031,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; @@ -1040,14 +1040,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 cbd3f0e8c64..a178e9c5719 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -413,7 +413,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 adc11e005d7..b6cf8584e2a 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 06b29d42b8b..6b0ff91c2bc 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 f456237273f..3878e4a5389 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 c10e01017fa..3e995980e92 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 0702729e36f..fe3045acb9c 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 bde00ec9996..8bb29e7d6c1 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 874ff77b50c..e3ba5a88f2d 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 97cc5a232ca..fcd7e1382be 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 90f34e39e9e..2b363615140 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 047cf47b0a4..b0a44fd901c 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 e824fe9b3cf..8f75eda8a10 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)); -- 2.30.2