diff options
author | Christoph Bumiller <[email protected]> | 2010-09-13 00:59:38 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-09-13 17:26:41 +0200 |
commit | 0b8170103c8eaff46b75e89608198b3eb564bc52 (patch) | |
tree | 363b7d151dd5f5175e4448809c9b3d27ba2f324f | |
parent | 3b3c20744f2ea90f6aaae33b337bdc5e135f3198 (diff) |
nv50: fix indirect CONST access with large or negative offsets
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_emit.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 9 |
2 files changed, 12 insertions, 3 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc_emit.c b/src/gallium/drivers/nv50/nv50_pc_emit.c index 8c64b198756..1eb44741f16 100644 --- a/src/gallium/drivers/nv50/nv50_pc_emit.c +++ b/src/gallium/drivers/nv50/nv50_pc_emit.c @@ -696,7 +696,9 @@ emit_add_b32(struct nv_pc *pc, struct nv_instruction *i) static void emit_add_a16(struct nv_pc *pc, struct nv_instruction *i) { - pc->emit[0] = 0xd0000001 | (get_immd_u32(i->src[0]) << 9); + int s = (i->opcode == NV_OP_MOV) ? 0 : 1; + + pc->emit[0] = 0xd0000001 | ((uint16_t)get_immd_u32(i->src[s]) << 9); pc->emit[1] = 0x20000000; pc->emit[0] |= (DREG(i->def[0])->id + 1) << 2; @@ -704,7 +706,7 @@ emit_add_a16(struct nv_pc *pc, struct nv_instruction *i) set_pred(pc, i); if (i->src[1]) - set_a16_bits(pc, SREG(i->src[1])->id); + set_a16_bits(pc, SREG(i->src[1])->id + 1); } static void diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index 54d6fb960f8..a2b6901c81e 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -665,6 +665,7 @@ bld_get_address(struct bld_context *bld, int id, struct nv_value *indirect) { int i; struct nv_instruction *nvi; + struct nv_value *val; for (i = 0; i < 4; ++i) { if (!bld->saved_addr[i][0]) @@ -677,7 +678,13 @@ bld_get_address(struct bld_context *bld, int id, struct nv_value *indirect) } i &= 3; - bld->saved_addr[i][0] = bld_load_imm_u32(bld, id); + val = bld_imm_u32(bld, id); + if (indirect) + val = bld_insn_2(bld, NV_OP_ADD, indirect, val); + else + val = bld_insn_1(bld, NV_OP_MOV, val); + + bld->saved_addr[i][0] = val; bld->saved_addr[i][0]->reg.file = NV_FILE_ADDR; bld->saved_addr[i][0]->reg.type = NV_TYPE_U16; bld->saved_addr[i][1] = indirect; |