diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 7f3ea63cc52..474a99c74e8 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -306,6 +306,9 @@ typedef struct compiler_context { midgard_instruction *writeout_branch[MIDGARD_NUM_RTS][MIDGARD_MAX_SAMPLE_ITER]; struct hash_table_u64 *sysval_to_id; + + /* Mask of UBOs that need to be uploaded */ + uint32_t ubo_mask; } compiler_context; /* Per-block live_in/live_out */ diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c index 1b11eb775b2..704cfc87466 100644 --- a/src/panfrost/midgard/midgard_ra.c +++ b/src/panfrost/midgard/midgard_ra.c @@ -1042,6 +1042,8 @@ mir_demote_uniforms(compiler_context *ctx, unsigned new_cutoff) unsigned idx = (23 - SSA_REG_FROM_FIXED(ins->src[i])) * 4; assert(idx < ctx->info->push.count); + ctx->ubo_mask |= BITSET_BIT(ctx->info->push.words[idx].ubo); + midgard_instruction ld = { .type = TAG_LOAD_STORE_4, .mask = 0xF, diff --git a/src/panfrost/midgard/mir_promote_uniforms.c b/src/panfrost/midgard/mir_promote_uniforms.c index 5a8dbafbd8f..5d7045a9c79 100644 --- a/src/panfrost/midgard/mir_promote_uniforms.c +++ b/src/panfrost/midgard/mir_promote_uniforms.c @@ -37,10 +37,16 @@ */ static bool -mir_is_direct_aligned_ubo(midgard_instruction *ins) +mir_is_ubo(midgard_instruction *ins) { return (ins->type == TAG_LOAD_STORE_4) && - (OP_IS_UBO_READ(ins->op)) && + (OP_IS_UBO_READ(ins->op)); +} + +static bool +mir_is_direct_aligned_ubo(midgard_instruction *ins) +{ + return mir_is_ubo(ins) && !(ins->constants.u32[0] & 0xF) && (ins->src[1] == ~0) && (ins->src[2] == ~0); @@ -258,8 +264,12 @@ mir_special_indices(compiler_context *ctx) void midgard_promote_uniforms(compiler_context *ctx) { - if (ctx->inputs->no_ubo_to_push) + if (ctx->inputs->no_ubo_to_push) { + /* If nothing is pushed, all UBOs need to be uploaded + * conventionally */ + ctx->ubo_mask = ~0; return; + } struct mir_ubo_analysis analysis = mir_analyze_ranges(ctx); @@ -273,15 +283,29 @@ midgard_promote_uniforms(compiler_context *ctx) /* First, figure out special indices a priori so we don't recompute a lot */ BITSET_WORD *special = mir_special_indices(ctx); + ctx->ubo_mask = 0; + mir_foreach_instr_global_safe(ctx, ins) { - if (!mir_is_direct_aligned_ubo(ins)) continue; + if (!mir_is_ubo(ins)) continue; unsigned ubo = midgard_unpack_ubo_index_imm(ins->load_store); unsigned qword = ins->constants.u32[0] / 16; + if (!mir_is_direct_aligned_ubo(ins)) { + if (ins->src[1] == ~0) + ctx->ubo_mask |= BITSET_BIT(ubo); + else + ctx->ubo_mask = ~0; + + continue; + } + /* Check if we decided to push this */ assert(ubo < analysis.nr_blocks); - if (!BITSET_TEST(analysis.blocks[ubo].pushed, qword)) continue; + if (!BITSET_TEST(analysis.blocks[ubo].pushed, qword)) { + ctx->ubo_mask |= BITSET_BIT(ubo); + continue; + } /* Find where we pushed to, TODO: unaligned pushes to pack */ unsigned base = pan_lookup_pushed_ubo(&ctx->info->push, ubo, qword * 16);