broadcom/compiler: don't assign payload registers to spilling setup temps

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 <apinheiro@igalia.com>
cc: mesa-stable

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29343>
This commit is contained in:
Iago Toral Quiroga
2024-05-22 13:09:07 +02:00
committed by Marge Bot
parent 901c485997
commit cb83f25b39
2 changed files with 20 additions and 3 deletions

View File

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

View File

@@ -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;
}