From 5159db60fccf17b00b8da4257dac027b6e2327ef Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Mon, 12 Aug 2019 11:43:26 -0400 Subject: [PATCH] etnaviv: implement 64bpp clear At the same time, update etna_clear_blit_pack_rgba to work with integer formats. Signed-off-by: Jonathan Marek Reviewed-by: Christian Gmeiner --- src/gallium/drivers/etnaviv/etnaviv_blt.c | 7 +++-- .../drivers/etnaviv/etnaviv_clear_blit.c | 28 ++++++++++++++----- .../drivers/etnaviv/etnaviv_clear_blit.h | 6 ++-- src/gallium/drivers/etnaviv/etnaviv_emit.c | 1 + .../drivers/etnaviv/etnaviv_internal.h | 1 + .../drivers/etnaviv/etnaviv_resource.h | 2 +- src/gallium/drivers/etnaviv/etnaviv_rs.c | 8 ++++-- src/gallium/drivers/etnaviv/etnaviv_state.c | 1 + src/gallium/drivers/etnaviv/etnaviv_surface.c | 4 ++- src/gallium/drivers/etnaviv/etnaviv_texture.c | 2 +- 10 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.c b/src/gallium/drivers/etnaviv/etnaviv_blt.c index 7266505eb4f..08f74035c06 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blt.c +++ b/src/gallium/drivers/etnaviv/etnaviv_blt.c @@ -215,7 +215,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst, { struct etna_context *ctx = etna_context(pctx); struct etna_surface *surf = etna_surface(dst); - uint32_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color->f); + uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color); struct etna_resource *res = etna_resource(surf->base.texture); struct blt_clear_op clr = {}; @@ -232,13 +232,13 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst, clr.dest.ts_addr.offset = 0; 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_clear_value[1] = new_clear_value >> 32; clr.dest.ts_mode = surf->level->ts_mode; clr.dest.ts_compress_fmt = surf->level->ts_compress_fmt; } clr.clear_value[0] = new_clear_value; - clr.clear_value[1] = new_clear_value; + clr.clear_value[1] = new_clear_value >> 32; clr.clear_bits[0] = 0xffffffff; /* TODO: Might want to clear only specific channels? */ clr.clear_bits[1] = 0xffffffff; clr.rect_x = 0; /* What about scissors? */ @@ -251,6 +251,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst, /* This made the TS valid */ if (surf->surf.ts_size) { ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value; + ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32; surf->level->ts_valid = true; ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS; } diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c index 51d16aa19f7..42dc50e2dff 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c @@ -66,15 +66,29 @@ etna_blit_save_state(struct etna_context *ctx) ctx->num_fragment_sampler_views, ctx->sampler_view); } -uint32_t -etna_clear_blit_pack_rgba(enum pipe_format format, const float *rgba) +uint64_t +etna_clear_blit_pack_rgba(enum pipe_format format, const union pipe_color_union *color) { union util_color uc; - util_pack_color(rgba, format, &uc); - if (util_format_get_blocksize(format) == 2) - return uc.ui[0] << 16 | (uc.ui[0] & 0xffff); - else - return uc.ui[0]; + + if (util_format_is_pure_uint(format)) { + util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1); + } else if (util_format_is_pure_sint(format)) { + util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1); + } else { + util_pack_color(color->f, format, &uc); + } + + switch (util_format_get_blocksize(format)) { + case 1: + uc.ui[0] = uc.ui[0] << 8 | (uc.ui[0] & 0xff); + case 2: + uc.ui[0] = uc.ui[0] << 16 | (uc.ui[0] & 0xffff); + case 4: + uc.ui[1] = uc.ui[0]; + default: + return (uint64_t) uc.ui[1] << 32 | uc.ui[0]; + } } static void diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h index 05a7b64a9f8..2249a5b12e0 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h @@ -36,7 +36,7 @@ struct etna_surface; void etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf, - uint32_t clear_value); + uint64_t clear_value); void etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst, @@ -50,8 +50,8 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst, void etna_blit_save_state(struct etna_context *ctx); -uint32_t -etna_clear_blit_pack_rgba(enum pipe_format format, const float *rgba); +uint64_t +etna_clear_blit_pack_rgba(enum pipe_format format, const union pipe_color_union *color); void etna_clear_blit_init(struct pipe_context *pctx); diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c index 6d8dd349f84..ba3d8c021e7 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c @@ -545,6 +545,7 @@ etna_emit_state(struct etna_context *ctx) /*01664*/ EMIT_STATE_RELOC(TS_DEPTH_STATUS_BASE, &ctx->framebuffer.TS_DEPTH_STATUS_BASE); /*01668*/ EMIT_STATE_RELOC(TS_DEPTH_SURFACE_BASE, &ctx->framebuffer.TS_DEPTH_SURFACE_BASE); /*0166C*/ EMIT_STATE(TS_DEPTH_CLEAR_VALUE, ctx->framebuffer.TS_DEPTH_CLEAR_VALUE); + /*016BC*/ EMIT_STATE(TS_COLOR_CLEAR_VALUE_EXT, ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT); } if (unlikely(dirty & (ETNA_DIRTY_SHADER))) { /*0381C*/ EMIT_STATE(GL_VARYING_TOTAL_COMPONENTS, ctx->shader_state.GL_VARYING_TOTAL_COMPONENTS); diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h index e5a5b590efa..8655eac53c3 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h @@ -212,6 +212,7 @@ struct compiled_framebuffer_state { struct etna_reloc TS_DEPTH_STATUS_BASE; struct etna_reloc TS_DEPTH_SURFACE_BASE; uint32_t TS_COLOR_CLEAR_VALUE; + uint32_t TS_COLOR_CLEAR_VALUE_EXT; struct etna_reloc TS_COLOR_STATUS_BASE; struct etna_reloc TS_COLOR_SURFACE_BASE; uint32_t PE_LOGIC_OP; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h index 51e54074139..1da0315ab9e 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.h +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h @@ -52,7 +52,7 @@ struct etna_resource_level { uint32_t ts_offset; uint32_t ts_layer_stride; uint32_t ts_size; - uint32_t clear_value; /* clear value of resource level (mainly for TS) */ + uint64_t clear_value; /* clear value of resource level (mainly for TS) */ bool ts_valid; uint8_t ts_mode; int8_t ts_compress_fmt; /* COLOR_COMPRESSION_FORMAT_* (-1 = disable) */ diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c index 5c9c45deb86..e3f7fbd8d3b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c @@ -265,7 +265,7 @@ etna_submit_rs_state(struct etna_context *ctx, /* Generate clear command for a surface (non-fast clear case) */ void etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf, - uint32_t clear_value) + uint64_t clear_value) { struct etna_resource *dst = etna_resource(surf->base.texture); uint32_t format; @@ -301,7 +301,7 @@ etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf, .dither = {0xffffffff, 0xffffffff}, .width = surf->surf.padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */ .height = surf->surf.padded_height, - .clear_value = {clear_value}, + .clear_value = {clear_value, clear_value >> 32, clear_value, clear_value >> 32}, .clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1, .clear_bits = 0xffff }); @@ -313,10 +313,11 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, struct pipe_surface *dst, { struct etna_context *ctx = etna_context(pctx); struct etna_surface *surf = etna_surface(dst); - uint32_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color->f); + uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color); if (surf->surf.ts_size) { /* TS: use precompiled clear command */ ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value; + ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32; if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) { /* Set number of color tiles to be filled */ @@ -742,6 +743,7 @@ etna_try_rs_blit(struct pipe_context *pctx, etna_set_state_reloc(ctx->stream, VIVS_TS_COLOR_SURFACE_BASE, &reloc); etna_set_state(ctx->stream, VIVS_TS_COLOR_CLEAR_VALUE, src_lev->clear_value); + etna_set_state(ctx->stream, VIVS_TS_COLOR_CLEAR_VALUE_EXT, src_lev->clear_value >> 32); source_ts_valid = true; } else { diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 5c8448315f0..f5f5993abc5 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -187,6 +187,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx, if (cbuf->surf.ts_size) { cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value; + cs->TS_COLOR_CLEAR_VALUE_EXT = cbuf->level->clear_value >> 32; cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc; cs->TS_COLOR_STATUS_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE; diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c b/src/gallium/drivers/etnaviv/etnaviv_surface.c index d93519db6df..153ab837246 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_surface.c +++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c @@ -103,8 +103,10 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc, if (VIV_FEATURE(ctx->screen, chipFeatures, FAST_CLEAR) && VIV_FEATURE(ctx->screen, chipMinorFeatures0, MC20) && !rsc->ts_bo && + /* needs to be RS/BLT compatible for transfer_map/unmap */ (rsc->levels[level].padded_width & ETNA_RS_WIDTH_MASK) == 0 && - (rsc->levels[level].padded_height & ETNA_RS_HEIGHT_MASK) == 0) { + (rsc->levels[level].padded_height & ETNA_RS_HEIGHT_MASK) == 0 && + etna_resource_hw_tileable(ctx->specs.use_blt, prsc)) { etna_screen_resource_alloc_ts(pctx->screen, rsc); } diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c index aa4b2534419..f3ca6a736fc 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture.c +++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c @@ -102,7 +102,7 @@ etna_configure_sampler_ts(struct etna_sampler_ts *sts, struct pipe_sampler_view COND(lev->ts_compress_fmt >= 0, VIVS_TS_SAMPLER_CONFIG_COMPRESSION) | VIVS_TS_SAMPLER_CONFIG_COMPRESSION_FORMAT(lev->ts_compress_fmt); sts->TS_SAMPLER_CLEAR_VALUE = lev->clear_value; - sts->TS_SAMPLER_CLEAR_VALUE2 = lev->clear_value; /* To handle 64-bit formats this needs a different value */ + sts->TS_SAMPLER_CLEAR_VALUE2 = lev->clear_value >> 32; sts->TS_SAMPLER_STATUS_BASE.bo = rsc->ts_bo; sts->TS_SAMPLER_STATUS_BASE.offset = lev->ts_offset; sts->TS_SAMPLER_STATUS_BASE.flags = ETNA_RELOC_READ; -- 2.30.2