Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / src / gallium / drivers / vc4 / vc4_qir_lower_uniforms.c
index 9f782dfc7df3c218e981014eb30a10b6c2dccebe..d7c22e75c2938fc52513fb64c8deb9a7627d7a60 100644 (file)
@@ -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]);
+                                        }
                                 }
                         }
                 }