mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
agx: add "is helper program?" key bit
so we can enforce correctness a bit more at build-time. if the helper program does not fit in the required RA, spilling will be broken in the driver; now this is a build-time failure instead of a silent runtime one. Closes https://gitlab.freedesktop.org/asahi/mesa/-/issues/36 Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27616>
This commit is contained in:
parent
a3f647fde1
commit
c116d1efbb
4 changed files with 21 additions and 1 deletions
|
|
@ -507,7 +507,10 @@ main(int argc, char **argv)
|
|||
|
||||
UNUSED struct agx_uncompiled_shader_info info;
|
||||
UNUSED struct agx_shader_info compiled_info;
|
||||
struct agx_shader_key key = {.libagx = nir};
|
||||
struct agx_shader_key key = {
|
||||
.libagx = nir,
|
||||
.is_helper = true,
|
||||
};
|
||||
|
||||
agx_preprocess_nir(b.shader, nir, false, &info);
|
||||
agx_compile_shader_nir(b.shader, &key, NULL, &binary, &compiled_info);
|
||||
|
|
|
|||
|
|
@ -1256,6 +1256,7 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr)
|
|||
}
|
||||
|
||||
case nir_intrinsic_fence_helper_exit_agx: {
|
||||
assert(b->shader->key->is_helper);
|
||||
agx_memory_barrier(b);
|
||||
agx_unknown_barrier_1(b);
|
||||
agx_memory_barrier_2(b);
|
||||
|
|
@ -1329,12 +1330,15 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr)
|
|||
return agx_get_sr_to(b, dst, AGX_SR_CORE_ID);
|
||||
|
||||
case nir_intrinsic_load_helper_op_id_agx:
|
||||
assert(b->shader->key->is_helper);
|
||||
return agx_get_sr_barrier_to(b, dst, AGX_SR_HELPER_OP);
|
||||
|
||||
case nir_intrinsic_load_helper_arg_lo_agx:
|
||||
assert(b->shader->key->is_helper);
|
||||
return agx_get_sr_barrier_to(b, dst, AGX_SR_HELPER_ARG_L);
|
||||
|
||||
case nir_intrinsic_load_helper_arg_hi_agx:
|
||||
assert(b->shader->key->is_helper);
|
||||
return agx_get_sr_barrier_to(b, dst, AGX_SR_HELPER_ARG_H);
|
||||
|
||||
case nir_intrinsic_load_barycentric_sample:
|
||||
|
|
|
|||
|
|
@ -232,6 +232,11 @@ struct agx_shader_key {
|
|||
/* Whether scratch memory is available in the given shader stage */
|
||||
bool has_scratch;
|
||||
|
||||
/* Whether we're compiling the helper program used for scratch allocation.
|
||||
* This has special register allocation requirements.
|
||||
*/
|
||||
bool is_helper;
|
||||
|
||||
union {
|
||||
struct agx_vs_shader_key vs;
|
||||
struct agx_fs_shader_key fs;
|
||||
|
|
|
|||
|
|
@ -1141,6 +1141,11 @@ agx_ra(agx_context *ctx)
|
|||
agx_max_registers_for_occupancy(threads_per_workgroup);
|
||||
}
|
||||
|
||||
/* The helper program is unspillable and has a limited register file */
|
||||
if (ctx->key->is_helper) {
|
||||
max_possible_regs = 32;
|
||||
}
|
||||
|
||||
/* Calculate the demand. We'll use it to determine if we need to spill and to
|
||||
* bound register assignment.
|
||||
*/
|
||||
|
|
@ -1211,6 +1216,9 @@ agx_ra(agx_context *ctx)
|
|||
* affecting occupancy. This reduces live range splitting.
|
||||
*/
|
||||
unsigned max_regs = agx_occupancy_for_register_count(demand).max_registers;
|
||||
if (ctx->key->is_helper)
|
||||
max_regs = 32;
|
||||
|
||||
max_regs = ROUND_DOWN_TO(max_regs, reg_file_alignment);
|
||||
|
||||
/* Or, we can bound tightly for debugging */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue