X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fvc4%2Fvc4_qir_lower_uniforms.c;h=d7c22e75c2938fc52513fb64c8deb9a7627d7a60;hp=9f782dfc7df3c218e981014eb30a10b6c2dccebe;hb=HEAD;hpb=d3cdbf6fd817ae5e7a8a72bcc3f43cc1b04a709b diff --git a/src/gallium/drivers/vc4/vc4_qir_lower_uniforms.c b/src/gallium/drivers/vc4/vc4_qir_lower_uniforms.c index 9f782dfc7df..d7c22e75c29 100644 --- a/src/gallium/drivers/vc4/vc4_qir_lower_uniforms.c +++ b/src/gallium/drivers/vc4/vc4_qir_lower_uniforms.c @@ -66,7 +66,7 @@ remove_uniform(struct hash_table *ht, struct qreg reg) entry = _mesa_hash_table_search(ht, key); assert(entry); - entry->data--; + entry->data = (void *)(((uintptr_t) entry->data) - 1); if (entry->data == NULL) _mesa_hash_table_remove(ht, entry); } @@ -77,7 +77,7 @@ is_lowerable_uniform(struct qinst *inst, int i) if (inst->src[i].file != QFILE_UNIF) return false; if (qir_is_tex(inst)) - return i != 1; + return i != qir_get_tex_uniform_src(inst); return true; } @@ -89,7 +89,7 @@ qir_get_instruction_uniform_count(struct qinst *inst) { uint32_t count = 0; - for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { + for (int i = 0; i < qir_get_nsrc(inst); i++) { if (inst->src[i].file != QFILE_UNIF) continue; @@ -119,7 +119,7 @@ qir_lower_uniforms(struct vc4_compile *c) * ht. */ qir_for_each_inst_inorder(inst, c) { - uint32_t nsrc = qir_get_op_nsrc(inst->op); + uint32_t nsrc = qir_get_nsrc(inst); if (qir_get_instruction_uniform_count(inst) <= 1) continue; @@ -136,7 +136,6 @@ qir_lower_uniforms(struct vc4_compile *c) */ uint32_t max_count = 0; uint32_t max_index = 0; - struct hash_entry *entry; hash_table_foreach(ht, entry) { uint32_t count = (uintptr_t)entry->data; uint32_t index = (uintptr_t)entry->key - 1; @@ -146,41 +145,56 @@ qir_lower_uniforms(struct vc4_compile *c) } } + struct qreg unif = qir_reg(QFILE_UNIF, max_index); + /* Now, find the instructions using this uniform and make them * reference a temp instead. */ - struct qreg temp = qir_get_temp(c); - struct qreg unif = qir_reg(QFILE_UNIF, max_index); - struct qinst *mov = qir_inst(QOP_MOV, temp, unif, c->undef); - list_add(&mov->link, &c->instructions); - c->defs[temp.index] = mov; - qir_for_each_inst_inorder(inst, c) { - uint32_t nsrc = qir_get_op_nsrc(inst->op); - - uint32_t count = qir_get_instruction_uniform_count(inst); - - if (count <= 1) - continue; - - bool removed = false; - for (int i = 0; i < nsrc; i++) { - if (is_lowerable_uniform(inst, i) && - inst->src[i].index == max_index) { - inst->src[i] = temp; - remove_uniform(ht, unif); - removed = true; + qir_for_each_block(block, c) { + struct qinst *mov = NULL; + + qir_for_each_inst(inst, block) { + uint32_t nsrc = qir_get_nsrc(inst); + + uint32_t count = qir_get_instruction_uniform_count(inst); + + if (count <= 1) + continue; + + /* If the block doesn't have a load of hte + * uniform yet, add it. We could potentially + * do better and CSE MOVs from multiple blocks + * into dominating blocks, except that may + * cause troubles for register allocation. + */ + if (!mov) { + mov = qir_inst(QOP_MOV, qir_get_temp(c), + unif, c->undef); + list_add(&mov->link, + &block->instructions); + c->defs[mov->dst.index] = mov; } - } - if (removed) - count--; - /* If the instruction doesn't need lowering any more, - * then drop it from the list. - */ - if (count <= 1) { + bool removed = false; for (int i = 0; i < nsrc; i++) { - if (is_lowerable_uniform(inst, i)) - remove_uniform(ht, inst->src[i]); + if (is_lowerable_uniform(inst, i) && + inst->src[i].index == max_index) { + inst->src[i] = mov->dst; + remove_uniform(ht, unif); + removed = true; + } + } + if (removed) + count--; + + /* If the instruction doesn't need lowering any more, + * then drop it from the list. + */ + if (count <= 1) { + for (int i = 0; i < nsrc; i++) { + if (is_lowerable_uniform(inst, i)) + remove_uniform(ht, inst->src[i]); + } } } }