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>
This commit is contained in:
Zack Rusin
2014-03-06 18:43:44 -05:00
parent 7d5903980e
commit dfa25ea5cd
29 changed files with 88 additions and 64 deletions

View File

@@ -332,7 +332,7 @@ void cso_release_all( struct cso_context *ctx )
ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL ); ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
if (ctx->pipe->set_stream_output_targets) 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 */ /* free fragment sampler views */
@@ -1241,7 +1241,7 @@ void
cso_set_stream_outputs(struct cso_context *ctx, cso_set_stream_outputs(struct cso_context *ctx,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct pipe_context *pipe = ctx->pipe; struct pipe_context *pipe = ctx->pipe;
uint i; uint i;
@@ -1266,7 +1266,7 @@ cso_set_stream_outputs(struct cso_context *ctx,
} }
pipe->set_stream_output_targets(pipe, num_targets, targets, pipe->set_stream_output_targets(pipe, num_targets, targets,
append_bitmask); offsets);
ctx->nr_so_targets = num_targets; ctx->nr_so_targets = num_targets;
} }
@@ -1292,6 +1292,7 @@ cso_restore_stream_outputs(struct cso_context *ctx)
{ {
struct pipe_context *pipe = ctx->pipe; struct pipe_context *pipe = ctx->pipe;
uint i; uint i;
unsigned offset[PIPE_MAX_SO_BUFFERS];
if (!ctx->has_streamout) { if (!ctx->has_streamout) {
return; return;
@@ -1302,19 +1303,21 @@ cso_restore_stream_outputs(struct cso_context *ctx)
return; return;
} }
assert(ctx->nr_so_targets_saved <= PIPE_MAX_SO_BUFFERS);
for (i = 0; i < ctx->nr_so_targets_saved; i++) { for (i = 0; i < ctx->nr_so_targets_saved; i++) {
pipe_so_target_reference(&ctx->so_targets[i], NULL); pipe_so_target_reference(&ctx->so_targets[i], NULL);
/* move the reference from one pointer to another */ /* move the reference from one pointer to another */
ctx->so_targets[i] = ctx->so_targets_saved[i]; ctx->so_targets[i] = ctx->so_targets_saved[i];
ctx->so_targets_saved[i] = NULL; ctx->so_targets_saved[i] = NULL;
/* -1 means append */
offset[i] = (unsigned)-1;
} }
for (; i < ctx->nr_so_targets; i++) { for (; i < ctx->nr_so_targets; i++) {
pipe_so_target_reference(&ctx->so_targets[i], NULL); pipe_so_target_reference(&ctx->so_targets[i], NULL);
} }
/* ~0 means append */
pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved, 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 = ctx->nr_so_targets_saved;
ctx->nr_so_targets_saved = 0; ctx->nr_so_targets_saved = 0;

View File

@@ -115,7 +115,7 @@ unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx);
void cso_set_stream_outputs(struct cso_context *ctx, void cso_set_stream_outputs(struct cso_context *ctx,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask); const unsigned *offsets);
void cso_save_stream_outputs(struct cso_context *ctx); void cso_save_stream_outputs(struct cso_context *ctx);
void cso_restore_stream_outputs(struct cso_context *ctx); void cso_restore_stream_outputs(struct cso_context *ctx);

View File

@@ -53,14 +53,13 @@ struct tgsi_sampler;
* structure to contain driver internal information * structure to contain driver internal information
* for stream out support. mapping stores the pointer * for stream out support. mapping stores the pointer
* to the buffer contents, and internal offset stores * 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). * out buffer is used (in bytes).
*/ */
struct draw_so_target { struct draw_so_target {
struct pipe_stream_output_target target; struct pipe_stream_output_target target;
void *mapping; void *mapping;
int internal_offset; int internal_offset;
int emitted_vertices;
}; };
struct draw_context *draw_create( struct pipe_context *pipe ); struct draw_context *draw_create( struct pipe_context *pipe );

View File

@@ -431,14 +431,16 @@ draw_pt_arrays_restart(struct draw_context *draw,
*/ */
static void static void
resolve_draw_info(const struct pipe_draw_info *raw_info, 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)); memcpy(info, raw_info, sizeof(struct pipe_draw_info));
if (raw_info->count_from_stream_output) { if (raw_info->count_from_stream_output) {
struct draw_so_target *target = struct draw_so_target *target =
(struct draw_so_target *)info->count_from_stream_output; (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 */ /* Stream output draw can not be indexed */
debug_assert(!info->indexed); debug_assert(!info->indexed);
@@ -467,7 +469,7 @@ draw_vbo(struct draw_context *draw,
*/ */
util_fpstate_set_denorms_to_zero(fpstate); 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; info = &resolved_info;
assert(info->instance_count > 0); assert(info->instance_count > 0);

View File

@@ -194,7 +194,7 @@ static void so_emit_prim(struct pt_so_emit *so,
{ {
int j; int j;
debug_printf("VERT[%d], offset = %d, slot[%d] sc = %d, num_c = %d, idx = %d = [", 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, draw->so.targets[ob]->internal_offset,
slot, start_comp, num_comps, idx); slot, start_comp, num_comps, idx);
for (j = 0; j < num_comps; ++j) { 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]; struct draw_so_target *target = draw->so.targets[ob];
if (target && buffer_written[ob]) { if (target && buffer_written[ob]) {
target->internal_offset += state->stride[ob] * sizeof(float); target->internal_offset += state->stride[ob] * sizeof(float);
target->emitted_vertices += 1;
} }
} }
} }

View File

@@ -454,7 +454,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
cso_set_depth_stencil_alpha(cso, &hud->dsa); cso_set_depth_stencil_alpha(cso, &hud->dsa);
cso_set_rasterizer(cso, &hud->rasterizer); cso_set_rasterizer(cso, &hud->rasterizer);
cso_set_viewport(cso, &viewport); 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_geometry_shader_handle(cso, NULL);
cso_set_vertex_shader_handle(cso, hud->vs); cso_set_vertex_shader_handle(cso, hud->vs);
cso_set_vertex_elements(cso, 2, hud->velems); cso_set_vertex_elements(cso, 2, hud->velems);

View File

@@ -136,7 +136,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
/* set default state */ /* set default state */
cso_set_sample_mask(cso, ~0); 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_geometry_shader_handle(cso, NULL);
cso_set_render_condition(cso, NULL, FALSE, 0); cso_set_render_condition(cso, NULL, FALSE, 0);

View File

@@ -537,7 +537,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_sample_mask(ctx->cso, ~0); cso_set_sample_mask(ctx->cso, ~0);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem); 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 */ /* sampler */
ctx->sampler.normalized_coords = normalized; ctx->sampler.normalized_coords = normalized;

View File

@@ -472,9 +472,12 @@ static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
/* Stream outputs. */ /* Stream outputs. */
if (ctx->has_stream_out) { 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, pipe->set_stream_output_targets(pipe,
ctx->base.saved_num_so_targets, 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++) for (i = 0; i < ctx->base.saved_num_so_targets; i++)
pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL); 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) if (ctx->has_geometry_shader)
pipe->bind_gs_state(pipe, NULL); pipe->bind_gs_state(pipe, NULL);
if (ctx->has_stream_out) 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, 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_context *pipe = ctx->base.pipe;
struct pipe_vertex_buffer vb; struct pipe_vertex_buffer vb;
struct pipe_stream_output_target *so_target; struct pipe_stream_output_target *so_target;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
if (srcx >= src->width0 || if (srcx >= src->width0 ||
dstx >= dst->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); pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
so_target = pipe->create_stream_output_target(pipe, dst, dstx, size); 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); 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_context *pipe = ctx->base.pipe;
struct pipe_vertex_buffer vb = {0}; struct pipe_vertex_buffer vb = {0};
struct pipe_stream_output_target *so_target; struct pipe_stream_output_target *so_target;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
assert(num_channels >= 1); assert(num_channels >= 1);
assert(num_channels <= 4); 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); pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
so_target = pipe->create_stream_output_target(pipe, dst, offset, size); 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); util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);

