nv50: make assimilate_temp safe
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 30 Dec 2009 20:17:31 +0000 (21:17 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 31 Dec 2009 13:34:38 +0000 (14:34 +0100)
Cannot change hw reg assigned to a TGSI TEMP on the fly if
we are in a loop, conditional, or can jump around wildly.

src/gallium/drivers/nv50/nv50_program.c

index a85587b9869e606a9151a019f456772a7f4b82d0..7d1b5fd82c8d71a6cefd25a1a261710aed5df6f1 100644 (file)
@@ -285,22 +285,6 @@ alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
        return NULL;
 }
 
-/* Assign the hw of the discarded temporary register src
- * to the tgsi register dst and free src.
- */
-static void
-assimilate_temp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
-{
-       assert(src->index == -1 && src->hw != -1);
-
-       if (dst->hw != -1)
-               pc->r_temp[dst->hw] = NULL;
-       pc->r_temp[src->hw] = dst;
-       dst->hw = src->hw;
-
-       FREE(src);
-}
-
 /* release the hardware resource held by r */
 static void
 release_hw(struct nv50_pc *pc, struct nv50_reg *r)
@@ -721,6 +705,34 @@ emit_mov_immdval(struct nv50_pc *pc, struct nv50_reg *dst, float f)
        FREE(imm);
 }
 
+/* Assign the hw of the discarded temporary register src
+ * to the tgsi register dst and free src.
+ */
+static void
+assimilate_temp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
+{
+       assert(src->index == -1 && src->hw != -1);
+
+       if (pc->if_lvl || pc->loop_lvl ||
+           (dst->type != P_TEMP) ||
+           (src->hw < pc->result_nr * 4 &&
+            pc->p->type == PIPE_SHADER_FRAGMENT) ||
+           pc->p->info.opcode_count[TGSI_OPCODE_CAL] ||
+           pc->p->info.opcode_count[TGSI_OPCODE_BRA]) {
+
+               emit_mov(pc, dst, src);
+               free_temp(pc, src);
+               return;
+       }
+
+       if (dst->hw != -1)
+               pc->r_temp[dst->hw] = NULL;
+       pc->r_temp[src->hw] = dst;
+       dst->hw = src->hw;
+
+       FREE(src);
+}
+
 static void
 emit_nop(struct nv50_pc *pc)
 {