etnaviv: implement TS_MODE for GC7000L

GC7000L has a TS mode with larger tiles, which improves performance.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
Jonathan Marek 2019-07-01 16:16:54 -04:00
parent bc5ae6a330
commit 95d937852e
10 changed files with 35 additions and 12 deletions

View File

@ -68,7 +68,7 @@ blt_compute_img_config_bits(const struct blt_imginfo *img, bool for_dest)
tiling_bits |= for_dest ? BLT_IMAGE_CONFIG_TO_SUPER_TILED : BLT_IMAGE_CONFIG_FROM_SUPER_TILED;
}
return BLT_IMAGE_CONFIG_TS_MODE(img->cache_mode) |
return BLT_IMAGE_CONFIG_TS_MODE(img->ts_mode) |
COND(img->use_ts, BLT_IMAGE_CONFIG_TS) |
COND(img->compressed, BLT_IMAGE_CONFIG_COMPRESSION) |
BLT_IMAGE_CONFIG_COMPRESSION_FORMAT(img->compress_fmt) |
@ -182,7 +182,7 @@ emit_blt_inplace(struct etna_cmd_stream *stream, const struct blt_inplace_op *op
etna_cmd_stream_reserve(stream, 64*2); /* Never allow BLT sequences to be broken up */
etna_set_state(stream, VIVS_BLT_ENABLE, 0x00000001);
etna_set_state(stream, VIVS_BLT_CONFIG,
VIVS_BLT_CONFIG_INPLACE_TS_MODE(op->cache_mode) |
VIVS_BLT_CONFIG_INPLACE_TS_MODE(op->ts_mode) |
VIVS_BLT_CONFIG_INPLACE_BOTH |
(util_logbase2(op->bpp) << VIVS_BLT_CONFIG_INPLACE_BPP__SHIFT));
etna_set_state(stream, VIVS_BLT_DEST_TS_CLEAR_VALUE0, op->ts_clear_value[0]);
@ -216,7 +216,6 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
clr.dest.compress_fmt = 3;
*/
clr.dest.tiling = res->layout;
clr.dest.cache_mode = TS_MODE_32; /* TODO: cache modes */
if (surf->surf.ts_size) {
clr.dest.use_ts = 1;
@ -225,6 +224,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
clr.dest.ts_addr.flags = ETNA_RELOC_WRITE;
clr.dest.ts_clear_value[0] = new_clear_value;
clr.dest.ts_clear_value[1] = new_clear_value;
clr.dest.ts_mode = surf->level->ts_mode;
}
clr.clear_value[0] = new_clear_value;
@ -292,7 +292,6 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
clr.dest.compress_fmt = COLOR_COMPRESSION_FORMAT_D24S8;
#endif
clr.dest.tiling = res->layout;
clr.dest.cache_mode = TS_MODE_32; /* TODO: cache modes */
if (surf->surf.ts_size) {
clr.dest.use_ts = 1;
@ -301,6 +300,7 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
clr.dest.ts_addr.flags = ETNA_RELOC_WRITE;
clr.dest.ts_clear_value[0] = new_clear_value;
clr.dest.ts_clear_value[1] = new_clear_value;
clr.dest.ts_mode = surf->level->ts_mode;
}
clr.clear_value[0] = new_clear_value;
@ -434,8 +434,8 @@ etna_try_blt_blit(struct pipe_context *pctx,
op.ts_addr.flags = ETNA_RELOC_READ;
op.ts_clear_value[0] = src_lev->clear_value;
op.ts_clear_value[1] = src_lev->clear_value;
op.cache_mode = TS_MODE_32; /* TODO: cache modes */
op.num_tiles = src_lev->size / 128; /* TODO: cache modes */
op.ts_mode = src_lev->ts_mode;
op.num_tiles = DIV_ROUND_UP(src_lev->size, src_lev->ts_mode ? 256 : 128);
op.bpp = util_format_get_blocksize(src->base.format);
etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, 0x00000c23);
@ -451,7 +451,6 @@ etna_try_blt_blit(struct pipe_context *pctx,
op.src.format = translate_blt_format(src_format);
op.src.stride = src_lev->stride;
op.src.tiling = src->layout;
op.src.cache_mode = TS_MODE_32; /* TODO: cache modes */
const struct util_format_description *src_format_desc =
util_format_description(src_format);
for (unsigned x=0; x<4; ++x)
@ -464,6 +463,7 @@ etna_try_blt_blit(struct pipe_context *pctx,
op.src.ts_addr.flags = ETNA_RELOC_READ;
op.src.ts_clear_value[0] = src_lev->clear_value;
op.src.ts_clear_value[1] = src_lev->clear_value;
op.src.ts_mode = src_lev->ts_mode;
}
op.dest.addr.bo = dst->bo;
@ -476,7 +476,6 @@ etna_try_blt_blit(struct pipe_context *pctx,
op.dest.compress_fmt = 3;
*/
op.dest.tiling = dst->layout;
op.dest.cache_mode = TS_MODE_32; /* TODO cache modes */
const struct util_format_description *dst_format_desc =
util_format_description(dst_format);
for (unsigned x=0; x<4; ++x)

View File

@ -47,7 +47,7 @@ struct blt_imginfo
enum etna_surface_layout tiling; /* ETNA_LAYOUT_* */
uint32_t ts_clear_value[2];
uint8_t swizzle[4]; /* TEXTURE_SWIZZLE_* */
uint8_t cache_mode; /* TS_CACHE_MODE_* */
uint8_t ts_mode; /* TS_MODE_* */
uint8_t endian_mode; /* ENDIAN_MODE_* */
uint8_t bpp; /* # bytes per pixel 1/2/4/8 - only used for CLEAR_IMAGE */
};
@ -89,7 +89,7 @@ struct blt_inplace_op
struct etna_reloc ts_addr;
uint32_t ts_clear_value[2];
uint32_t num_tiles;
uint8_t cache_mode; /* TS_CACHE_MODE_* */
uint8_t ts_mode; /* TS_MODE_* */
uint8_t bpp;
};

View File

@ -356,7 +356,6 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
etna_set_state(stream, VIVS_RA_UNK00E0C, 0x00000000);
}
if (ctx->specs.halti >= 3) { /* Only on HALTI3+ */
etna_set_state(stream, VIVS_PE_MEM_CONFIG, 0x00000000); /* TODO: cache modes */
etna_set_state(stream, VIVS_PS_HALTI3_UNK0103C, 0x76543210);
}
if (ctx->specs.halti >= 4) { /* Only on HALTI4+ */

View File

@ -531,6 +531,10 @@ etna_emit_state(struct etna_context *ctx)
/*014A8*/ EMIT_STATE(PE_DITHER(x), blend->PE_DITHER[x]);
}
}
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER)) && ctx->specs.halti >= 3)
/*014BC*/ EMIT_STATE(PE_MEM_CONFIG, ctx->framebuffer.PE_MEM_CONFIG);
if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_TS))) {
/*01654*/ EMIT_STATE(TS_MEM_CONFIG, ctx->framebuffer.TS_MEM_CONFIG);
/*01658*/ EMIT_STATE_RELOC(TS_COLOR_STATUS_BASE, &ctx->framebuffer.TS_COLOR_STATUS_BASE);

View File

@ -193,6 +193,7 @@ struct compiled_framebuffer_state {
struct etna_reloc PE_COLOR_ADDR;
struct etna_reloc PE_PIPE_COLOR_ADDR[ETNA_MAX_PIXELPIPES];
uint32_t PE_COLOR_STRIDE;
uint32_t PE_MEM_CONFIG;
uint32_t SE_SCISSOR_LEFT;
uint32_t SE_SCISSOR_TOP;
uint32_t SE_SCISSOR_RIGHT;

View File

@ -85,11 +85,21 @@ etna_screen_resource_alloc_ts(struct pipe_screen *pscreen,
{
struct etna_screen *screen = etna_screen(pscreen);
size_t rt_ts_size, ts_layer_stride;
size_t ts_bits_per_tile, bytes_per_tile;
uint8_t ts_mode = TS_MODE_128B; /* only used by halti5 */
assert(!rsc->ts_bo);
if (screen->specs.halti >= 5) {
ts_bits_per_tile = 4;
bytes_per_tile = ts_mode == TS_MODE_256B ? 256 : 128;
} else {
ts_bits_per_tile = screen->specs.bits_per_tile;
bytes_per_tile = 64;
}
ts_layer_stride = align(DIV_ROUND_UP(rsc->levels[0].layer_stride,
64 * 8 / screen->specs.bits_per_tile),
bytes_per_tile * 8 / ts_bits_per_tile),
0x100 * screen->specs.pixel_pipes);
rt_ts_size = ts_layer_stride * rsc->base.array_size;
if (rt_ts_size == 0)
@ -110,6 +120,7 @@ etna_screen_resource_alloc_ts(struct pipe_screen *pscreen,
rsc->levels[0].ts_offset = 0;
rsc->levels[0].ts_layer_stride = ts_layer_stride;
rsc->levels[0].ts_size = rt_ts_size;
rsc->levels[0].ts_mode = ts_mode;
/* It is important to initialize the TS, as random pattern
* can result in crashes. Do this on the CPU as this only happens once

View File

@ -51,6 +51,7 @@ struct etna_resource_level {
uint32_t ts_size;
uint32_t clear_value; /* clear value of resource level (mainly for TS) */
bool ts_valid;
uint8_t ts_mode;
/* keep track if we have done some per block patching */
bool patched;

View File

@ -122,6 +122,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
/* Set up TS as well. Warning: this state is used by both the RS and PE */
uint32_t ts_mem_config = 0;
uint32_t pe_mem_config = 0;
if (sv->nr_cbufs > 0) { /* at least one color buffer? */
struct etna_surface *cbuf = etna_surface(sv->cbufs[0]);
@ -173,6 +174,8 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
cs->TS_COLOR_SURFACE_BASE = cbuf->reloc[0];
cs->TS_COLOR_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
pe_mem_config |= VIVS_PE_MEM_CONFIG_COLOR_TS_MODE(cbuf->level->ts_mode);
}
/* MSAA */
@ -239,6 +242,8 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
cs->TS_DEPTH_SURFACE_BASE = zsbuf->reloc[0];
cs->TS_DEPTH_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
pe_mem_config |= VIVS_PE_MEM_CONFIG_DEPTH_TS_MODE(zsbuf->level->ts_mode);
}
ts_mem_config |= COND(depth_bits == 16, VIVS_TS_MEM_CONFIG_DEPTH_16BPP);
@ -316,6 +321,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
cs->SE_CLIP_BOTTOM = (sv->height << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM;
cs->TS_MEM_CONFIG = ts_mem_config;
cs->PE_MEM_CONFIG = pe_mem_config;
/* Single buffer setup. There is only one switch for this, not a separate
* one per color buffer / depth buffer. To keep the logic simple always use

View File

@ -83,6 +83,7 @@ etna_configure_sampler_ts(struct etna_sampler_ts *sts, struct pipe_sampler_view
struct etna_resource_level *lev = &rsc->levels[0];
assert(rsc->ts_bo && lev->ts_valid);
sts->mode = lev->ts_mode;
sts->TS_SAMPLER_CONFIG =
VIVS_TS_SAMPLER_CONFIG_ENABLE |
VIVS_TS_SAMPLER_CONFIG_COMPRESSION_FORMAT(translate_ts_sampler_format(rsc->base.format));

View File

@ -36,6 +36,7 @@ struct etna_context;
struct etna_sampler_ts {
unsigned enable:1;
unsigned mode:1;
uint32_t TS_SAMPLER_CONFIG;
struct etna_reloc TS_SAMPLER_STATUS_BASE;
uint32_t TS_SAMPLER_CLEAR_VALUE;