Path: blob/21.2-virgl/src/freedreno/ir3/ir3_context.c
4565 views
/*1* Copyright (C) 2015-2018 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*22* Authors:23* Rob Clark <[email protected]>24*/2526#include "ir3_context.h"27#include "ir3_compiler.h"28#include "ir3_image.h"29#include "ir3_nir.h"30#include "ir3_shader.h"3132struct ir3_context *33ir3_context_init(struct ir3_compiler *compiler, struct ir3_shader_variant *so)34{35struct ir3_context *ctx = rzalloc(NULL, struct ir3_context);3637if (compiler->gpu_id >= 400) {38if (so->type == MESA_SHADER_VERTEX) {39ctx->astc_srgb = so->key.vastc_srgb;40} else if (so->type == MESA_SHADER_FRAGMENT) {41ctx->astc_srgb = so->key.fastc_srgb;42}4344} else {45if (so->type == MESA_SHADER_VERTEX) {46ctx->samples = so->key.vsamples;47} else if (so->type == MESA_SHADER_FRAGMENT) {48ctx->samples = so->key.fsamples;49}50}5152if (compiler->gpu_id >= 600) {53ctx->funcs = &ir3_a6xx_funcs;54} else if (compiler->gpu_id >= 400) {55ctx->funcs = &ir3_a4xx_funcs;56}5758ctx->compiler = compiler;59ctx->so = so;60ctx->def_ht =61_mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);62ctx->block_ht =63_mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);64ctx->continue_block_ht =65_mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);66ctx->sel_cond_conversions =67_mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);6869/* TODO: maybe generate some sort of bitmask of what key70* lowers vs what shader has (ie. no need to lower71* texture clamp lowering if no texture sample instrs)..72* although should be done further up the stack to avoid73* creating duplicate variants..74*/7576ctx->s = nir_shader_clone(ctx, so->shader->nir);77ir3_nir_lower_variant(so, ctx->s);7879/* this needs to be the last pass run, so do this here instead of80* in ir3_optimize_nir():81*/82bool progress = false;83NIR_PASS(progress, ctx->s, nir_lower_locals_to_regs);8485/* we could need cleanup after lower_locals_to_regs */86while (progress) {87progress = false;88NIR_PASS(progress, ctx->s, nir_opt_algebraic);89NIR_PASS(progress, ctx->s, nir_opt_constant_folding);90}9192/* We want to lower nir_op_imul as late as possible, to catch also93* those generated by earlier passes (e.g, nir_lower_locals_to_regs).94* However, we want a final swing of a few passes to have a chance95* at optimizing the result.96*/97progress = false;98NIR_PASS(progress, ctx->s, ir3_nir_lower_imul);99while (progress) {100progress = false;101NIR_PASS(progress, ctx->s, nir_opt_algebraic);102NIR_PASS(progress, ctx->s, nir_opt_copy_prop_vars);103NIR_PASS(progress, ctx->s, nir_opt_dead_write_vars);104NIR_PASS(progress, ctx->s, nir_opt_dce);105NIR_PASS(progress, ctx->s, nir_opt_constant_folding);106}107108/* Enable the texture pre-fetch feature only a4xx onwards. But109* only enable it on generations that have been tested:110*/111if ((so->type == MESA_SHADER_FRAGMENT) && (compiler->gpu_id >= 600))112NIR_PASS_V(ctx->s, ir3_nir_lower_tex_prefetch);113114NIR_PASS(progress, ctx->s, nir_lower_phis_to_scalar, true);115116/* Super crude heuristic to limit # of tex prefetch in small117* shaders. This completely ignores loops.. but that's really118* not the worst of it's problems. (A frag shader that has119* loops is probably going to be big enough to not trigger a120* lower threshold.)121*122* 1) probably want to do this in terms of ir3 instructions123* 2) probably really want to decide this after scheduling124* (or at least pre-RA sched) so we have a rough idea about125* nops, and don't count things that get cp'd away126* 3) blob seems to use higher thresholds with a mix of more127* SFU instructions. Which partly makes sense, more SFU128* instructions probably means you want to get the real129* shader started sooner, but that considers where in the130* shader the SFU instructions are, which blob doesn't seem131* to do.132*133* This uses more conservative thresholds assuming a more alu134* than sfu heavy instruction mix.135*/136if (so->type == MESA_SHADER_FRAGMENT) {137nir_function_impl *fxn = nir_shader_get_entrypoint(ctx->s);138139unsigned instruction_count = 0;140nir_foreach_block (block, fxn) {141instruction_count += exec_list_length(&block->instr_list);142}143144if (instruction_count < 50) {145ctx->prefetch_limit = 2;146} else if (instruction_count < 70) {147ctx->prefetch_limit = 3;148} else {149ctx->prefetch_limit = IR3_MAX_SAMPLER_PREFETCH;150}151}152153if (shader_debug_enabled(so->type)) {154mesa_logi("NIR (final form) for %s shader %s:", ir3_shader_stage(so),155so->shader->nir->info.name);156nir_log_shaderi(ctx->s);157}158159ir3_ibo_mapping_init(&so->image_mapping, ctx->s->info.num_textures);160161return ctx;162}163164void165ir3_context_free(struct ir3_context *ctx)166{167ralloc_free(ctx);168}169170/*171* Misc helpers172*/173174/* allocate a n element value array (to be populated by caller) and175* insert in def_ht176*/177struct ir3_instruction **178ir3_get_dst_ssa(struct ir3_context *ctx, nir_ssa_def *dst, unsigned n)179{180struct ir3_instruction **value =181ralloc_array(ctx->def_ht, struct ir3_instruction *, n);182_mesa_hash_table_insert(ctx->def_ht, dst, value);183return value;184}185186struct ir3_instruction **187ir3_get_dst(struct ir3_context *ctx, nir_dest *dst, unsigned n)188{189struct ir3_instruction **value;190191if (dst->is_ssa) {192value = ir3_get_dst_ssa(ctx, &dst->ssa, n);193} else {194value = ralloc_array(ctx, struct ir3_instruction *, n);195}196197/* NOTE: in non-ssa case, we don't really need to store last_dst198* but this helps us catch cases where put_dst() call is forgotten199*/200compile_assert(ctx, !ctx->last_dst);201ctx->last_dst = value;202ctx->last_dst_n = n;203204return value;205}206207struct ir3_instruction *const *208ir3_get_src(struct ir3_context *ctx, nir_src *src)209{210if (src->is_ssa) {211struct hash_entry *entry;212entry = _mesa_hash_table_search(ctx->def_ht, src->ssa);213compile_assert(ctx, entry);214return entry->data;215} else {216nir_register *reg = src->reg.reg;217struct ir3_array *arr = ir3_get_array(ctx, reg);218unsigned num_components = arr->r->num_components;219struct ir3_instruction *addr = NULL;220struct ir3_instruction **value =221ralloc_array(ctx, struct ir3_instruction *, num_components);222223if (src->reg.indirect)224addr = ir3_get_addr0(ctx, ir3_get_src(ctx, src->reg.indirect)[0],225reg->num_components);226227for (unsigned i = 0; i < num_components; i++) {228unsigned n = src->reg.base_offset * reg->num_components + i;229compile_assert(ctx, n < arr->length);230value[i] = ir3_create_array_load(ctx, arr, n, addr);231}232233return value;234}235}236237void238ir3_put_dst(struct ir3_context *ctx, nir_dest *dst)239{240unsigned bit_size = nir_dest_bit_size(*dst);241242/* add extra mov if dst value is shared reg.. in some cases not all243* instructions can read from shared regs, in cases where they can244* ir3_cp will clean up the extra mov:245*/246for (unsigned i = 0; i < ctx->last_dst_n; i++) {247if (!ctx->last_dst[i])248continue;249if (ctx->last_dst[i]->dsts[0]->flags & IR3_REG_SHARED) {250ctx->last_dst[i] = ir3_MOV(ctx->block, ctx->last_dst[i], TYPE_U32);251}252}253254/* Note: 1-bit bools are stored in 32-bit regs */255if (bit_size == 16) {256for (unsigned i = 0; i < ctx->last_dst_n; i++) {257struct ir3_instruction *dst = ctx->last_dst[i];258ir3_set_dst_type(dst, true);259ir3_fixup_src_type(dst);260if (dst->opc == OPC_META_SPLIT) {261ir3_set_dst_type(ssa(dst->srcs[0]), true);262ir3_fixup_src_type(ssa(dst->srcs[0]));263dst->srcs[0]->flags |= IR3_REG_HALF;264}265}266}267268if (!dst->is_ssa) {269nir_register *reg = dst->reg.reg;270struct ir3_array *arr = ir3_get_array(ctx, reg);271unsigned num_components = ctx->last_dst_n;272struct ir3_instruction *addr = NULL;273274if (dst->reg.indirect)275addr = ir3_get_addr0(ctx, ir3_get_src(ctx, dst->reg.indirect)[0],276reg->num_components);277278for (unsigned i = 0; i < num_components; i++) {279unsigned n = dst->reg.base_offset * reg->num_components + i;280compile_assert(ctx, n < arr->length);281if (!ctx->last_dst[i])282continue;283ir3_create_array_store(ctx, arr, n, ctx->last_dst[i], addr);284}285286ralloc_free(ctx->last_dst);287}288289ctx->last_dst = NULL;290ctx->last_dst_n = 0;291}292293static unsigned294dest_flags(struct ir3_instruction *instr)295{296return instr->dsts[0]->flags & (IR3_REG_HALF | IR3_REG_SHARED);297}298299struct ir3_instruction *300ir3_create_collect(struct ir3_context *ctx, struct ir3_instruction *const *arr,301unsigned arrsz)302{303struct ir3_block *block = ctx->block;304struct ir3_instruction *collect;305306if (arrsz == 0)307return NULL;308309unsigned flags = dest_flags(arr[0]);310311collect = ir3_instr_create(block, OPC_META_COLLECT, 1, arrsz);312__ssa_dst(collect)->flags |= flags;313for (unsigned i = 0; i < arrsz; i++) {314struct ir3_instruction *elem = arr[i];315316/* Since arrays are pre-colored in RA, we can't assume that317* things will end up in the right place. (Ie. if a collect318* joins elements from two different arrays.) So insert an319* extra mov.320*321* We could possibly skip this if all the collected elements322* are contiguous elements in a single array.. not sure how323* likely that is to happen.324*325* Fixes a problem with glamor shaders, that in effect do326* something like:327*328* if (foo)329* texcoord = ..330* else331* texcoord = ..332* color = texture2D(tex, texcoord);333*334* In this case, texcoord will end up as nir registers (which335* translate to ir3 array's of length 1. And we can't assume336* the two (or more) arrays will get allocated in consecutive337* scalar registers.338*339*/340if (elem->dsts[0]->flags & IR3_REG_ARRAY) {341type_t type = (flags & IR3_REG_HALF) ? TYPE_U16 : TYPE_U32;342elem = ir3_MOV(block, elem, type);343}344345compile_assert(ctx, dest_flags(elem) == flags);346__ssa_src(collect, elem, flags);347}348349collect->dsts[0]->wrmask = MASK(arrsz);350351return collect;352}353354/* helper for instructions that produce multiple consecutive scalar355* outputs which need to have a split meta instruction inserted356*/357void358ir3_split_dest(struct ir3_block *block, struct ir3_instruction **dst,359struct ir3_instruction *src, unsigned base, unsigned n)360{361if ((n == 1) && (src->dsts[0]->wrmask == 0x1) &&362/* setup_input needs ir3_split_dest to generate a SPLIT instruction */363src->opc != OPC_META_INPUT) {364dst[0] = src;365return;366}367368if (src->opc == OPC_META_COLLECT) {369debug_assert((base + n) <= src->srcs_count);370371for (int i = 0; i < n; i++) {372dst[i] = ssa(src->srcs[i + base]);373}374375return;376}377378unsigned flags = dest_flags(src);379380for (int i = 0, j = 0; i < n; i++) {381struct ir3_instruction *split =382ir3_instr_create(block, OPC_META_SPLIT, 1, 1);383__ssa_dst(split)->flags |= flags;384__ssa_src(split, src, flags);385split->split.off = i + base;386387if (src->dsts[0]->wrmask & (1 << (i + base)))388dst[j++] = split;389}390}391392NORETURN void393ir3_context_error(struct ir3_context *ctx, const char *format, ...)394{395struct hash_table *errors = NULL;396va_list ap;397va_start(ap, format);398if (ctx->cur_instr) {399errors = _mesa_hash_table_create(NULL, _mesa_hash_pointer,400_mesa_key_pointer_equal);401char *msg = ralloc_vasprintf(errors, format, ap);402_mesa_hash_table_insert(errors, ctx->cur_instr, msg);403} else {404mesa_loge_v(format, ap);405}406va_end(ap);407nir_log_shader_annotated(ctx->s, errors);408ralloc_free(errors);409ctx->error = true;410unreachable("");411}412413static struct ir3_instruction *414create_addr0(struct ir3_block *block, struct ir3_instruction *src, int align)415{416struct ir3_instruction *instr, *immed;417418instr = ir3_COV(block, src, TYPE_U32, TYPE_S16);419420switch (align) {421case 1:422/* src *= 1: */423break;424case 2:425/* src *= 2 => src <<= 1: */426immed = create_immed_typed(block, 1, TYPE_S16);427instr = ir3_SHL_B(block, instr, 0, immed, 0);428break;429case 3:430/* src *= 3: */431immed = create_immed_typed(block, 3, TYPE_S16);432instr = ir3_MULL_U(block, instr, 0, immed, 0);433break;434case 4:435/* src *= 4 => src <<= 2: */436immed = create_immed_typed(block, 2, TYPE_S16);437instr = ir3_SHL_B(block, instr, 0, immed, 0);438break;439default:440unreachable("bad align");441return NULL;442}443444instr->dsts[0]->flags |= IR3_REG_HALF;445446instr = ir3_MOV(block, instr, TYPE_S16);447instr->dsts[0]->num = regid(REG_A0, 0);448449return instr;450}451452static struct ir3_instruction *453create_addr1(struct ir3_block *block, unsigned const_val)454{455struct ir3_instruction *immed =456create_immed_typed(block, const_val, TYPE_U16);457struct ir3_instruction *instr = ir3_MOV(block, immed, TYPE_U16);458instr->dsts[0]->num = regid(REG_A0, 1);459return instr;460}461462/* caches addr values to avoid generating multiple cov/shl/mova463* sequences for each use of a given NIR level src as address464*/465struct ir3_instruction *466ir3_get_addr0(struct ir3_context *ctx, struct ir3_instruction *src, int align)467{468struct ir3_instruction *addr;469unsigned idx = align - 1;470471compile_assert(ctx, idx < ARRAY_SIZE(ctx->addr0_ht));472473if (!ctx->addr0_ht[idx]) {474ctx->addr0_ht[idx] = _mesa_hash_table_create(ctx, _mesa_hash_pointer,475_mesa_key_pointer_equal);476} else {477struct hash_entry *entry;478entry = _mesa_hash_table_search(ctx->addr0_ht[idx], src);479if (entry)480return entry->data;481}482483addr = create_addr0(ctx->block, src, align);484_mesa_hash_table_insert(ctx->addr0_ht[idx], src, addr);485486return addr;487}488489/* Similar to ir3_get_addr0, but for a1.x. */490struct ir3_instruction *491ir3_get_addr1(struct ir3_context *ctx, unsigned const_val)492{493struct ir3_instruction *addr;494495if (!ctx->addr1_ht) {496ctx->addr1_ht = _mesa_hash_table_u64_create(ctx);497} else {498addr = _mesa_hash_table_u64_search(ctx->addr1_ht, const_val);499if (addr)500return addr;501}502503addr = create_addr1(ctx->block, const_val);504_mesa_hash_table_u64_insert(ctx->addr1_ht, const_val, addr);505506return addr;507}508509struct ir3_instruction *510ir3_get_predicate(struct ir3_context *ctx, struct ir3_instruction *src)511{512struct ir3_block *b = ctx->block;513struct ir3_instruction *cond;514515/* NOTE: only cmps.*.* can write p0.x: */516cond = ir3_CMPS_S(b, src, 0, create_immed(b, 0), 0);517cond->cat2.condition = IR3_COND_NE;518519/* condition always goes in predicate register: */520cond->dsts[0]->num = regid(REG_P0, 0);521cond->dsts[0]->flags &= ~IR3_REG_SSA;522523return cond;524}525526/*527* Array helpers528*/529530void531ir3_declare_array(struct ir3_context *ctx, nir_register *reg)532{533struct ir3_array *arr = rzalloc(ctx, struct ir3_array);534arr->id = ++ctx->num_arrays;535/* NOTE: sometimes we get non array regs, for example for arrays of536* length 1. See fs-const-array-of-struct-of-array.shader_test. So537* treat a non-array as if it was an array of length 1.538*539* It would be nice if there was a nir pass to convert arrays of540* length 1 to ssa.541*/542arr->length = reg->num_components * MAX2(1, reg->num_array_elems);543compile_assert(ctx, arr->length > 0);544arr->r = reg;545arr->half = reg->bit_size <= 16;546// HACK one-bit bools still end up as 32b:547if (reg->bit_size == 1)548arr->half = false;549list_addtail(&arr->node, &ctx->ir->array_list);550}551552struct ir3_array *553ir3_get_array(struct ir3_context *ctx, nir_register *reg)554{555foreach_array (arr, &ctx->ir->array_list) {556if (arr->r == reg)557return arr;558}559ir3_context_error(ctx, "bogus reg: r%d\n", reg->index);560return NULL;561}562563/* relative (indirect) if address!=NULL */564struct ir3_instruction *565ir3_create_array_load(struct ir3_context *ctx, struct ir3_array *arr, int n,566struct ir3_instruction *address)567{568struct ir3_block *block = ctx->block;569struct ir3_instruction *mov;570struct ir3_register *src;571unsigned flags = 0;572573mov = ir3_instr_create(block, OPC_MOV, 1, 1);574if (arr->half) {575mov->cat1.src_type = TYPE_U16;576mov->cat1.dst_type = TYPE_U16;577flags |= IR3_REG_HALF;578} else {579mov->cat1.src_type = TYPE_U32;580mov->cat1.dst_type = TYPE_U32;581}582583mov->barrier_class = IR3_BARRIER_ARRAY_R;584mov->barrier_conflict = IR3_BARRIER_ARRAY_W;585__ssa_dst(mov)->flags |= flags;586src = ir3_src_create(mov, 0,587IR3_REG_ARRAY | COND(address, IR3_REG_RELATIV) | flags);588src->def = (arr->last_write && arr->last_write->instr->block == block)589? arr->last_write590: NULL;591src->size = arr->length;592src->array.id = arr->id;593src->array.offset = n;594src->array.base = INVALID_REG;595596if (address)597ir3_instr_set_address(mov, address);598599return mov;600}601602/* relative (indirect) if address!=NULL */603void604ir3_create_array_store(struct ir3_context *ctx, struct ir3_array *arr, int n,605struct ir3_instruction *src,606struct ir3_instruction *address)607{608struct ir3_block *block = ctx->block;609struct ir3_instruction *mov;610struct ir3_register *dst;611unsigned flags = 0;612613/* if not relative store, don't create an extra mov, since that614* ends up being difficult for cp to remove.615*616* Also, don't skip the mov if the src is meta (like fanout/split),617* since that creates a situation that RA can't really handle properly.618*/619if (!address && !is_meta(src)) {620dst = src->dsts[0];621622src->barrier_class |= IR3_BARRIER_ARRAY_W;623src->barrier_conflict |= IR3_BARRIER_ARRAY_R | IR3_BARRIER_ARRAY_W;624625dst->flags |= IR3_REG_ARRAY;626dst->size = arr->length;627dst->array.id = arr->id;628dst->array.offset = n;629dst->array.base = INVALID_REG;630631if (arr->last_write && arr->last_write->instr->block == src->block)632ir3_reg_set_last_array(src, dst, arr->last_write);633634arr->last_write = dst;635636array_insert(block, block->keeps, src);637638return;639}640641mov = ir3_instr_create(block, OPC_MOV, 1, 1);642if (arr->half) {643mov->cat1.src_type = TYPE_U16;644mov->cat1.dst_type = TYPE_U16;645flags |= IR3_REG_HALF;646} else {647mov->cat1.src_type = TYPE_U32;648mov->cat1.dst_type = TYPE_U32;649}650mov->barrier_class = IR3_BARRIER_ARRAY_W;651mov->barrier_conflict = IR3_BARRIER_ARRAY_R | IR3_BARRIER_ARRAY_W;652dst = ir3_dst_create(653mov, 0,654IR3_REG_SSA | IR3_REG_ARRAY | flags | COND(address, IR3_REG_RELATIV));655dst->instr = mov;656dst->size = arr->length;657dst->array.id = arr->id;658dst->array.offset = n;659dst->array.base = INVALID_REG;660ir3_src_create(mov, 0, IR3_REG_SSA | flags)->def = src->dsts[0];661662if (arr->last_write && arr->last_write->instr->block == block)663ir3_reg_set_last_array(mov, dst, arr->last_write);664665if (address)666ir3_instr_set_address(mov, address);667668arr->last_write = dst;669670/* the array store may only matter to something in an earlier671* block (ie. loops), but since arrays are not in SSA, depth672* pass won't know this.. so keep all array stores:673*/674array_insert(block, block->keeps, mov);675}676677678