Exemple #1
0
static void r600_emit_streamout_begin(struct r600_common_context *rctx, struct r600_atom *atom)
{
	struct radeon_winsys_cs *cs = rctx->rings.gfx.cs;
	struct r600_so_target **t = rctx->streamout.targets;
	unsigned *stride_in_dw = rctx->streamout.stride_in_dw;
	unsigned i, update_flags = 0;

	r600_flush_vgt_streamout(rctx);

	if (rctx->chip_class >= EVERGREEN) {
		evergreen_set_streamout_enable(rctx, rctx->streamout.enabled_mask);
	} else {
		r600_set_streamout_enable(rctx, rctx->streamout.enabled_mask);
	}

	for (i = 0; i < rctx->streamout.num_targets; i++) {
		if (!t[i])
			continue;

		t[i]->stride_in_dw = stride_in_dw[i];

		if (rctx->chip_class >= SI) {
			/* SI binds streamout buffers as shader resources.
			 * VGT only counts primitives and tells the shader
			 * through SGPRs what to do. */
			r600_write_context_reg_seq(cs, R_028AD0_VGT_STRMOUT_BUFFER_SIZE_0 + 16*i, 2);
			radeon_emit(cs, (t[i]->b.buffer_offset +
					 t[i]->b.buffer_size) >> 2);	/* BUFFER_SIZE (in DW) */
			radeon_emit(cs, stride_in_dw[i]);		/* VTX_STRIDE (in DW) */
		} else {
Exemple #2
0
void r600_streamout_buffers_dirty(struct r600_common_context *rctx)
{
    struct r600_atom *begin = &rctx->streamout.begin_atom;
    unsigned num_bufs = util_bitcount(rctx->streamout.enabled_mask);
    unsigned num_bufs_appended = util_bitcount(rctx->streamout.enabled_mask &
                                 rctx->streamout.append_bitmask);

    if (!num_bufs)
        return;

    rctx->streamout.num_dw_for_end =
        12 + /* flush_vgt_streamout */
        num_bufs * 11; /* STRMOUT_BUFFER_UPDATE, BUFFER_SIZE */

    begin->num_dw = 12; /* flush_vgt_streamout */

    if (rctx->chip_class >= SI) {
        begin->num_dw += num_bufs * 4; /* SET_CONTEXT_REG */
    } else {
        begin->num_dw += num_bufs * 7; /* SET_CONTEXT_REG */

        if (rctx->family >= CHIP_RS780 && rctx->family <= CHIP_RV740)
            begin->num_dw += num_bufs * 5; /* STRMOUT_BASE_UPDATE */
    }

    begin->num_dw +=
        num_bufs_appended * 8 + /* STRMOUT_BUFFER_UPDATE */
        (num_bufs - num_bufs_appended) * 6 + /* STRMOUT_BUFFER_UPDATE */
        (rctx->family > CHIP_R600 && rctx->family < CHIP_RS780 ? 2 : 0); /* SURFACE_BASE_UPDATE */

    begin->dirty = true;

    r600_set_streamout_enable(rctx, true);
}
Exemple #3
0
void r600_set_streamout_targets(struct pipe_context *ctx,
				unsigned num_targets,
				struct pipe_stream_output_target **targets,
				const unsigned *offsets)
{
	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
	unsigned i;
        unsigned enabled_mask = 0, append_bitmask = 0;

	/* Stop streamout. */
	if (rctx->streamout.num_targets && rctx->streamout.begin_emitted) {
		r600_emit_streamout_end(rctx);
	}

	/* Set the new targets. */
	for (i = 0; i < num_targets; i++) {
		pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], targets[i]);
		if (!targets[i])
			continue;

		r600_context_add_resource_size(ctx, targets[i]->buffer);
		enabled_mask |= 1 << i;
		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);
	}

	rctx->streamout.enabled_mask = enabled_mask;

	rctx->streamout.num_targets = num_targets;
	rctx->streamout.append_bitmask = append_bitmask;

	if (num_targets) {
		r600_streamout_buffers_dirty(rctx);
	} else {
		rctx->set_atom_dirty(rctx, &rctx->streamout.begin_atom, false);
		r600_set_streamout_enable(rctx, false);
	}
}