diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2014-07-29 18:49:28 +0200 |
---|---|---|
committer | Lucas Stach <l.stach@pengutronix.de> | 2014-07-30 12:22:54 +0200 |
commit | 6841b35cb6cd25d82b16109d099c77b2f08baa3b (patch) | |
tree | 27bbd0158d36a78707bd625d38b53d6b6eb1773c | |
parent | 77e635f9f4bc42100122263fbe2126a69583b403 (diff) | |
download | mesa-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.c | 79 |
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, ©_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, ©_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 */ } |