summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2014-03-06 18:43:44 -0500
committerZack Rusin <zackr@vmware.com>2014-03-07 12:49:33 -0500
commitdfa25ea5cd19d5a050a1c94bd7370a2259b9f007 (patch)
tree8ce2db3ceab01311df710c2d7f307f5b708312c5
parent7d5903980ed7c4405e20dbc4f5ade9d202c559cb (diff)
downloadexternal_mesa3d-dfa25ea5cd19d5a050a1c94bd7370a2259b9f007.zip
external_mesa3d-dfa25ea5cd19d5a050a1c94bd7370a2259b9f007.tar.gz
external_mesa3d-dfa25ea5cd19d5a050a1c94bd7370a2259b9f007.tar.bz2
gallium: allow setting of the internal stream output offset
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@vmware.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com> Reviewed-by: Jose Fonseca <jfonseca@vmware.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com>
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c13
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_so_emit.c3
-rw-r--r--src/gallium/auxiliary/hud/hud_context.c2
-rw-r--r--src/gallium/auxiliary/postprocess/pp_run.c2
-rw-r--r--src/gallium/auxiliary/util/u_blit.c2
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c13
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c2
-rw-r--r--src/gallium/docs/source/context.rst9
-rw-r--r--src/gallium/drivers/galahad/glhd_context.c4
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_so.c12
-rw-r--r--src/gallium/drivers/noop/noop_state.c2
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_state.c7
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c7
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h2
-rw-r--r--src/gallium/drivers/radeon/r600_streamout.c5
-rw-r--r--src/gallium/drivers/radeonsi/si_descriptors.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_state_so.c2
-rw-r--r--src/gallium/drivers/trace/tr_context.c6
-rw-r--r--src/gallium/include/pipe/p_context.h2
-rwxr-xr-xsrc/gallium/tools/trace/dump_state.py4
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c2
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c2
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c2
-rw-r--r--src/mesa/state_tracker/st_cb_drawtex.c2
-rw-r--r--src/mesa/state_tracker/st_cb_xformfb.c20
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 c03d729..862636b 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 dec5355..88dbaa1 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 cbd3f0e..a178e9c 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 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 06b29d4..6b0ff91 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));