mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 09:48:07 +02:00
etnaviv: stop caching RS clear commands on surface
As we want to get rid of the etna_surface, stop caching the (fast) clear commands for the RS engine on the surface. As the pipe_surface is no longer a CSO, we were regenerating those commands on each framebuffer state change anyway, so the additional CPU overhead of doing this for each clear shouldn't be too much worse. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35406>
This commit is contained in:
parent
6111d07048
commit
0acee3bfbf
4 changed files with 54 additions and 84 deletions
|
|
@ -181,24 +181,6 @@ etna_compile_rs_state(struct etna_context *ctx, struct compiled_rs_state *cs,
|
|||
cs->RS_KICKER_INPLACE = rs->tile_count;
|
||||
}
|
||||
cs->source_ts_valid = rs->source_ts_valid;
|
||||
cs->valid = true;
|
||||
}
|
||||
|
||||
/* modify the clear bits value in the compiled RS state */
|
||||
static void
|
||||
etna_modify_rs_clearbits(struct compiled_rs_state *cs, uint32_t clear_bits)
|
||||
{
|
||||
cs->RS_CLEAR_CONTROL &= ~VIVS_RS_CLEAR_CONTROL_BITS__MASK;
|
||||
cs->RS_CLEAR_CONTROL |= VIVS_RS_CLEAR_CONTROL_BITS(clear_bits);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_modify_rs_fill_value(struct compiled_rs_state *cs, uint64_t clear_value)
|
||||
{
|
||||
cs->RS_FILL_VALUE[0] = clear_value;
|
||||
cs->RS_FILL_VALUE[1] = clear_value >> 32;
|
||||
cs->RS_FILL_VALUE[2] = clear_value;
|
||||
cs->RS_FILL_VALUE[3] = clear_value >> 32;
|
||||
}
|
||||
|
||||
#define EMIT_STATE(state_name, src_value) \
|
||||
|
|
@ -293,14 +275,16 @@ etna_submit_rs_state(struct etna_context *ctx,
|
|||
|
||||
/* Generate clear command for a surface (non-fast clear case) */
|
||||
static void
|
||||
etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
|
||||
uint64_t clear_value)
|
||||
etna_rs_gen_clear_cmd(struct etna_context *ctx,
|
||||
struct pipe_surface *psurf, struct etna_resource *res,
|
||||
uint64_t clear_value, uint32_t clear_bits,
|
||||
struct compiled_rs_state *rs_state)
|
||||
{
|
||||
ASSERTED struct etna_screen *screen = ctx->screen;
|
||||
struct etna_resource *dst = etna_resource(surf->base.texture);
|
||||
struct etna_resource_level *level = &res->levels[psurf->level];
|
||||
uint32_t format;
|
||||
|
||||
switch (util_format_get_blocksizebits(surf->base.format)) {
|
||||
switch (util_format_get_blocksizebits(psurf->format)) {
|
||||
case 16:
|
||||
format = RS_FORMAT_A4R4G4B4;
|
||||
break;
|
||||
|
|
@ -317,22 +301,47 @@ etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
|
|||
}
|
||||
|
||||
/* use tiled clear if width is multiple of 16 */
|
||||
bool tiled_clear = (surf->level->padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
|
||||
(surf->level->padded_height & ETNA_RS_HEIGHT_MASK) == 0;
|
||||
bool tiled_clear = (level->padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
|
||||
(level->padded_height & ETNA_RS_HEIGHT_MASK) == 0;
|
||||
|
||||
etna_compile_rs_state( ctx, &surf->clear_command, &(struct rs_state) {
|
||||
etna_compile_rs_state(ctx, rs_state, &(struct rs_state) {
|
||||
.source_format = format,
|
||||
.dest_format = format,
|
||||
.dest = dst->bo,
|
||||
.dest_offset = surf->level->offset + surf->base.first_layer * surf->level->layer_stride,
|
||||
.dest_stride = surf->level->stride,
|
||||
.dest_padded_height = surf->level->padded_height,
|
||||
.dest_tiling = tiled_clear ? dst->layout : ETNA_LAYOUT_LINEAR,
|
||||
.dest = res->bo,
|
||||
.dest_offset = level->offset + psurf->first_layer * level->layer_stride,
|
||||
.dest_stride = level->stride,
|
||||
.dest_padded_height = level->padded_height,
|
||||
.dest_tiling = tiled_clear ? res->layout : ETNA_LAYOUT_LINEAR,
|
||||
.dither = {0xffffffff, 0xffffffff},
|
||||
.width = surf->level->padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */
|
||||
.height = surf->level->padded_height,
|
||||
.width = level->padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */
|
||||
.height = level->padded_height,
|
||||
.clear_value = {clear_value, clear_value >> 32, clear_value, clear_value >> 32},
|
||||
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
|
||||
.clear_bits = clear_bits
|
||||
});
|
||||
}
|
||||
|
||||
/* Generate TS clear command for a surface (fast clear case) */
|
||||
static void
|
||||
etna_rs_gen_ts_clear_cmd(struct etna_context *ctx,
|
||||
struct pipe_surface *psurf, struct etna_resource *res,
|
||||
struct compiled_rs_state *rs_state)
|
||||
{
|
||||
ASSERTED struct etna_screen *screen = ctx->screen;
|
||||
struct etna_resource_level *level = &res->levels[psurf->level];
|
||||
|
||||
etna_compile_rs_state(ctx, rs_state, &(struct rs_state) {
|
||||
.source_format = RS_FORMAT_A8R8G8B8,
|
||||
.dest_format = RS_FORMAT_A8R8G8B8,
|
||||
.dest = res->ts_bo,
|
||||
.dest_offset = level->ts_offset,
|
||||
.dest_stride = 0x40,
|
||||
.dest_tiling = ETNA_LAYOUT_TILED,
|
||||
.dither = {0xffffffff, 0xffffffff},
|
||||
.width = 16,
|
||||
.height = align(level->ts_layer_stride / 0x40, 4),
|
||||
.clear_value = {screen->specs.ts_clear_value},
|
||||
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
|
||||
.clear_bits = 0xffff
|
||||
});
|
||||
}
|
||||
|
|
@ -345,8 +354,9 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx,
|
|||
struct pipe_surface *dst = ctx->fb_cbufs[idx];
|
||||
struct etna_surface *surf = etna_surface(dst);
|
||||
uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color);
|
||||
struct compiled_rs_state rs_state;
|
||||
|
||||
if (use_ts && surf->level->ts_size) { /* TS: use precompiled clear command */
|
||||
if (use_ts && surf->level->ts_size) {
|
||||
if (idx == 0) {
|
||||
ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
|
||||
ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32;
|
||||
|
|
@ -367,24 +377,20 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx,
|
|||
etna_resource_ext_ts(etna_resource(dst->texture))))
|
||||
surf->level->ts_meta->v0.clear_value = new_clear_value;
|
||||
|
||||
assert(surf->ts_clear_command.valid);
|
||||
etna_submit_rs_state(ctx, &surf->ts_clear_command);
|
||||
etna_rs_gen_ts_clear_cmd(ctx, dst, etna_resource(dst->texture), &rs_state);
|
||||
|
||||
etna_resource_level_ts_mark_valid(surf->level);
|
||||
etna_resource_level_mark_unflushed(surf->level);
|
||||
ctx->dirty |= ETNA_DIRTY_TS;
|
||||
} else { /* Queue normal RS clear for non-TS surfaces */
|
||||
/* If no valid command yet generate stored command, otherwise simply
|
||||
* update the clear value. */
|
||||
if (unlikely(!surf->clear_command.valid))
|
||||
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
|
||||
else
|
||||
etna_modify_rs_fill_value(&surf->clear_command, new_clear_value);
|
||||
etna_rs_gen_clear_cmd(ctx, dst, etna_resource(dst->texture),
|
||||
new_clear_value, 0xffff, &rs_state);
|
||||
|
||||
etna_submit_rs_state(ctx, &surf->clear_command);
|
||||
etna_resource_level_ts_mark_invalid(surf->level);
|
||||
}
|
||||
|
||||
etna_submit_rs_state(ctx, &rs_state);
|
||||
|
||||
ctx->dirty |= ETNA_DIRTY_DERIVE_TS;
|
||||
surf->level->clear_value = new_clear_value;
|
||||
resource_written(ctx, surf->base.texture);
|
||||
|
|
@ -399,6 +405,7 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
struct etna_surface *surf = etna_surface(dst);
|
||||
uint32_t new_clear_value = translate_clear_depth_stencil(surf->base.format, depth, stencil);
|
||||
uint32_t new_clear_bits = 0, clear_bits_depth, clear_bits_stencil;
|
||||
struct compiled_rs_state rs_state;
|
||||
|
||||
/* Get the channels to clear */
|
||||
switch (surf->base.format) {
|
||||
|
|
@ -431,8 +438,7 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_DEPTH_AUTO_DISABLE;
|
||||
}
|
||||
|
||||
assert(surf->ts_clear_command.valid);
|
||||
etna_submit_rs_state(ctx, &surf->ts_clear_command);
|
||||
etna_rs_gen_ts_clear_cmd(ctx, dst, etna_resource(dst->texture), &rs_state);
|
||||
|
||||
etna_resource_level_ts_mark_valid(surf->level);
|
||||
etna_resource_level_mark_unflushed(surf->level);
|
||||
|
|
@ -443,21 +449,14 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
etna_copy_resource(pctx, surf->base.texture, surf->base.texture,
|
||||
surf->base.level, surf->base.level);
|
||||
|
||||
/* If no valid command yet generate stored command, otherwise simply
|
||||
* update clear value. */
|
||||
if (unlikely(!surf->clear_command.valid))
|
||||
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
|
||||
else
|
||||
etna_modify_rs_fill_value(&surf->clear_command, new_clear_value);
|
||||
|
||||
/* Update the channels to be cleared */
|
||||
etna_modify_rs_clearbits(&surf->clear_command, new_clear_bits);
|
||||
|
||||
etna_submit_rs_state(ctx, &surf->clear_command);
|
||||
etna_rs_gen_clear_cmd(ctx, dst, etna_resource(dst->texture),
|
||||
new_clear_value, new_clear_bits, &rs_state);
|
||||
|
||||
etna_resource_level_ts_mark_invalid(surf->level);
|
||||
}
|
||||
|
||||
etna_submit_rs_state(ctx, &rs_state);
|
||||
|
||||
surf->level->clear_value = new_clear_value;
|
||||
resource_written(ctx, surf->base.texture);
|
||||
etna_resource_level_mark_changed(surf->level);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ struct rs_state {
|
|||
|
||||
/* treat this as opaque structure */
|
||||
struct compiled_rs_state {
|
||||
uint8_t valid : 1;
|
||||
uint8_t source_ts_valid : 1;
|
||||
uint32_t RS_CONFIG;
|
||||
uint32_t RS_SOURCE_STRIDE;
|
||||
|
|
|
|||
|
|
@ -98,31 +98,6 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
|
|||
surf->base.last_layer = templat->last_layer;
|
||||
surf->level = lev;
|
||||
|
||||
if (surf->level->ts_size) {
|
||||
assert(layer == 0);
|
||||
|
||||
if (!screen->specs.use_blt) {
|
||||
/* This (ab)uses the RS as a plain buffer memset().
|
||||
* Currently uses a fixed row size of 64 bytes. Some benchmarking with
|
||||
* different sizes may be in order. */
|
||||
struct etna_bo *ts_bo = etna_resource(surf->base.texture)->ts_bo;
|
||||
etna_compile_rs_state(ctx, &surf->ts_clear_command, &(struct rs_state) {
|
||||
.source_format = RS_FORMAT_A8R8G8B8,
|
||||
.dest_format = RS_FORMAT_A8R8G8B8,
|
||||
.dest = ts_bo,
|
||||
.dest_offset = surf->level->ts_offset,
|
||||
.dest_stride = 0x40,
|
||||
.dest_tiling = ETNA_LAYOUT_TILED,
|
||||
.dither = {0xffffffff, 0xffffffff},
|
||||
.width = 16,
|
||||
.height = align(lev->ts_layer_stride / 0x40, 4),
|
||||
.clear_value = {screen->specs.ts_clear_value},
|
||||
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
|
||||
.clear_bits = 0xffff
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return &surf->base;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,9 +34,6 @@
|
|||
|
||||
struct etna_surface {
|
||||
struct pipe_surface base;
|
||||
|
||||
struct compiled_rs_state clear_command;
|
||||
struct compiled_rs_state ts_clear_command;
|
||||
/* Keep pointer to resource level, for fast clear */
|
||||
struct etna_resource_level *level;
|
||||
/* keep pointer to original resource (for when a render compatible resource is used) */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue