pan/compiler: Fix WaRaR hazard in pressure scheduler

A common memory swap operation might be compiled as:
%v1 = LOAD %a1  # L1
%v2 = LOAD %a2  # L2
STORE %v2, %a1  # S1
STORE %v1, %a2  # S2

The current pressure scheduler just records the last load/store
operation for dependencies, thus the dependency chain becomes L2 -> S1
-> S2.  The compiler might thus reorder them as L2, S1, L1, S2, i.e
                #    L1:
%v2 = LOAD %a2  # L2 |
STORE %v2, %a1  # S1 |
%v1 = LOAD %a1  # L1<-
STORE %v1, %a2  # S2

This is incorrect as S1 depends on L1 too.  The fix makes all loads also
depend on each other, restricting load reordering.  The proper fix that
NAK has is to track all loads and make each store depend on every load,
building a more correct DAG.  This doesn't matter as much in panfrost
since all loads are serialized by the scoreboard.  We might still want
to implement it for register pressure in the future.

Signed-off-by: Lorenzo Rossi <lorenzo.rossi@collabora.com>
Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40924>
This commit is contained in:
Lorenzo Rossi 2026-04-09 22:27:06 +02:00 committed by Marge Bot
parent abde403a7c
commit ac23e3c6c5
2 changed files with 6 additions and 1 deletions

View file

@ -83,7 +83,6 @@ shaders@point-vertex-id gl_vertexid divisor,Fail
shaders@point-vertex-id gl_vertexid,Fail
shaders@point-vertex-id gl_vertexid gl_instanceid divisor,Fail
shaders@point-vertex-id gl_vertexid gl_instanceid,Fail
spec@arb_arrays_of_arrays@execution@atomic_counters@fs-indirect-index,Fail
spec@arb_point_sprite@arb_point_sprite-mipmap,Fail
spec@arb_shader_texture_lod@execution@arb_shader_texture_lod-texgradcube,Fail
spec@arb_shader_texture_lod@execution@arb_shader_texture_lod-texgrad,Fail

View file

@ -74,6 +74,11 @@ create_dag(bi_context *ctx, bi_block *block, void *memctx)
*/
if (I->seg != BI_SEG_UBO) {
add_dep(node, memory_store);
/* Chain loads together so a store cannot be scheduled
* between two loads to the same address. Without alias
* analysis we conservatively serialize all loads.
*/
add_dep(node, memory_load);
memory_load = node;
}
@ -87,6 +92,7 @@ create_dag(bi_context *ctx, bi_block *block, void *memctx)
if ((I->op == BI_OPCODE_LD_TEX) || (I->op == BI_OPCODE_LD_TEX_IMM) ||
(I->op == BI_OPCODE_LD_ATTR_TEX)) {
add_dep(node, memory_store);
add_dep(node, memory_load);
memory_load = node;
}