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);