From cb83f25b39173db92d8ccaeac3a9b640f46f7651 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 22 May 2024 13:09:07 +0200 Subject: [PATCH] broadcom/compiler: don't assign payload registers to spilling setup temps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We read our payload registers first in the shader so we generally don't have to care about temps being allocated to them and stomping their value before we can read them. Hoewer, spilling setup instructions are an exception since these will be inserted first when there is any spilling in the program. To fix this, we flag RA nodes involved with these instructions so we can then try to avoid assiging these registers to them. Fixes CTS failures with V3D_DEBUG=opt_compile_time, particularly: dEQP-VK.binding_model.buffer_device_address.set0.depth2.basessbo.convertcheckuv2.nostore.single.std140.comp_offset_nonzero Reviewed-by: Alejandro PiƱeiro cc: mesa-stable Part-of: --- src/broadcom/compiler/v3d_compiler.h | 5 +++++ src/broadcom/compiler/vir_register_allocate.c | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index 12aaacdc14a..43c4d0fbacc 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -603,6 +603,11 @@ struct v3d_ra_node_info { bool is_program_end; bool unused; + /* If this node may have an allocation conflict with a + * payload register. + */ + bool payload_conflict; + /* V3D 7.x */ bool is_ldunif_dst; } *info; diff --git a/src/broadcom/compiler/vir_register_allocate.c b/src/broadcom/compiler/vir_register_allocate.c index a4b9d432690..de2baeed770 100644 --- a/src/broadcom/compiler/vir_register_allocate.c +++ b/src/broadcom/compiler/vir_register_allocate.c @@ -48,6 +48,13 @@ get_phys_index(const struct v3d_device_info *devinfo) #define CLASS_BITS_ACC (1 << 1) #define CLASS_BITS_R5 (1 << 4) +static inline bool +stage_has_payload(struct v3d_compile *c) +{ + return c->s->info.stage == MESA_SHADER_FRAGMENT || + c->s->info.stage == MESA_SHADER_COMPUTE; +} + static uint8_t get_class_bit_any(const struct v3d_device_info *devinfo) { @@ -387,6 +394,7 @@ add_node(struct v3d_compile *c, uint32_t temp, uint8_t class_bits) c->nodes.info[node].is_ldunif_dst = false; c->nodes.info[node].is_program_end = false; c->nodes.info[node].unused = false; + c->nodes.info[node].payload_conflict = false; return node; } @@ -440,7 +448,9 @@ v3d_setup_spill_base(struct v3d_compile *c) i != c->spill_base.index) { temp_class |= CLASS_BITS_ACC; } - add_node(c, i, temp_class); + int node = add_node(c, i, temp_class); + c->nodes.info[node].payload_conflict = + stage_has_payload(c); } } @@ -942,10 +952,12 @@ v3d_ra_select_rf(struct v3d_ra_select_callback_data *v3d_ra, /* The last 3 instructions in a shader can't use some specific registers * (usually early rf registers, depends on v3d version) so try to * avoid allocating these to registers used by the last instructions - * in the shader. + * in the shader. Do the same for spilling setup instructions that + * may conflict with payload registers. */ const uint32_t safe_rf_start = v3d_ra->devinfo->ver == 42 ? 3 : 4; - if (v3d_ra->nodes->info[node].is_program_end && + if ((v3d_ra->nodes->info[node].is_program_end || + v3d_ra->nodes->info[node].payload_conflict) && v3d_ra->next_phys < safe_rf_start) { v3d_ra->next_phys = safe_rf_start; }