summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2009-12-14 18:39:13 +0100
committerChristoph Bumiller <[email protected]>2009-12-14 18:39:13 +0100
commit2677f199a547f6e44d964b8c34dd7f60d9523ab2 (patch)
tree91edff4312ba23e5561a615db5cb24da107e8dd2 /src/gallium/drivers/nv50
parentc14be63c5647e4406a0a4d80570a4def593b551b (diff)
nv50: be more cautious about using reg_instance
Trying to free part of nv50_pc->reg_instances[] for an nv50_reg representing an indirect constant resulted in a segmentation fault.
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index fe8ccd03494..e496cf4cad8 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -156,14 +156,15 @@ struct nv50_pc {
static INLINE struct nv50_reg *
reg_instance(struct nv50_pc *pc, struct nv50_reg *reg)
{
- struct nv50_reg *dup = NULL;
+ struct nv50_reg *ri;
+
+ assert(pc->reg_instance_nr < 16);
+ ri = &pc->reg_instances[pc->reg_instance_nr++];
if (reg) {
- assert(pc->reg_instance_nr < 16);
- dup = &pc->reg_instances[pc->reg_instance_nr++];
- *dup = *reg;
+ *ri = *reg;
reg->mod = 0;
}
- return dup;
+ return ri;
}
static INLINE void
@@ -1886,7 +1887,7 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
/* Indicate indirection by setting r->acc < 0 and
* use the index field to select the address reg.
*/
- r = MALLOC_STRUCT(nv50_reg);
+ r = reg_instance(pc, NULL);
swz = tgsi_util_get_src_register_swizzle(
&src->Indirect, 0);
ctor_reg(r, P_CONST,
@@ -1940,6 +1941,8 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
break;
}
+ if (r && r->acc >= 0 && r != temp)
+ return reg_instance(pc, r);
return r;
}
@@ -2094,8 +2097,7 @@ nv50_program_tx_insn(struct nv50_pc *pc,
for (c = 0; c < 4; c++)
if (src_mask & (1 << c))
- src[i][c] = reg_instance(pc,
- tgsi_src(pc, c, fs, neg_supp));
+ src[i][c] = tgsi_src(pc, c, fs, neg_supp);
}
brdc = temp = pc->r_brdc;
@@ -2466,15 +2468,6 @@ nv50_program_tx_insn(struct nv50_pc *pc,
}
}
- for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
- for (c = 0; c < 4; c++) {
- if (!src[i][c])
- continue;
- if (src[i][c]->acc < 0 && src[i][c]->type == P_CONST)
- FREE(src[i][c]); /* indirect constant */
- }
- }
-
kill_temp_temp(pc);
pc->reg_instance_nr = 0;