etnaviv: TS usage for MRT needs HALTI2

I have not seen any usage of TS when MRTs are used in my traces for
GC2000. I think that this is related to gcvFEATURE_MRT_TILE_STATUS_BUFFER
found in some galcore kernel headers.

We need to take extra care as those render targets might already have valid
TS state, because they have been fast cleared or have been rendered to with
a state that did allow TS usage.

Fixes piglit's related to MRTs on GC2000.

Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26565>
This commit is contained in:
Christian Gmeiner
2023-12-05 12:29:24 +01:00
committed by Marge Bot
parent 2df17da0c3
commit 6b154706f3
3 changed files with 35 additions and 4 deletions
+9 -4
View File
@@ -32,6 +32,7 @@
#include "etnaviv_format.h"
#include "etnaviv_resource.h"
#include "etnaviv_screen.h"
#include "etnaviv_state.h"
#include "etnaviv_surface.h"
#include "etnaviv_tiling.h"
#include "etnaviv_translate.h"
@@ -326,14 +327,14 @@ etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
static void
etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx,
const union pipe_color_union *color)
const union pipe_color_union *color, bool use_ts)
{
struct etna_context *ctx = etna_context(pctx);
struct pipe_surface *dst = ctx->framebuffer_s.cbufs[idx];
struct etna_surface *surf = etna_surface(dst);
uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color);
if (surf->level->ts_size) { /* TS: use precompiled clear command */
if (use_ts && surf->level->ts_size) { /* TS: use precompiled clear command */
if (idx == 0) {
ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32;
@@ -358,7 +359,7 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx,
etna_submit_rs_state(ctx, &surf->ts_clear_command);
etna_resource_level_ts_mark_valid(surf->level);
ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS;
ctx->dirty |= ETNA_DIRTY_TS;
} else { /* Queue normal RS clear for non-TS surfaces */
/* If clear color changed or no valid command yet (re-)generate
* stored command */
@@ -367,8 +368,10 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, unsigned idx,
etna_rs_gen_clear_surface(ctx, surf, new_clear_value);
etna_submit_rs_state(ctx, &surf->clear_command);
etna_resource_level_ts_mark_invalid(surf->level);
}
ctx->dirty |= ETNA_DIRTY_DERIVE_TS;
surf->level->clear_value = new_clear_value;
resource_written(ctx, surf->base.texture);
etna_resource_level_mark_changed(surf->level);
@@ -488,13 +491,15 @@ etna_clear_rs(struct pipe_context *pctx, unsigned buffers, const struct pipe_sci
* resolve and copy) do not require the TS state.
*/
if (buffers & PIPE_CLEAR_COLOR) {
const bool use_ts = etna_use_ts_for_mrt(ctx->screen, &ctx->framebuffer_s);
for (int idx = 0; idx < ctx->framebuffer_s.nr_cbufs; ++idx) {
struct etna_surface *surf = etna_surface(ctx->framebuffer_s.cbufs[idx]);
if (!surf)
continue;
etna_blit_clear_color_rs(pctx, idx, color);
etna_blit_clear_color_rs(pctx, idx, color, use_ts);
if (!etna_resource(surf->prsc)->explicit_flush)
etna_context_add_flush_resource(ctx, surf->prsc);
@@ -146,6 +146,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
uint32_t pe_mem_config = 0;
uint32_t pe_logic_op = 0;
const bool use_ts = etna_use_ts_for_mrt(screen, fb);
unsigned rt = 0;
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
@@ -157,6 +158,12 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0;
uint32_t fmt = translate_pe_format(cbuf->base.format);
/* Resolve TS if needed */
if (!use_ts) {
etna_copy_resource(pctx, &res->base, &res->base, cbuf->base.u.tex.level, cbuf->base.u.tex.level);
etna_resource_level_ts_mark_invalid(&res->levels[cbuf->base.u.tex.level]);
}
assert((res->layout & ETNA_LAYOUT_BIT_TILE) ||
VIV_FEATURE(screen, ETNA_FEATURE_LINEAR_PE));
etna_update_render_surface(pctx, cbuf);
@@ -29,6 +29,7 @@
#define ETNAVIV_STATE_H_
#include "etnaviv_context.h"
#include "etnaviv_screen.h"
#include "pipe/p_context.h"
static inline bool
@@ -43,6 +44,24 @@ etna_stencil_enabled(struct etna_context *ctx)
return ctx->zsa && ctx->zsa->stencil[0].enabled;
}
static inline bool
etna_use_ts_for_mrt(const struct etna_screen *screen, const struct pipe_framebuffer_state *fb)
{
if (screen->info->halti >= 2)
return true;
unsigned count = 0;
for (unsigned i = 0; i < fb->nr_cbufs; i++) {
if (!fb->cbufs[i])
continue;
count++;
}
return count <= 1;
}
bool
etna_state_update(struct etna_context *ctx);