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 */
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;
}
pipe->set_stream_output_targets(pipe, num_targets, targets,
- append_bitmask);
+ offsets);
ctx->nr_so_targets = num_targets;
}
{
struct pipe_context *pipe = ctx->pipe;
uint i;
+ unsigned offset[PIPE_MAX_SO_BUFFERS];
if (!ctx->has_streamout) {
return;
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;
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);
* 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 );
*/
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);
*/
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);
{
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) {
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;
}
}
}
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);
/* 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);
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;
/* 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);
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,
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) {
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);
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);
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);
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);
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
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
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;
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);
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];
}
}
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)
{
}
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;
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;
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]);
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;
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]);
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);
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) {
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);
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];
*/
/* 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++) {
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;
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;
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();
}
void (*set_stream_output_targets)(struct pipe_context *,
unsigned num_targets,
struct pipe_stream_output_target **targets,
- unsigned append_bitmask);
+ const unsigned *offsets);
/*@}*/
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
}
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;
}
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);
}
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);
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 */
{
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));
}
/* 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);
}
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);
}
{
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);
}
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));