From 21dff176f16e2c538d29c0666afeee99068d75f2 Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Fri, 23 Jul 2021 12:14:32 +1200 Subject: [PATCH 1/5] pan/mdg: Use the correct swizzle for condition moves Fixes: 70072a20e00 ("pan/midgard: Refactor swizzles") --- src/panfrost/midgard/midgard_schedule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panfrost/midgard/midgard_schedule.c b/src/panfrost/midgard/midgard_schedule.c index f987b7f17fd4..f1b78ccba285 100644 --- a/src/panfrost/midgard/midgard_schedule.c +++ b/src/panfrost/midgard/midgard_schedule.c @@ -978,7 +978,7 @@ mir_schedule_condition(compiler_context *ctx, midgard_instruction *cond = mir_schedule_comparison( ctx, instructions, predicate, worklist, count, last->src[condition_index], - vector, last->swizzle[2], last); + vector, last->swizzle[condition_index], last); /* We have exclusive reign over this (possibly move) conditional * instruction. We can rewrite into a pipeline conditional register */ -- GitLab From 0dc960a55f90f172c094d7c07fb0a75c60f560f4 Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Thu, 22 Jul 2021 22:15:30 +1200 Subject: [PATCH 2/5] pan/mdg: Unaligned uniform pushing --- src/panfrost/midgard/mir_promote_uniforms.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/panfrost/midgard/mir_promote_uniforms.c b/src/panfrost/midgard/mir_promote_uniforms.c index 5d7045a9c799..1d7bc29c3869 100644 --- a/src/panfrost/midgard/mir_promote_uniforms.c +++ b/src/panfrost/midgard/mir_promote_uniforms.c @@ -46,8 +46,14 @@ mir_is_ubo(midgard_instruction *ins) static bool mir_is_direct_aligned_ubo(midgard_instruction *ins) { - return mir_is_ubo(ins) && - !(ins->constants.u32[0] & 0xF) && + if (!mir_is_ubo(ins)) + return false; + + unsigned offset = ins->constants.u32[0]; + unsigned size = util_logbase2_ceil(mir_bytemask(ins)); + + return !(offset & 0x3) && + ((offset & 0xf) + size <= 16) && (ins->src[1] == ~0) && (ins->src[2] == ~0); } @@ -290,6 +296,7 @@ midgard_promote_uniforms(compiler_context *ctx) unsigned ubo = midgard_unpack_ubo_index_imm(ins->load_store); unsigned qword = ins->constants.u32[0] / 16; + unsigned offset = ins->constants.u32[0] % 16; if (!mir_is_direct_aligned_ubo(ins)) { if (ins->src[1] == ~0) @@ -318,6 +325,13 @@ midgard_promote_uniforms(compiler_context *ctx) assert(address < promoted_count); unsigned promoted = SSA_FIXED_REGISTER(uniform_reg); + unsigned comps = mir_components_for_type(ins->dest_type); + unsigned swz_offset = offset * comps / 16; + + unsigned swizzle[MIR_VEC_COMPONENTS]; + for (unsigned i = 0; i < comps - swz_offset; ++i) + swizzle[i] = i + swz_offset; + /* We do need the move for safety for a non-SSA dest, or if * we're being fed into a special class */ @@ -331,12 +345,13 @@ midgard_promote_uniforms(compiler_context *ctx) midgard_instruction mov = v_mov(promoted, ins->dest); mov.dest_type = nir_type_uint | type_size; mov.src_types[1] = mov.dest_type; + memcpy(mov.swizzle[1], swizzle, sizeof(swizzle)); uint16_t rounded = mir_round_bytemask_up(mir_bytemask(ins), type_size); mir_set_bytemask(&mov, rounded); mir_insert_instruction_before(ctx, ins, mov); } else { - mir_rewrite_index_src(ctx, ins->dest, promoted); + mir_rewrite_index_src_swizzle(ctx, ins->dest, promoted, swizzle); } mir_remove_instruction(ins); -- GitLab From 453314e3f3399a9fcc5d4b5025d251757896a806 Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Tue, 11 May 2021 23:06:38 +1200 Subject: [PATCH 3/5] pan/mdg: Make sure the sysval push range is first --- src/panfrost/midgard/mir_promote_uniforms.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/panfrost/midgard/mir_promote_uniforms.c b/src/panfrost/midgard/mir_promote_uniforms.c index 1d7bc29c3869..d8f8fc37b332 100644 --- a/src/panfrost/midgard/mir_promote_uniforms.c +++ b/src/panfrost/midgard/mir_promote_uniforms.c @@ -102,10 +102,13 @@ mir_analyze_ranges(compiler_context *ctx) * sophisticated. Select from the last UBO first to prioritize sysvals. */ static void -mir_pick_ubo(struct panfrost_ubo_push *push, struct mir_ubo_analysis *analysis, unsigned max_qwords) +mir_pick_ubo(struct panfrost_ubo_push *push, struct mir_ubo_analysis *analysis, unsigned max_qwords, unsigned sysval_ubo) { unsigned max_words = MIN2(PAN_MAX_PUSH, max_qwords * 4); + /* The sysval push range must be first */ + assert(sysval_ubo == analysis->nr_blocks - 1); + for (signed ubo = analysis->nr_blocks - 1; ubo >= 0; --ubo) { struct mir_ubo_block *block = &analysis->blocks[ubo]; @@ -282,8 +285,11 @@ midgard_promote_uniforms(compiler_context *ctx) unsigned work_count = mir_work_heuristic(ctx, &analysis); unsigned promoted_count = 24 - work_count; + unsigned sysval_ubo = + MAX2(ctx->inputs->sysval_ubo, ctx->nir->info.num_ubos); + /* Ensure we are 16 byte aligned to avoid underallocations */ - mir_pick_ubo(&ctx->info->push, &analysis, promoted_count); + mir_pick_ubo(&ctx->info->push, &analysis, promoted_count, sysval_ubo); ctx->info->push.count = ALIGN_POT(ctx->info->push.count, 4); /* First, figure out special indices a priori so we don't recompute a lot */ -- GitLab From 2e36a9cb545e95dffaa1838e4c7e7083438e06d3 Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Wed, 26 May 2021 15:17:31 +1200 Subject: [PATCH 4/5] pan/bi: Don't use unaligned sysval loads Unaligned loads are problematic for uniform pushing code, instead use larger loads and then move the values to the right place. --- src/panfrost/bifrost/bifrost_compile.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index b3b7192eb4fe..28f7427d426e 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -378,7 +378,7 @@ bi_make_vec_to(bi_builder *b, bi_index final_dst, } } -static bi_instr * +static void bi_load_sysval_to(bi_builder *b, bi_index dest, int sysval, unsigned nr_components, unsigned offset) { @@ -388,11 +388,18 @@ bi_load_sysval_to(bi_builder *b, bi_index dest, int sysval, pan_lookup_sysval(b->shader->sysval_to_id, &b->shader->info->sysvals, sysval); - unsigned idx = (uniform * 16) + offset; + unsigned idx = uniform * 16; + + unsigned offset_words = offset / 4; + + bi_index load_dest = bi_temp(b->shader); + bi_load_to(b, (nr_components + offset_words) * 32, load_dest, + bi_imm_u32(idx), + bi_imm_u32(sysval_ubo), BI_SEG_UBO); - return bi_load_to(b, nr_components * 32, dest, - bi_imm_u32(idx), - bi_imm_u32(sysval_ubo), BI_SEG_UBO); + for (unsigned i = 0; i < nr_components; ++i) + bi_mov_i32_to(b, bi_word(dest, i), + bi_word(load_dest, i + offset_words)); } static void -- GitLab From b07a240a6c46ecd44e530a4f6c0305693897edfb Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Sat, 8 May 2021 21:58:08 +1200 Subject: [PATCH 5/5] pan/bi: Make sure sysvals are pushed in a single range --- src/panfrost/bifrost/bi_opt_push_ubo.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/panfrost/bifrost/bi_opt_push_ubo.c b/src/panfrost/bifrost/bi_opt_push_ubo.c index caaa5ee872fd..25e68706c777 100644 --- a/src/panfrost/bifrost/bi_opt_push_ubo.c +++ b/src/panfrost/bifrost/bi_opt_push_ubo.c @@ -91,8 +91,12 @@ bi_analyze_ranges(bi_context *ctx) * sophisticated. Select from the last UBO first to prioritize sysvals. */ static void -bi_pick_ubo(struct panfrost_ubo_push *push, struct bi_ubo_analysis *analysis) +bi_pick_ubo(struct panfrost_ubo_push *push, struct bi_ubo_analysis *analysis, + unsigned sysval_ubo) { + /* The sysval push range must be first */ + assert(sysval_ubo == analysis->nr_blocks - 1); + for (signed ubo = analysis->nr_blocks - 1; ubo >= 0; --ubo) { struct bi_ubo_block *block = &analysis->blocks[ubo]; @@ -102,6 +106,11 @@ bi_pick_ubo(struct panfrost_ubo_push *push, struct bi_ubo_analysis *analysis) /* Don't push something we don't access */ if (range == 0) continue; + /* We want a single push range for sysvals, pretend + * there are no holes between sysvals */ + if (ubo == sysval_ubo) + range = 4; + /* Don't push more than possible */ if (push->count > PAN_MAX_PUSH - range) return; @@ -133,8 +142,11 @@ bi_opt_push_ubo(bi_context *ctx) /* This pass only runs once */ assert(ctx->info->push.count == 0); + unsigned sysval_ubo = + MAX2(ctx->inputs->sysval_ubo, ctx->nir->info.num_ubos); + struct bi_ubo_analysis analysis = bi_analyze_ranges(ctx); - bi_pick_ubo(&ctx->info->push, &analysis); + bi_pick_ubo(&ctx->info->push, &analysis, sysval_ubo); ctx->ubo_mask = 0; -- GitLab