Example #1
0
struct pipe_context *
fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
		const uint8_t *primtypes, void *priv)
{
	struct fd_screen *screen = fd_screen(pscreen);
	struct pipe_context *pctx;
	int i;

	ctx->screen = screen;

	ctx->primtypes = primtypes;
	ctx->primtype_mask = 0;
	for (i = 0; i < PIPE_PRIM_MAX; i++)
		if (primtypes[i])
			ctx->primtype_mask |= (1 << i);

	/* need some sane default in case state tracker doesn't
	 * set some state:
	 */
	ctx->sample_mask = 0xffff;

	pctx = &ctx->base;
	pctx->screen = pscreen;
	pctx->priv = priv;
	pctx->flush = fd_context_flush;

	for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) {
		ctx->rings[i] = fd_ringbuffer_new(screen->pipe, 0x100000);
		if (!ctx->rings[i])
			goto fail;
	}

	fd_context_next_rb(pctx);
	fd_reset_wfi(ctx);

	util_dynarray_init(&ctx->draw_patches);

	util_slab_create(&ctx->transfer_pool, sizeof(struct pipe_transfer),
			16, UTIL_SLAB_SINGLETHREADED);

	fd_draw_init(pctx);
	fd_resource_context_init(pctx);
	fd_query_context_init(pctx);
	fd_texture_init(pctx);
	fd_state_init(pctx);

	ctx->blitter = util_blitter_create(pctx);
	if (!ctx->blitter)
		goto fail;

	ctx->primconvert = util_primconvert_create(pctx, ctx->primtype_mask);
	if (!ctx->primconvert)
		goto fail;

	return pctx;

fail:
	pctx->destroy(pctx);
	return NULL;
}
Example #2
0
static void
timestamp_resume(struct fd_acc_query *aq, struct fd_batch *batch)
{
	struct fd_ringbuffer *ring = batch->draw;

	OUT_PKT7(ring, CP_EVENT_WRITE, 4);
	OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(CACHE_FLUSH_AND_INV_EVENT) |
			CP_EVENT_WRITE_0_TIMESTAMP);
	OUT_RELOCW(ring, query_sample(aq, start));
	OUT_RING(ring, 0x00000000);

	fd_reset_wfi(batch);
}
Example #3
0
static void
render_sysmem(struct fd_batch *batch)
{
	struct fd_context *ctx = batch->ctx;

	ctx->emit_sysmem_prep(batch);

	fd_hw_query_prepare_tile(batch, 0, batch->gmem);

	/* emit IB to drawcmds: */
	ctx->emit_ib(batch->gmem, batch->draw);
	fd_reset_wfi(batch);
}
Example #4
0
static void
occlusion_resume(struct fd_acc_query *aq, struct fd_batch *batch)
{
	struct fd_ringbuffer *ring = batch->draw;

	OUT_PKT4(ring, REG_A5XX_RB_SAMPLE_COUNT_CONTROL, 1);
	OUT_RING(ring, A5XX_RB_SAMPLE_COUNT_CONTROL_COPY);

	OUT_PKT4(ring, REG_A5XX_RB_SAMPLE_COUNT_ADDR_LO, 2);
	OUT_RELOCW(ring, query_sample(aq, start));

	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
	OUT_RING(ring, ZPASS_DONE);
	fd_reset_wfi(batch);

	fd5_context(batch->ctx)->samples_passed_queries++;
}
Example #5
0
static void
draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
		struct fd6_emit *emit, unsigned index_offset)
{
	const struct pipe_draw_info *info = emit->info;
	enum pc_di_primtype primtype = ctx->primtypes[info->mode];

	fd6_emit_state(ctx, ring, emit);

	if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
		fd6_emit_vertex_bufs(ring, emit);

	OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 2);
	OUT_RING(ring, info->index_size ? info->index_bias : info->start); /* VFD_INDEX_OFFSET */
	OUT_RING(ring, info->start_instance);   /* VFD_INSTANCE_START_OFFSET */

	OUT_PKT4(ring, REG_A6XX_PC_RESTART_INDEX, 1);
	OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
			info->restart_index : 0xffffffff);

	fd6_emit_render_cntl(ctx, false, emit->key.binning_pass);

	/* for debug after a lock up, write a unique counter value
	 * to scratch7 for each draw, to make it easier to match up
	 * register dumps to cmdstream.  The combination of IB
	 * (scratch6) and DRAW is enough to "triangulate" the
	 * particular draw that caused lockup.
	 */
	emit_marker6(ring, 7);

	if (info->indirect) {
		draw_emit_indirect(ctx->batch, ring, primtype,
						   emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
						   info, index_offset);
	} else {
		draw_emit(ctx->batch, ring, primtype,
				  emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
				  info, index_offset);
	}

	emit_marker6(ring, 7);
	fd_reset_wfi(ctx->batch);
}
Example #6
0
void
fd_gmem_render_tiles(struct fd_batch *batch)
{
	struct fd_context *ctx = batch->ctx;
	struct pipe_framebuffer_state *pfb = &batch->framebuffer;
	bool sysmem = false;

	if (ctx->emit_sysmem_prep) {
		if (batch->cleared || batch->gmem_reason || (batch->num_draws > 5)) {
			DBG("GMEM: cleared=%x, gmem_reason=%x, num_draws=%u",
				batch->cleared, batch->gmem_reason, batch->num_draws);
		} else if (!(fd_mesa_debug & FD_DBG_NOBYPASS)) {
			sysmem = true;
		}
	}

	fd_reset_wfi(batch);

	ctx->stats.batch_total++;

	if (sysmem) {
		DBG("%p: rendering sysmem %ux%u (%s/%s)",
			batch, pfb->width, pfb->height,
			util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
			util_format_short_name(pipe_surface_format(pfb->zsbuf)));
		fd_hw_query_prepare(batch, 1);
		render_sysmem(batch);
		ctx->stats.batch_sysmem++;
	} else {
		struct fd_gmem_stateobj *gmem = &ctx->gmem;
		calculate_tiles(batch);
		DBG("%p: rendering %dx%d tiles %ux%u (%s/%s)",
			batch, pfb->width, pfb->height, gmem->nbins_x, gmem->nbins_y,
			util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
			util_format_short_name(pipe_surface_format(pfb->zsbuf)));
		fd_hw_query_prepare(batch, gmem->nbins_x * gmem->nbins_y);
		render_tiles(batch);
		ctx->stats.batch_gmem++;
	}

	flush_ring(batch);
}
Example #7
0
static void
occlusion_pause(struct fd_acc_query *aq, struct fd_batch *batch)
{
	struct fd_ringbuffer *ring = batch->draw;

	OUT_PKT7(ring, CP_MEM_WRITE, 4);
	OUT_RELOCW(ring, query_sample(aq, stop));
	OUT_RING(ring, 0xffffffff);
	OUT_RING(ring, 0xffffffff);

	OUT_PKT7(ring, CP_WAIT_MEM_WRITES, 0);

	OUT_PKT4(ring, REG_A5XX_RB_SAMPLE_COUNT_CONTROL, 1);
	OUT_RING(ring, A5XX_RB_SAMPLE_COUNT_CONTROL_COPY);

	OUT_PKT4(ring, REG_A5XX_RB_SAMPLE_COUNT_ADDR_LO, 2);
	OUT_RELOCW(ring, query_sample(aq, stop));

	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
	OUT_RING(ring, ZPASS_DONE);
	fd_reset_wfi(batch);

	OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);
	OUT_RING(ring, 0x00000014);   // XXX
	OUT_RELOC(ring, query_sample(aq, stop));
	OUT_RING(ring, 0xffffffff);
	OUT_RING(ring, 0xffffffff);
	OUT_RING(ring, 0x00000010);   // XXX

	/* result += stop - start: */
	OUT_PKT7(ring, CP_MEM_TO_MEM, 9);
	OUT_RING(ring, CP_MEM_TO_MEM_0_DOUBLE |
			CP_MEM_TO_MEM_0_NEG_C);
	OUT_RELOCW(ring, query_sample(aq, result));     /* dst */
	OUT_RELOC(ring, query_sample(aq, result));      /* srcA */
	OUT_RELOC(ring, query_sample(aq, stop));        /* srcB */
	OUT_RELOC(ring, query_sample(aq, start));       /* srcC */

	fd5_context(batch->ctx)->samples_passed_queries--;
}
Example #8
0
static void
render_tiles(struct fd_batch *batch)
{
	struct fd_context *ctx = batch->ctx;
	struct fd_gmem_stateobj *gmem = &ctx->gmem;
	int i;

	ctx->emit_tile_init(batch);

	if (batch->restore)
		ctx->stats.batch_restore++;

	for (i = 0; i < (gmem->nbins_x * gmem->nbins_y); i++) {
		struct fd_tile *tile = &ctx->tile[i];

		DBG("bin_h=%d, yoff=%d, bin_w=%d, xoff=%d",
			tile->bin_h, tile->yoff, tile->bin_w, tile->xoff);

		ctx->emit_tile_prep(batch, tile);

		if (batch->restore) {
			ctx->emit_tile_mem2gmem(batch, tile);
		}

		ctx->emit_tile_renderprep(batch, tile);

		fd_hw_query_prepare_tile(batch, i, batch->gmem);

		/* emit IB to drawcmds: */
		ctx->emit_ib(batch->gmem, batch->draw);
		fd_reset_wfi(batch);

		/* emit gmem2mem to transfer tile back to system memory: */
		ctx->emit_tile_gmem2mem(batch, tile);
	}

	if (ctx->emit_tile_fini)
		ctx->emit_tile_fini(batch);
}
Example #9
0
static void
timestamp_pause(struct fd_acc_query *aq, struct fd_batch *batch)
{
	struct fd_ringbuffer *ring = batch->draw;

	OUT_PKT7(ring, CP_EVENT_WRITE, 4);
	OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(CACHE_FLUSH_AND_INV_EVENT) |
			CP_EVENT_WRITE_0_TIMESTAMP);
	OUT_RELOCW(ring, query_sample(aq, stop));
	OUT_RING(ring, 0x00000000);

	fd_reset_wfi(batch);
	fd_wfi(batch, ring);

	/* result += stop - start: */
	OUT_PKT7(ring, CP_MEM_TO_MEM, 9);
	OUT_RING(ring, CP_MEM_TO_MEM_0_DOUBLE |
			CP_MEM_TO_MEM_0_NEG_C);
	OUT_RELOCW(ring, query_sample(aq, result));     /* dst */
	OUT_RELOC(ring, query_sample(aq, result));      /* srcA */
	OUT_RELOC(ring, query_sample(aq, stop));        /* srcB */
	OUT_RELOC(ring, query_sample(aq, start));       /* srcC */
}