diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.c b/src/gallium/drivers/etnaviv/etnaviv_blt.c index 5cc6b8dd8b2..e0274a5b599 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blt.c +++ b/src/gallium/drivers/etnaviv/etnaviv_blt.c @@ -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) diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.h b/src/gallium/drivers/etnaviv/etnaviv_blt.h index 868440828ac..8bbc6c5e875 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blt.h +++ b/src/gallium/drivers/etnaviv/etnaviv_blt.h @@ -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; }; diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index b0a56c6c9b9..8aabbe6e944 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -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+ */ diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c index ee54daabf3e..7c954732368 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c @@ -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); diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h index e2f701c3bc9..c00101732e2 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h @@ -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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 6607e792f46..3cf45b6c803 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -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 diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h index 2938ffa9170..c2ad10fddc9 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.h +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h @@ -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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index e23722b0d2f..a63350993fe 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -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 diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c index 58cca3c9ffb..6965ee001ea 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture.c +++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c @@ -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)); diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.h b/src/gallium/drivers/etnaviv/etnaviv_texture.h index 4d66a9f3948..e982ee551db 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture.h +++ b/src/gallium/drivers/etnaviv/etnaviv_texture.h @@ -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;