summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2014-07-29 18:49:28 +0200
committerLucas Stach <l.stach@pengutronix.de>2014-07-30 12:22:54 +0200
commit6841b35cb6cd25d82b16109d099c77b2f08baa3b (patch)
tree27bbd0158d36a78707bd625d38b53d6b6eb1773c
parent77e635f9f4bc42100122263fbe2126a69583b403 (diff)
downloadmesa-6841b35cb6cd25d82b16109d099c77b2f08baa3b.tar.gz
mesa-6841b35cb6cd25d82b16109d099c77b2f08baa3b.tar.xz
etna: rough cut at implementing RS blit
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--src/gallium/drivers/etna/etna_clear_blit.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/gallium/drivers/etna/etna_clear_blit.c b/src/gallium/drivers/etna/etna_clear_blit.c
index 6312a8f36a..50ff925ddd 100644
--- a/src/gallium/drivers/etna/etna_clear_blit.c
+++ b/src/gallium/drivers/etna/etna_clear_blit.c
@@ -233,6 +233,82 @@ static void etna_pipe_resource_copy_region(struct pipe_context *pipe,
etna_resource_touch(pipe, src);
}
+static bool etna_try_rs_blit(struct pipe_context *pipe,
+ const struct pipe_blit_info *blit_info)
+{
+ struct etna_pipe_context *pctx = etna_pipe_context(pipe);
+ struct etna_ctx *ectx = pctx->ctx;
+ struct etna_resource *src = etna_resource(blit_info->src.resource);
+ struct etna_resource *dst = etna_resource(blit_info->dst.resource);
+ struct compiled_rs_state copy_to_screen;
+ uint32_t ts_mem_config = 0;
+ int msaa_xscale = 1, msaa_yscale = 1;
+
+ if(!translate_samples_to_xyscale(src->base.nr_samples, &msaa_xscale,
+ &msaa_yscale, NULL))
+ return FALSE;
+
+ if (translate_rt_format(blit_info->src.format, true) == ETNA_NO_MATCH ||
+ translate_rt_format(blit_info->dst.format, true) == ETNA_NO_MATCH ||
+ blit_info->mask != PIPE_MASK_RGBA || blit_info->scissor_enable ||
+ blit_info->src.box.x != 0 || blit_info->src.box.y != 0 ||
+ blit_info->src.box.z != 0 || blit_info->dst.box.x != 0 ||
+ blit_info->dst.box.y != 0 || blit_info->dst.box.z != 0 ||
+ blit_info->dst.box.width != (blit_info->src.box.width / msaa_xscale) ||
+ blit_info->dst.box.height != (blit_info->src.box.height / msaa_yscale))
+ {
+ printf("rs blit bail out\n");
+ return FALSE;
+ }
+
+ etna_set_state(ectx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
+ etna_stall(ectx, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);
+
+ /* Set up color TS to source surface before blit, if needed */
+ if(src->base.nr_samples > 1)
+ ts_mem_config |= VIVS_TS_MEM_CONFIG_MSAA |
+ translate_msaa_format(src->base.format, false);
+ if(src->levels[blit_info->src.level].ts_size) {
+ etna_set_state_multi(ectx, VIVS_TS_MEM_CONFIG, 4, (uint32_t[]) {
+ pctx->gpu3d.TS_MEM_CONFIG = VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR | ts_mem_config,
+ pctx->gpu3d.TS_COLOR_STATUS_BASE = etna_bo_gpu_address(src->ts_bo) +
+ src->levels[blit_info->src.level].ts_offset,
+ pctx->gpu3d.TS_COLOR_SURFACE_BASE = etna_bo_gpu_address(src->bo) +
+ src->levels[blit_info->src.level].offset,
+ pctx->gpu3d.TS_COLOR_CLEAR_VALUE =
+ src->levels[blit_info->src.level].clear_value
+ });
+ } else {
+ etna_set_state(ectx, VIVS_TS_MEM_CONFIG,
+ pctx->gpu3d.TS_MEM_CONFIG = ts_mem_config);
+ }
+ pctx->dirty_bits |= ETNA_STATE_TS;
+
+ /* Kick off RS here */
+ etna_compile_rs_state(ectx, &copy_to_screen, &(struct rs_state){
+ .source_format = translate_rt_format(blit_info->src.format, false),
+ .source_tiling = src->layout,
+ .source_addr[0] = etna_get_level_pipe_addr(src, blit_info->src.level, 0),
+ .source_addr[1] = etna_get_level_pipe_addr(src, blit_info->src.level, 1),
+ .source_stride = src->levels[blit_info->src.level].stride,
+ .dest_format = translate_rt_format(blit_info->dst.format, false),
+ .dest_tiling = dst->layout,
+ .dest_addr[0] = etna_bo_gpu_address(dst->bo),
+ .dest_stride = dst->levels[blit_info->dst.level].stride,
+ .downsample_x = msaa_xscale > 1,
+ .downsample_y = msaa_yscale > 1,
+ .swap_rb = translate_rb_src_dst_swap(src->base.format, dst->base.format),
+ .dither = {0xffffffff, 0xffffffff}, // XXX dither when going from 24 to 16 bit?
+ .clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_DISABLED,
+ .width = dst->levels[blit_info->dst.level].width * msaa_xscale,
+ .height = dst->levels[blit_info->dst.level].height * msaa_yscale
+ });
+
+ etna_submit_rs_state(ectx, &copy_to_screen);
+
+ return TRUE;
+}
+
static void etna_pipe_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info)
{
/* This is a more extended version of resource_copy_region */
@@ -258,6 +334,9 @@ static void etna_pipe_blit(struct pipe_context *pipe, const struct pipe_blit_inf
DBG("color resolve unimplemented");
return;
}
+ if (etna_try_rs_blit(pipe, blit_info))
+ return;
+
if (util_try_blit_via_copy_region(pipe, blit_info)) {
return; /* done */
}