vc4: Dynamically allocate the TGSI-to-qreg arrays.
authorEric Anholt <eric@anholt.net>
Mon, 15 Sep 2014 19:02:43 +0000 (12:02 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 15 Sep 2014 20:12:27 +0000 (13:12 -0700)
Fixes buffer overflows in some piglit tests (which are still failing to
register allocate anyway).

src/gallium/drivers/vc4/vc4_program.c
src/gallium/drivers/vc4/vc4_qir.h

index 12584e10526decd016194f112a2fe030ae2eed90..6ae8103960ecc9eeca1082d84293d92248235e47 100644 (file)
@@ -64,6 +64,23 @@ struct vc4_vs_key {
         enum pipe_format attr_formats[8];
 };
 
+static void
+resize_qreg_array(struct vc4_compile *c,
+                  struct qreg **regs,
+                  uint32_t *size,
+                  uint32_t decl_size)
+{
+        if (*size >= decl_size)
+                return;
+
+        *size = MAX2(*size * 2, decl_size);
+        *regs = reralloc(c, *regs, struct qreg, *size);
+        if (!*regs) {
+                fprintf(stderr, "Malloc failure\n");
+                abort();
+        }
+}
+
 static struct qreg
 add_uniform(struct vc4_compile *c,
             enum quniform_contents contents,
@@ -91,6 +108,9 @@ get_temp_for_uniform(struct vc4_compile *c, enum quniform_contents contents,
         struct qreg u = add_uniform(c, contents, data);
         struct qreg t = qir_MOV(c, u);
 
+        resize_qreg_array(c, &c->uniforms, &c->uniforms_array_size,
+                          u.index + 1);
+
         c->uniforms[u.index] = t;
         return t;
 }
@@ -843,7 +863,15 @@ emit_tgsi_declaration(struct vc4_compile *c,
                       struct tgsi_full_declaration *decl)
 {
         switch (decl->Declaration.File) {
+        case TGSI_FILE_TEMPORARY:
+                resize_qreg_array(c, &c->temps, &c->temps_array_size,
+                                  (decl->Range.Last + 1) * 4);
+                break;
+
         case TGSI_FILE_INPUT:
+                resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
+                                  (decl->Range.Last + 1) * 4);
+
                 for (int i = decl->Range.First;
                      i <= decl->Range.Last;
                      i++) {
@@ -859,6 +887,11 @@ emit_tgsi_declaration(struct vc4_compile *c,
                         }
                 }
                 break;
+
+        case TGSI_FILE_OUTPUT:
+                resize_qreg_array(c, &c->outputs, &c->outputs_array_size,
+                                  (decl->Range.Last + 1) * 4);
+                break;
         }
 }
 
@@ -998,6 +1031,7 @@ parse_tgsi_immediate(struct vc4_compile *c, struct tgsi_full_immediate *imm)
 {
         for (int i = 0; i < 4; i++) {
                 unsigned n = c->num_consts++;
+                resize_qreg_array(c, &c->consts, &c->consts_array_size, n + 1);
                 c->consts[n] = qir_uniform_ui(c, imm->u[i].Uint);
         }
 }
@@ -1152,10 +1186,6 @@ vc4_blend(struct vc4_compile *c, struct qreg *result,
 static void
 emit_frag_end(struct vc4_compile *c)
 {
-        struct qreg src_color[4] = {
-                c->outputs[0], c->outputs[1], c->outputs[2], c->outputs[3],
-        };
-
         enum pipe_format color_format = c->fs_key->color_format;
         const uint8_t *format_swiz = vc4_get_format_swizzle(color_format);
         struct qreg tlb_read_color[4] = { c->undef, c->undef, c->undef, c->undef };
@@ -1172,7 +1202,11 @@ emit_frag_end(struct vc4_compile *c)
         }
 
         struct qreg blend_color[4];
-        vc4_blend(c, blend_color, dst_color, src_color);
+        struct qreg undef_array[4] = {
+                c->undef, c->undef, c->undef, c->undef
+        };
+        vc4_blend(c, blend_color, dst_color,
+                  c->outputs ? c->outputs : undef_array);
 
         /* If the bit isn't set in the color mask, then just return the
          * original dst color, instead.
@@ -1312,13 +1346,6 @@ vc4_shader_tgsi_to_qir(struct vc4_compiled_shader *shader, enum qstage stage,
 
         c->stage = stage;
 
-        /* XXX sizing */
-        c->temps = ralloc_array(c, struct qreg, 1024);
-        c->inputs = ralloc_array(c, struct qreg, 8 * 4);
-        c->outputs = ralloc_array(c, struct qreg, 1024);
-        c->uniforms = ralloc_array(c, struct qreg, 1024);
-        c->consts = ralloc_array(c, struct qreg, 1024);
-
         c->uniform_data = ralloc_array(c, uint32_t, 1024);
         c->uniform_contents = ralloc_array(c, enum quniform_contents, 1024);
 
index fbf56f02a3a0d760568694cb2eea0b32cad90d00..539993f41b4f14169455f8a1475223c686145a01 100644 (file)
@@ -208,6 +208,11 @@ struct vc4_compile {
         struct qreg *outputs;
         struct qreg *uniforms;
         struct qreg *consts;
+        uint32_t temps_array_size;
+        uint32_t inputs_array_size;
+        uint32_t outputs_array_size;
+        uint32_t uniforms_array_size;
+        uint32_t consts_array_size;
         uint32_t num_consts;
         struct qreg line_x, point_x, point_y;
         struct qreg discard;