ir3: add helper to create STC

Creating STC is complicated since we might need to use a1.x for
addressing. Extract the current code into a helper so that it can be
used elsewhere.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32454>
This commit is contained in:
Job Noorman 2025-03-03 09:58:54 +01:00 committed by Marge Bot
parent 3186443057
commit 62d2069617
3 changed files with 43 additions and 26 deletions

View file

@ -1006,6 +1006,43 @@ ir3_create_addr1(struct ir3_builder *build, unsigned const_val)
return instr;
}
struct ir3_instruction *
ir3_store_const(struct ir3_shader_variant *so, struct ir3_builder *build,
struct ir3_instruction *src, unsigned dst)
{
unsigned dst_lo = dst & 0xff;
unsigned dst_hi = dst >> 8;
unsigned components = util_last_bit(src->dsts[0]->wrmask);
struct ir3_instruction *a1 = NULL;
if (dst_hi) {
/* Encode only the high part of the destination in a1.x to increase the
* chance that we can reuse the a1.x value in subsequent stc
* instructions.
*/
a1 = ir3_create_addr1(build, dst_hi << 8);
}
struct ir3_instruction *stc =
ir3_STC(build, create_immed(build, dst_lo), 0, src, 0);
stc->cat6.iim_val = components;
stc->cat6.type = TYPE_U32;
stc->barrier_conflict = IR3_BARRIER_CONST_W;
if (a1) {
ir3_instr_set_address(stc, a1);
stc->flags |= IR3_INSTR_A1EN;
}
/* The assembler isn't aware of what value a1.x has, so make sure that
* constlen includes the stc here.
*/
so->constlen = MAX2(so->constlen, DIV_ROUND_UP(dst + components, 4));
struct ir3_block *block = ir3_cursor_current_block(build->cursor);
array_insert(block, block->keeps, stc);
return stc;
}
/* Does this instruction use the scalar ALU?
*/
bool

View file

@ -2676,6 +2676,11 @@ ir3_BALLOT_MACRO(struct ir3_builder *build, struct ir3_instruction *src,
return instr;
}
struct ir3_instruction *ir3_store_const(struct ir3_shader_variant *so,
struct ir3_builder *build,
struct ir3_instruction *src,
unsigned dst);
/* clang-format off */
#define __INSTR0(flag, name, opc) \
static inline struct ir3_instruction *ir3_##name(struct ir3_builder *build) \

View file

@ -3358,37 +3358,12 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_store_const_ir3: {
unsigned components = nir_src_num_components(intr->src[0]);
unsigned dst = nir_intrinsic_base(intr);
unsigned dst_lo = dst & 0xff;
unsigned dst_hi = dst >> 8;
struct ir3_instruction *src =
ir3_create_collect(b, ir3_get_src_shared(ctx, &intr->src[0],
ctx->compiler->has_scalar_alu),
components);
struct ir3_instruction *a1 = NULL;
if (dst_hi) {
/* Encode only the high part of the destination in a1.x to increase the
* chance that we can reuse the a1.x value in subsequent stc
* instructions.
*/
a1 = ir3_create_addr1(&ctx->build, dst_hi << 8);
}
struct ir3_instruction *stc =
ir3_STC(b, create_immed(b, dst_lo), 0, src, 0);
stc->cat6.iim_val = components;
stc->cat6.type = TYPE_U32;
stc->barrier_conflict = IR3_BARRIER_CONST_W;
if (a1) {
ir3_instr_set_address(stc, a1);
stc->flags |= IR3_INSTR_A1EN;
}
/* The assembler isn't aware of what value a1.x has, so make sure that
* constlen includes the stc here.
*/
ctx->so->constlen =
MAX2(ctx->so->constlen, DIV_ROUND_UP(dst + components, 4));
array_insert(ctx->block, ctx->block->keeps, stc);
ir3_store_const(ctx->so, b, src, dst);
break;
}
case nir_intrinsic_copy_push_const_to_uniform_ir3: {