vc4: Fix uniform reordering to support reading the same uniform twice.
authorEric Anholt <eric@anholt.net>
Tue, 17 Nov 2015 04:45:46 +0000 (20:45 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 18 Nov 2015 01:45:23 +0000 (17:45 -0800)
This does actually happen in the wild (particularly fabs of a uniform), so
we'd like to support it.

src/gallium/drivers/vc4/vc4_reorder_uniforms.c

index 7f11fba2340a54754d7c44bc115de2478e2e0fcd..85a0c95e85155c214d44faf2e67de010c1c675b8 100644 (file)
@@ -44,18 +44,28 @@ qir_reorder_uniforms(struct vc4_compile *c)
         uint32_t next_uniform = 0;
 
         list_for_each_entry(struct qinst, inst, &c->instructions, link) {
+                uint32_t new = ~0;
+
                 for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) {
                         if (inst->src[i].file != QFILE_UNIF)
                                 continue;
 
-                        uint32_t new = next_uniform++;
-                        if (uniform_index_size <= new) {
-                                uniform_index_size =
-                                        MAX2(uniform_index_size * 2, 16);
-                                uniform_index =
-                                        realloc(uniform_index,
-                                                uniform_index_size *
-                                                sizeof(uint32_t));
+                        if (new == ~0) {
+                                new = next_uniform++;
+                                if (uniform_index_size <= new) {
+                                        uniform_index_size =
+                                                MAX2(uniform_index_size * 2, 16);
+                                        uniform_index =
+                                                realloc(uniform_index,
+                                                        uniform_index_size *
+                                                        sizeof(uint32_t));
+                                }
+                        } else {
+                                /* If we've got two uniform references in this
+                                 * instruction, they need to be the same
+                                 * uniform value.
+                                 */
+                                assert(inst->src[i].index == uniform_index[new]);
                         }
 
                         uniform_index[new] = inst->src[i].index;