Exemplo n.º 1
0
static struct pipe_stream_output_target *
r600_create_so_target(struct pipe_context *ctx,
                      struct pipe_resource *buffer,
                      unsigned buffer_offset,
                      unsigned buffer_size)
{
    struct r600_common_context *rctx = (struct r600_common_context *)ctx;
    struct r600_so_target *t;
    struct r600_resource *rbuffer = (struct r600_resource*)buffer;

    t = CALLOC_STRUCT(r600_so_target);
    if (!t) {
        return NULL;
    }

    u_suballocator_alloc(rctx->allocator_so_filled_size, 4,
                         &t->buf_filled_size_offset,
                         (struct pipe_resource**)&t->buf_filled_size);
    if (!t->buf_filled_size) {
        FREE(t);
        return NULL;
    }

    t->b.reference.count = 1;
    t->b.context = ctx;
    pipe_resource_reference(&t->b.buffer, buffer);
    t->b.buffer_offset = buffer_offset;
    t->b.buffer_size = buffer_size;

    util_range_add(&rbuffer->valid_buffer_range, buffer_offset,
                   buffer_offset + buffer_size);
    return &t->b;
}
Exemplo n.º 2
0
void r600_emit_pfp_sync_me(struct r600_context *rctx)
{
	struct radeon_winsys_cs *cs = rctx->b.gfx.cs;

	if (rctx->b.chip_class >= EVERGREEN &&
	    rctx->b.screen->info.drm_minor >= 46) {
		radeon_emit(cs, PKT3(PKT3_PFP_SYNC_ME, 0, 0));
		radeon_emit(cs, 0);
	} else {
		/* Emulate PFP_SYNC_ME by writing a value to memory in ME and
		 * waiting for it in PFP.
		 */
		struct r600_resource *buf = NULL;
		unsigned offset, reloc;
		uint64_t va;

		/* 16-byte address alignment is required by WAIT_REG_MEM. */
		u_suballocator_alloc(rctx->b.allocator_zeroed_memory, 4, 16,
				     &offset, (struct pipe_resource**)&buf);
		if (!buf) {
			/* This is too heavyweight, but will work. */
			rctx->b.gfx.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
			return;
		}

		reloc = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, buf,
						  RADEON_USAGE_READWRITE,
						  RADEON_PRIO_FENCE);

		va = buf->gpu_address + offset;
		assert(va % 16 == 0);

		/* Write 1 to memory in ME. */
		radeon_emit(cs, PKT3(PKT3_MEM_WRITE, 3, 0));
		radeon_emit(cs, va);
		radeon_emit(cs, ((va >> 32) & 0xff) | MEM_WRITE_32_BITS);
		radeon_emit(cs, 1);
		radeon_emit(cs, 0);

		radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
		radeon_emit(cs, reloc);

		/* Wait in PFP (PFP can only do GEQUAL against memory). */
		radeon_emit(cs, PKT3(PKT3_WAIT_REG_MEM, 5, 0));
		radeon_emit(cs, WAIT_REG_MEM_GEQUAL |
			        WAIT_REG_MEM_MEMORY |
			        WAIT_REG_MEM_PFP);
		radeon_emit(cs, va);
		radeon_emit(cs, va >> 32);
		radeon_emit(cs, 1); /* reference value */
		radeon_emit(cs, 0xffffffff); /* mask */
		radeon_emit(cs, 4); /* poll interval */

		radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
		radeon_emit(cs, reloc);

		r600_resource_reference(&buf, NULL);
	}
}
Exemplo n.º 3
0
static bool si_ce_upload(struct si_context *sctx, unsigned ce_offset, unsigned size,
			 unsigned *out_offset, struct r600_resource **out_buf) {
	uint64_t va;

	u_suballocator_alloc(sctx->ce_suballocator, size, out_offset,
			     (struct pipe_resource**)out_buf);
	if (!out_buf)
			return false;

	va = (*out_buf)->gpu_address + *out_offset;

	radeon_emit(sctx->ce_ib, PKT3(PKT3_DUMP_CONST_RAM, 3, 0));
	radeon_emit(sctx->ce_ib, ce_offset);
	radeon_emit(sctx->ce_ib, size / 4);
	radeon_emit(sctx->ce_ib, va);
	radeon_emit(sctx->ce_ib, va >> 32);

	radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, *out_buf,
	                       RADEON_USAGE_READWRITE, RADEON_PRIO_DESCRIPTORS);

	sctx->ce_need_synchronization = true;
	return true;
}