summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2009-01-05 13:38:47 +1100
committerBen Skeggs <skeggsb@gmail.com>2009-01-06 08:05:57 +1100
commit3f66b72fdb4834c5211305698d22806eac80aa35 (patch)
tree43f3790080ddf7937887bf07a622a410d674d744
parent785e90a7dcfcaaf671157cd03699a165d45eabb0 (diff)
nv50: ensure we actually get contiguous regs for TEX insn.
Still many more horrible things to fix here...
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index d6fbdd1824..566d18cef4 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -179,6 +179,38 @@ free_temp(struct nv50_pc *pc, struct nv50_reg *r)
}
}
+static int
+alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx)
+{
+ int i;
+
+ if ((idx + 4) >= NV50_SU_MAX_TEMP)
+ return 1;
+
+ if (pc->r_temp[idx] || pc->r_temp[idx + 1] ||
+ pc->r_temp[idx + 2] || pc->r_temp[idx + 3])
+ return alloc_temp4(pc, dst, idx + 1);
+
+ for (i = 0; i < 4; i++) {
+ dst[i] = CALLOC_STRUCT(nv50_reg);
+ dst[i]->type = P_TEMP;
+ dst[i]->index = -1;
+ dst[i]->hw = idx + i;
+ pc->r_temp[idx + i] = dst[i];
+ }
+
+ return 0;
+}
+
+static void
+free_temp4(struct nv50_pc *pc, struct nv50_reg *reg[4])
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ free_temp(pc, reg[i]);
+}
+
static struct nv50_reg *
temp_temp(struct nv50_pc *pc)
{
@@ -1156,33 +1188,26 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
break;
case TGSI_OPCODE_TEX:
{
- struct nv50_reg *t0, *t1, *t2, *t3;
+ struct nv50_reg *t[4];
struct nv50_program_exec *e;
- t0 = alloc_temp(pc, NULL);
- t0 = alloc_temp(pc, NULL);
- t1 = alloc_temp(pc, NULL);
- t2 = alloc_temp(pc, NULL);
- t3 = alloc_temp(pc, NULL);
- emit_mov(pc, t0, src[0][0]);
- emit_mov(pc, t1, src[0][1]);
+ alloc_temp4(pc, t, 0);
+ emit_mov(pc, t[0], src[0][0]);
+ emit_mov(pc, t[1], src[0][1]);
e = exec(pc);
e->inst[0] = 0xf6400000;
set_long(pc, e);
e->inst[1] |= 0x0000c004;
- set_dst(pc, t0, e);
+ set_dst(pc, t[0], e);
emit(pc, e);
- if (mask & (1 << 0)) emit_mov(pc, dst[0], t0);
- if (mask & (1 << 1)) emit_mov(pc, dst[1], t1);
- if (mask & (1 << 2)) emit_mov(pc, dst[2], t2);
- if (mask & (1 << 3)) emit_mov(pc, dst[3], t3);
+ if (mask & (1 << 0)) emit_mov(pc, dst[0], t[0]);
+ if (mask & (1 << 1)) emit_mov(pc, dst[1], t[1]);
+ if (mask & (1 << 2)) emit_mov(pc, dst[2], t[2]);
+ if (mask & (1 << 3)) emit_mov(pc, dst[3], t[3]);
- free_temp(pc, t0);
- free_temp(pc, t1);
- free_temp(pc, t2);
- free_temp(pc, t3);
+ free_temp4(pc, t);
}
break;
case TGSI_OPCODE_XPD: