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>
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) |
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]);
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;
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;
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;
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;
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);
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)
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;
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)
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 */
};
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;
};
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+ */
/*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);
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;
{
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)
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
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;
/* 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]);
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 */
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);
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
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));
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;