View File

@@ -1578,7 +1578,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_sample_mask(ctx->cso, ~0); cso_set_sample_mask(ctx->cso, ~0);
cso_set_vertex_elements(ctx->cso, 2, ctx->velem); 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); cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
set_fragment_shader(ctx, type, is_depth); set_fragment_shader(ctx, type, is_depth);

View File

@@ -182,10 +182,11 @@ discussed above.
use pipe_so_target_reference instead. use pipe_so_target_reference instead.
* ``set_stream_output_targets`` binds stream output targets. The parameter * ``set_stream_output_targets`` binds stream output targets. The parameter
append_bitmask is a bitmask, where the i-th bit specifies whether new offset is an array which specifies the internal offset of the buffer. The
primitives should be appended to the i-th buffer (writing starts at internal offset is, besides writing, used for reading the data during the
the internal offset), or whether writing should start at the beginning draw_auto stage, i.e. it specifies how much data there is in the buffer
(the internal offset is effectively set to 0). 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 NOTE: The currently-bound vertex or geometry shader must be compiled with
the properly-filled-in structure pipe_stream_output_info describing which the properly-filled-in structure pipe_stream_output_info describing which

View File

@@ -613,12 +613,12 @@ static INLINE void
galahad_context_set_stream_output_targets(struct pipe_context *_pipe, galahad_context_set_stream_output_targets(struct pipe_context *_pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **tgs, struct pipe_stream_output_target **tgs,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct galahad_context *glhd_pipe = galahad_context(_pipe); struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct pipe_context *pipe = glhd_pipe->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 static void

View File

@@ -856,10 +856,11 @@ static void
ilo_set_stream_output_targets(struct pipe_context *pipe, ilo_set_stream_output_targets(struct pipe_context *pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offset)
{ {
struct ilo_context *ilo = ilo_context(pipe); struct ilo_context *ilo = ilo_context(pipe);
unsigned i; unsigned i;
unsigned append_bitmask = 0;
if (!targets) if (!targets)
num_targets = 0; num_targets = 0;
@@ -868,8 +869,11 @@ ilo_set_stream_output_targets(struct pipe_context *pipe,
if (!ilo->so.count && !num_targets) if (!ilo->so.count && !num_targets)
return; 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]); 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++) for (; i < ilo->so.count; i++)
pipe_so_target_reference(&ilo->so.states[i], NULL); pipe_so_target_reference(&ilo->so.states[i], NULL);

View File

@@ -64,17 +64,17 @@ static void
llvmpipe_set_so_targets(struct pipe_context *pipe, llvmpipe_set_so_targets(struct pipe_context *pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
int i; int i;
for (i = 0; i < num_targets; 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]); 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 /* If we're not appending then lets set the internal
data of our so target */ offset to what was requested */
if (!(append_bitmask & (1 << i)) && llvmpipe->so_targets[i]) { if (!append && llvmpipe->so_targets[i]) {
llvmpipe->so_targets[i]->internal_offset = 0; llvmpipe->so_targets[i]->internal_offset = offsets[i];
llvmpipe->so_targets[i]->emitted_vertices = 0;
} }
} }

View File

@@ -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, static void noop_set_stream_output_targets(struct pipe_context *ctx,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offsets)
{ {
} }

View File

@@ -1055,7 +1055,7 @@ static void
nv50_set_stream_output_targets(struct pipe_context *pipe, nv50_set_stream_output_targets(struct pipe_context *pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_mask) const unsigned *offsets)
{ {
struct nv50_context *nv50 = nv50_context(pipe); struct nv50_context *nv50 = nv50_context(pipe);
unsigned i; unsigned i;
@@ -1066,7 +1066,8 @@ nv50_set_stream_output_targets(struct pipe_context *pipe,
for (i = 0; i < num_targets; ++i) { for (i = 0; i < num_targets; ++i) {
const boolean changed = nv50->so_target[i] != 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; continue;
nv50->so_targets_dirty |= 1 << i; nv50->so_targets_dirty |= 1 << i;
@@ -1075,7 +1076,7 @@ nv50_set_stream_output_targets(struct pipe_context *pipe,
serialize = FALSE; serialize = FALSE;
} }
if (targets[i] && !(append_mask & (1 << i))) if (targets[i] && !append)
nv50_so_target(targets[i])->clean = TRUE; nv50_so_target(targets[i])->clean = TRUE;
pipe_so_target_reference(&nv50->so_target[i], targets[i]); pipe_so_target_reference(&nv50->so_target[i], targets[i]);

View File

@@ -1031,7 +1031,7 @@ static void
nvc0_set_transform_feedback_targets(struct pipe_context *pipe, nvc0_set_transform_feedback_targets(struct pipe_context *pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_mask) unsigned *offsets)
{ {
struct nvc0_context *nvc0 = nvc0_context(pipe); struct nvc0_context *nvc0 = nvc0_context(pipe);
unsigned i; unsigned i;
@@ -1040,14 +1040,15 @@ nvc0_set_transform_feedback_targets(struct pipe_context *pipe,
assert(num_targets <= 4); assert(num_targets <= 4);
for (i = 0; i < num_targets; ++i) { 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; continue;
nvc0->tfbbuf_dirty |= 1 << i; nvc0->tfbbuf_dirty |= 1 << i;
if (nvc0->tfbbuf[i] && nvc0->tfbbuf[i] != targets[i]) if (nvc0->tfbbuf[i] && nvc0->tfbbuf[i] != targets[i])
nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize); 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; nvc0_so_target(targets[i])->clean = TRUE;
pipe_so_target_reference(&nvc0->tfbbuf[i], targets[i]); pipe_so_target_reference(&nvc0->tfbbuf[i], targets[i]);

View File

@@ -413,7 +413,7 @@ void r600_streamout_buffers_dirty(struct r600_common_context *rctx);
void r600_set_streamout_targets(struct pipe_context *ctx, void r600_set_streamout_targets(struct pipe_context *ctx,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask); unsigned *offset);
void r600_emit_streamout_end(struct r600_common_context *rctx); void r600_emit_streamout_end(struct r600_common_context *rctx);
void r600_streamout_init(struct r600_common_context *rctx); void r600_streamout_init(struct r600_common_context *rctx);

View File

@@ -108,10 +108,11 @@ void r600_streamout_buffers_dirty(struct r600_common_context *rctx)
void r600_set_streamout_targets(struct pipe_context *ctx, void r600_set_streamout_targets(struct pipe_context *ctx,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct r600_common_context *rctx = (struct r600_common_context *)ctx; struct r600_common_context *rctx = (struct r600_common_context *)ctx;
unsigned i; unsigned i;
unsigned append_bitmask = 0;
/* Stop streamout. */ /* Stop streamout. */
if (rctx->streamout.num_targets && rctx->streamout.begin_emitted) { 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++) { for (i = 0; i < num_targets; i++) {
pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], 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); 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++) { for (; i < rctx->streamout.num_targets; i++) {
pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], NULL); pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], NULL);

View File

@@ -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, static void si_set_streamout_targets(struct pipe_context *ctx,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct si_context *sctx = (struct si_context *)ctx; struct si_context *sctx = (struct si_context *)ctx;
struct si_buffer_resources *buffers = &sctx->rw_buffers[PIPE_SHADER_VERTEX]; 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. */ /* 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.*/ /* Set the shader resources.*/
for (i = 0; i < num_targets; i++) { for (i = 0; i < num_targets; i++) {

View File

@@ -63,7 +63,7 @@ static void
softpipe_set_so_targets(struct pipe_context *pipe, softpipe_set_so_targets(struct pipe_context *pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct softpipe_context *softpipe = softpipe_context(pipe); struct softpipe_context *softpipe = softpipe_context(pipe);
unsigned i; unsigned i;

View File

@@ -1080,7 +1080,7 @@ static INLINE void
trace_context_set_stream_output_targets(struct pipe_context *_pipe, trace_context_set_stream_output_targets(struct pipe_context *_pipe,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **tgs, struct pipe_stream_output_target **tgs,
unsigned append_bitmask) const unsigned *offsets)
{ {
struct trace_context *tr_ctx = trace_context(_pipe); struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->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(ptr, pipe);
trace_dump_arg(uint, num_targets); trace_dump_arg(uint, num_targets);
trace_dump_arg_array(ptr, tgs, 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(); trace_dump_call_end();
} }

View File

@@ -260,7 +260,7 @@ struct pipe_context {
void (*set_stream_output_targets)(struct pipe_context *, void (*set_stream_output_targets)(struct pipe_context *,
unsigned num_targets, unsigned num_targets,
struct pipe_stream_output_target **targets, struct pipe_stream_output_target **targets,
unsigned append_bitmask); const unsigned *offsets);
/*@}*/ /*@}*/

View File

@@ -536,9 +536,9 @@ class Context(Dispatcher):
self._state.render_condition_condition = condition self._state.render_condition_condition = condition
self._state.render_condition_mode = mode 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_targets = tgs
self._state.so_append_bitmask = append_bitmask self._state.offsets = offsets
def draw_vbo(self, info): def draw_vbo(self, info):
self._draw_no += 1 self._draw_no += 1

View File

@@ -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_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 */ /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
z = z * 2.0f - 1.0f; z = z * 2.0f - 1.0f;

View File

@@ -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_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_sample_mask(st->cso_context, ~0);
cso_set_rasterizer(st->cso_context, &st->clear.raster); cso_set_rasterizer(st->cso_context, &st->clear.raster);

View File

@@ -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_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: */ /* texture state: */
cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv); cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);

View File

@@ -244,7 +244,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
} }
cso_set_vertex_elements(cso, numAttribs, velements); 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 */ /* viewport state: viewport matching window dims */
{ {

View File

@@ -113,6 +113,7 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
struct st_transform_feedback_object *sobj = struct st_transform_feedback_object *sobj =
st_transform_feedback_object(obj); st_transform_feedback_object(obj);
unsigned i, max_num_targets; unsigned i, max_num_targets;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
max_num_targets = MIN2(Elements(sobj->base.Buffers), max_num_targets = MIN2(Elements(sobj->base.Buffers),
Elements(sobj->targets)); 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. */ /* Start writing at the beginning of each target. */
cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets, cso_set_stream_outputs(st->cso_context, sobj->num_targets,
0); sobj->targets, offsets);
} }
@@ -155,7 +156,7 @@ st_pause_transform_feedback(struct gl_context *ctx,
struct gl_transform_feedback_object *obj) struct gl_transform_feedback_object *obj)
{ {
struct st_context *st = st_context(ctx); 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_context *st = st_context(ctx);
struct st_transform_feedback_object *sobj = struct st_transform_feedback_object *sobj =
st_transform_feedback_object(obj); st_transform_feedback_object(obj);
unsigned offsets[PIPE_MAX_SO_BUFFERS];
unsigned i;
cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets, for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++)
~0); offsets[i] = (unsigned)-1;
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 = struct st_transform_feedback_object *sobj =
st_transform_feedback_object(obj); 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, pipe_so_target_reference(&sobj->draw_count,
st_transform_feedback_get_draw_target(obj)); st_transform_feedback_get_draw_target(obj));