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 <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18380>
This commit is contained in:

committed by
Marge Bot

parent
a03ce740bb
commit
9645e46a53
@@ -430,8 +430,8 @@ agx_emit_fragment_out(agx_builder *b, nir_intrinsic_instr *instr)
|
|||||||
unsigned rt = (loc - FRAG_RESULT_DATA0);
|
unsigned rt = (loc - FRAG_RESULT_DATA0);
|
||||||
|
|
||||||
/* TODO: Reverse-engineer interactions with MRT */
|
/* TODO: Reverse-engineer interactions with MRT */
|
||||||
if (b->shader->nir->info.internal) {
|
if (b->shader->key->fs.ignore_tib_dependencies) {
|
||||||
/* clear */
|
assert(b->shader->nir->info.internal && "only for clear shaders");
|
||||||
} else if (b->shader->did_writeout) {
|
} else if (b->shader->did_writeout) {
|
||||||
agx_writeout(b, 0x0004);
|
agx_writeout(b, 0x0004);
|
||||||
} else {
|
} 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);
|
unsigned rt = (loc - FRAG_RESULT_DATA0);
|
||||||
|
|
||||||
/* TODO: Reverse-engineer interactions with MRT */
|
/* TODO: Reverse-engineer interactions with MRT */
|
||||||
|
assert(!b->shader->key->fs.ignore_tib_dependencies && "invalid usage");
|
||||||
agx_writeout(b, 0xC200);
|
agx_writeout(b, 0xC200);
|
||||||
agx_writeout(b, 0x0008);
|
agx_writeout(b, 0x0008);
|
||||||
b->shader->did_writeout = true;
|
b->shader->did_writeout = true;
|
||||||
@@ -563,6 +564,7 @@ agx_blend_const(agx_builder *b, agx_index dst, unsigned comp)
|
|||||||
static agx_instr *
|
static agx_instr *
|
||||||
agx_emit_discard(agx_builder *b, nir_intrinsic_instr *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, 0xC200);
|
||||||
agx_writeout(b, 0x0001);
|
agx_writeout(b, 0x0001);
|
||||||
b->shader->did_writeout = true;
|
b->shader->did_writeout = true;
|
||||||
|
@@ -240,6 +240,18 @@ struct agx_vs_shader_key {
|
|||||||
|
|
||||||
struct agx_fs_shader_key {
|
struct agx_fs_shader_key {
|
||||||
enum agx_format tib_formats[AGX_MAX_RTS];
|
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 {
|
struct agx_shader_key {
|
||||||
|
@@ -66,7 +66,8 @@ agx_build_reload_shader(struct agx_device *dev)
|
|||||||
struct agx_shader_info info;
|
struct agx_shader_info info;
|
||||||
|
|
||||||
struct agx_shader_key key = {
|
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);
|
agx_compile_shader_nir(s, &key, &binary, &info);
|
||||||
|
Reference in New Issue
Block a user