diff options
author | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-09-09 19:12:54 +0200 |
---|---|---|
committer | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-09-09 19:21:34 +0200 |
commit | f30810cb68a53c4fef360778a230126ed0ee0ee3 (patch) | |
tree | 6b4f2fe6919261a5e356f5d75078c78a941f6cb7 /src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | |
parent | d8dcff79702860eae92d3d35b461c9b71114c1c5 (diff) |
nv50: use actual loads/stores if TEMPs are accessed indirectly
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_tgsi_to_nc.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c index 983fcb2fbf..f4fee4e0f2 100644 --- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c +++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c @@ -558,6 +558,38 @@ bld_insn_3(struct bld_context *bld, uint opcode, return bld_def(insn, 0, new_value(bld->pc, NV_FILE_GPR, src0->reg.type)); } +static void +bld_lmem_store(struct bld_context *bld, struct nv_value *ptr, int ofst, + struct nv_value *val) +{ + struct nv_instruction *insn = new_instruction(bld->pc, NV_OP_STA); + struct nv_value *loc; + + loc = new_value(bld->pc, NV_FILE_MEM_L, NV_TYPE_U32); + + loc->reg.id = ofst * 4; + + nv_reference(bld->pc, &insn->src[0], loc); + nv_reference(bld->pc, &insn->src[1], val); + nv_reference(bld->pc, &insn->src[4], ptr); +} + +static struct nv_value * +bld_lmem_load(struct bld_context *bld, struct nv_value *ptr, int ofst) +{ + struct nv_value *loc, *val; + + loc = new_value(bld->pc, NV_FILE_MEM_L, NV_TYPE_U32); + + loc->reg.id = ofst * 4; + + val = bld_insn_1(bld, NV_OP_LDA, loc); + + nv_reference(bld->pc, &val->insn->src[4], ptr); + + return val; +} + #define BLD_INSN_1_EX(d, op, dt, s0, s0t) \ do { \ (d) = bld_insn_1(bld, (NV_OP_##op), (s0)); \ @@ -854,10 +886,18 @@ infer_dst_type(unsigned opcode) static void emit_store(struct bld_context *bld, const struct tgsi_full_instruction *inst, - unsigned chan, struct nv_value *value) + unsigned chan, struct nv_value *value) { + struct nv_value *ptr; const struct tgsi_full_dst_register *reg = &inst->Dst[0]; + if (reg->Register.Indirect) { + ptr = FETCH_ADDR(reg->Indirect.Index, + tgsi_util_get_src_register_swizzle(®->Indirect, 0)); + } else { + ptr = NULL; + } + assert(chan < 4); if (inst->Instruction.Opcode != TGSI_OPCODE_MOV) @@ -893,7 +933,11 @@ emit_store(struct bld_context *bld, const struct tgsi_full_instruction *inst, value->reg.file = NV_FILE_GPR; if (value->insn->bb != bld->pc->current_block) value = bld_insn_1(bld, NV_OP_MOV, value); - STORE_TEMP(reg->Register.Index, chan, value); + + if (bld->ti->store_to_memory) + bld_lmem_store(bld, ptr, reg->Register.Index * 4 + chan, value); + else + STORE_TEMP(reg->Register.Index, chan, value); break; case TGSI_FILE_ADDRESS: assert(reg->Register.Index < BLD_MAX_ADDRS); @@ -1064,8 +1108,10 @@ emit_fetch(struct bld_context *bld, const struct tgsi_full_instruction *insn, bld->saved_inputs[bld->ti->input_map[idx][swz]] = res; break; case TGSI_FILE_TEMPORARY: - /* this should be load from l[], with reload elimination later on */ - res = bld_fetch_global(bld, &bld->tvs[idx][swz]); + if (bld->ti->store_to_memory) + res = bld_lmem_load(bld, ptr, idx * 4 + swz); + else + res = bld_fetch_global(bld, &bld->tvs[idx][swz]); break; case TGSI_FILE_ADDRESS: res = bld_fetch_global(bld, &bld->avs[idx][swz]); |