From 9645e46a53b5d0770e20b1d520989985a6cdc952 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 1 Sep 2022 20:55:30 -0400 Subject: [PATCH] agx: Fix tib access in internal shaders The only case where tilebuffer access can be specially optimized is the st_tile used in internal clear (or reload) shaders. However, other shaders (like those used with u_blitter) may have nir->info.internal set, so we can't key off that. Instead, add a special key for this optimization to ensure correctness with other internal shaders. Fixes flaky tests in dEQP-GLES2.functional.color_clear.* Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_compile.c | 6 ++++-- src/asahi/compiler/agx_compile.h | 12 ++++++++++++ src/gallium/drivers/asahi/agx_blit.c | 3 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index a863bcda208..42e56d26b84 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -430,8 +430,8 @@ agx_emit_fragment_out(agx_builder *b, nir_intrinsic_instr *instr) unsigned rt = (loc - FRAG_RESULT_DATA0); /* TODO: Reverse-engineer interactions with MRT */ - if (b->shader->nir->info.internal) { - /* clear */ + if (b->shader->key->fs.ignore_tib_dependencies) { + assert(b->shader->nir->info.internal && "only for clear shaders"); } else if (b->shader->did_writeout) { agx_writeout(b, 0x0004); } else { @@ -467,6 +467,7 @@ agx_emit_load_tile(agx_builder *b, agx_index *dests, nir_intrinsic_instr *instr) unsigned rt = (loc - FRAG_RESULT_DATA0); /* TODO: Reverse-engineer interactions with MRT */ + assert(!b->shader->key->fs.ignore_tib_dependencies && "invalid usage"); agx_writeout(b, 0xC200); agx_writeout(b, 0x0008); b->shader->did_writeout = true; @@ -563,6 +564,7 @@ agx_blend_const(agx_builder *b, agx_index dst, unsigned comp) static agx_instr * agx_emit_discard(agx_builder *b, nir_intrinsic_instr *instr) { + assert(!b->shader->key->fs.ignore_tib_dependencies && "invalid usage"); agx_writeout(b, 0xC200); agx_writeout(b, 0x0001); b->shader->did_writeout = true; diff --git a/src/asahi/compiler/agx_compile.h b/src/asahi/compiler/agx_compile.h index c42dbd70918..622c69a8a61 100644 --- a/src/asahi/compiler/agx_compile.h +++ b/src/asahi/compiler/agx_compile.h @@ -240,6 +240,18 @@ struct agx_vs_shader_key { struct agx_fs_shader_key { enum agx_format tib_formats[AGX_MAX_RTS]; + + /* Normally, access to the tilebuffer must be guarded by appropriate fencing + * instructions to ensure correct results in the presence of out-of-order + * hardware optimizations. However, specially dispatched clear shaders are + * not subject to these conditions and can omit the wait instructions. + * + * Must (only) be set for special clear shaders. + * + * Must not be used with sample mask writes (including discards) or + * tilebuffer loads (including blending). + */ + bool ignore_tib_dependencies; }; struct agx_shader_key { diff --git a/src/gallium/drivers/asahi/agx_blit.c b/src/gallium/drivers/asahi/agx_blit.c index f905c5f0bf3..542f3533992 100644 --- a/src/gallium/drivers/asahi/agx_blit.c +++ b/src/gallium/drivers/asahi/agx_blit.c @@ -66,7 +66,8 @@ agx_build_reload_shader(struct agx_device *dev) struct agx_shader_info info; struct agx_shader_key key = { - .fs.tib_formats[0] = i + .fs.tib_formats[0] = i, + .fs.ignore_tib_dependencies = true, }; agx_compile_shader_nir(s, &key, &binary, &info);