diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index 3e51e49703f..ef04834f22b 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -6111,6 +6111,7 @@ bi_compile_variant_nir(nir_shader *nir, ctx->info = info; ctx->idvs = idvs; ctx->malloc_idvs = (ctx->arch >= 9) && !inputs->no_idvs; + ctx->fau_consts_count = info.init_fau_consts_count; unsigned execution_mode = nir->info.float_controls_execution_mode; ctx->rtz_fp16 = nir_is_rounding_mode_rtz(execution_mode, 16); @@ -6377,6 +6378,7 @@ bi_compile_variant(nir_shader *nir, .bifrost = &info->bifrost, .tls_size = info->tls_size, .push_offset = info->push.count, + .init_fau_consts_count = info->fau_consts_count, }; unsigned offset = binary->size; @@ -6399,6 +6401,8 @@ bi_compile_variant(nir_shader *nir, bi_context *ctx = bi_compile_variant_nir(nir, inputs, binary, local_info, stats, idvs); + info->fau_consts_count = ctx->fau_consts_count; + /* A register is preloaded <==> it is live before the first block */ bi_block *first_block = list_first_entry(&ctx->blocks, bi_block, link); uint64_t preload = first_block->reg_live_in; diff --git a/src/panfrost/compiler/compiler.h b/src/panfrost/compiler/compiler.h index d13551ca961..9c2c44e3750 100644 --- a/src/panfrost/compiler/compiler.h +++ b/src/panfrost/compiler/compiler.h @@ -981,6 +981,7 @@ struct bi_shader_info { unsigned tls_size; unsigned work_reg_count; unsigned push_offset; + unsigned init_fau_consts_count; bool has_ld_gclk_instr; }; @@ -1042,6 +1043,8 @@ typedef struct { */ bi_index preloaded[BI_MAX_REGS]; + uint32_t fau_consts_count; + /* For creating temporaries */ unsigned ssa_alloc; unsigned reg_alloc; diff --git a/src/panfrost/compiler/valhall/va_lower_constants.c b/src/panfrost/compiler/valhall/va_lower_constants.c index a6e6a9d546b..03cc0920c3e 100644 --- a/src/panfrost/compiler/valhall/va_lower_constants.c +++ b/src/panfrost/compiler/valhall/va_lower_constants.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2025 Arm Ltd. * Copyright (C) 2021 Collabora Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -108,6 +109,32 @@ is_extension_of_16(uint32_t x, bool is_signed) return (x <= UINT16_MAX); } +static bi_index +va_move_const_to_fau(bi_builder *b, uint32_t value) +{ + const unsigned push_base = b->shader->inputs->fau_consts.offset; + uint32_t *values = b->shader->inputs->fau_consts.values; + + assert(b->shader->inputs->fau_consts.max_amount == 0 || values != NULL); + assert(b->shader->fau_consts_count <= + b->shader->inputs->fau_consts.max_amount); + + for (unsigned i = 0; i < b->shader->fau_consts_count; ++i) { + if (values[i] == value) { + const unsigned idx = push_base + i; + return bi_fau((enum bir_fau)(BIR_FAU_UNIFORM | (idx >> 1)), idx & 1); + } + } + + if (b->shader->fau_consts_count < b->shader->inputs->fau_consts.max_amount) { + const unsigned int idx = push_base + b->shader->fau_consts_count; + values[b->shader->fau_consts_count++] = value; + return bi_fau((enum bir_fau)(BIR_FAU_UNIFORM | (idx >> 1)), idx & 1); + } + + return bi_null(); +} + static bi_index va_resolve_constant(bi_builder *b, uint32_t value, struct va_src_info info, bool is_signed, bool staging) @@ -179,7 +206,12 @@ va_resolve_constant(bi_builder *b, uint32_t value, struct va_src_info info, } } - /* TODO: Optimize to uniform */ + if (!staging) { + bi_index c = va_move_const_to_fau(b, value); + if (!bi_is_null(c)) + return c; + } + return va_mov_imm(b, value); }