Mesa (master): pan/bi: Use the interference mechanism to describe blend shader reg use
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Jan 11 20:54:31 UTC 2021
Module: Mesa
Branch: master
Commit: 4439757db23490b9a4b75487d699470cdd7ebcf4
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4439757db23490b9a4b75487d699470cdd7ebcf4
Author: Boris Brezillon <boris.brezillon at collabora.com>
Date: Fri Jan 8 19:21:33 2021 +0100
pan/bi: Use the interference mechanism to describe blend shader reg use
Blend shader might clobber r0-r15, we must make sure the RA is aware
when compiling fragment shaders that have BLEND operations.
Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8417>
---
src/panfrost/bifrost/bi_ra.c | 46 ++++++++++++++++++++++++++++++++++----------
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/src/panfrost/bifrost/bi_ra.c b/src/panfrost/bifrost/bi_ra.c
index 0be5bdbf62f..c7c2003bfd3 100644
--- a/src/panfrost/bifrost/bi_ra.c
+++ b/src/panfrost/bifrost/bi_ra.c
@@ -32,28 +32,45 @@
static void
bi_compute_interference(bi_context *ctx, struct lcra_state *l)
{
+ unsigned node_count = bi_max_temp(ctx);
+
bi_compute_liveness(ctx);
bi_foreach_block(ctx, _blk) {
bi_block *blk = (bi_block *) _blk;
- uint16_t *live = mem_dup(_blk->live_out, l->node_count * sizeof(uint16_t));
+ uint16_t *live = mem_dup(_blk->live_out, node_count * sizeof(uint16_t));
bi_foreach_instr_in_block_rev(blk, ins) {
/* Mark all registers live after the instruction as
* interfering with the destination */
for (unsigned d = 0; d < ARRAY_SIZE(ins->dest); ++d) {
- if (bi_get_node(ins->dest[d]) >= l->node_count)
+ if (bi_get_node(ins->dest[d]) >= node_count)
continue;
- for (unsigned i = 1; i < l->node_count; ++i) {
+ for (unsigned i = 1; i < node_count; ++i) {
if (live[i])
lcra_add_node_interference(l, bi_get_node(ins->dest[d]), bi_writemask(ins), i, live[i]);
}
}
+ if (!ctx->is_blend && ins->op == BI_OPCODE_BLEND) {
+ /* Add blend shader interference: blend shaders might
+ * clobber r0-r15. */
+ for (unsigned i = 1; i < node_count; ++i) {
+ if (!live[i])
+ continue;
+
+ for (unsigned j = 0; j < 4; j++) {
+ lcra_add_node_interference(l, node_count + j,
+ 0xFFFF,
+ i, live[i]);
+ }
+ }
+ }
+
/* Update live_in */
- bi_liveness_ins_update(live, ins, l->node_count);
+ bi_liveness_ins_update(live, ins, node_count);
}
free(live);
@@ -69,8 +86,15 @@ bi_allocate_registers(bi_context *ctx, bool *success)
{
unsigned node_count = bi_max_temp(ctx);
+ /* We need 4 hidden nodes to encode interference caused by non-terminal
+ * BLEND (blend shaders are allowed to use r0-r16).
+ */
struct lcra_state *l =
- lcra_alloc_equations(node_count, 1);
+ lcra_alloc_equations(node_count + 4, 1);
+
+ /* Preset solutions for the blend shader pseudo nodes */
+ for (unsigned i = 0; i < 4; i++)
+ l->solutions[node_count + i] = i * 16;
if (ctx->is_blend) {
/* R0-R3 are reserved for the blend input */
@@ -109,16 +133,17 @@ bi_allocate_registers(bi_context *ctx, bool *success)
}
static bi_index
-bi_reg_from_index(struct lcra_state *l, bi_index index)
+bi_reg_from_index(bi_context *ctx, struct lcra_state *l, bi_index index)
{
/* Offsets can only be applied when we register allocated an index, or
* alternatively for FAU's encoding */
ASSERTED bool is_offset = (index.offset > 0) &&
(index.type != BI_INDEX_FAU);
+ unsigned node_count = bi_max_temp(ctx);
/* Did we run RA for this index at all */
- if (bi_get_node(index) >= l->node_count) {
+ if (bi_get_node(index) >= node_count) {
assert(!is_offset);
return index;
}
@@ -146,10 +171,10 @@ static void
bi_install_registers(bi_context *ctx, struct lcra_state *l)
{
bi_foreach_instr_global(ctx, ins) {
- ins->dest[0] = bi_reg_from_index(l, ins->dest[0]);
+ ins->dest[0] = bi_reg_from_index(ctx, l, ins->dest[0]);
bi_foreach_src(ins, s)
- ins->src[s] = bi_reg_from_index(l, ins->src[s]);
+ ins->src[s] = bi_reg_from_index(ctx, l, ins->src[s]);
}
}
@@ -195,7 +220,8 @@ bi_choose_spill_node(bi_context *ctx, struct lcra_state *l)
}
}
- for (unsigned i = PAN_IS_REG; i < l->node_count; i += 2)
+ unsigned node_count = bi_max_temp(ctx);
+ for (unsigned i = PAN_IS_REG; i < node_count; i += 2)
lcra_set_node_spill_cost(l, i, -1);
return lcra_get_best_spill_node(l);
More information about the mesa-commit
mailing list