diff options
author | Luca Barbieri <[email protected]> | 2010-09-03 18:31:18 +0200 |
---|---|---|
committer | Luca Barbieri <[email protected]> | 2010-09-03 20:48:14 +0200 |
commit | b946984e3bbd91da3111edd0d62f90cfd4967ad3 (patch) | |
tree | ff0a2c8912924699d4680bf282ee009173b5259c /src/gallium/drivers/nvfx/nvfx_vertprog.c | |
parent | 7e282b8e62fb5d237a2e2cc94ac6a39a2f73f271 (diff) |
nvfx: support indirect addressing in vps
Negative or huge offsets not yet supported.
Diffstat (limited to 'src/gallium/drivers/nvfx/nvfx_vertprog.c')
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_vertprog.c | 99 |
1 files changed, 76 insertions, 23 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c index ea7e88c5613..838c3aa208b 100644 --- a/src/gallium/drivers/nvfx/nvfx_vertprog.c +++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c @@ -46,6 +46,7 @@ struct nvfx_vpc { struct nvfx_reg r_result[PIPE_MAX_SHADER_OUTPUTS]; struct nvfx_reg *r_address; struct nvfx_reg *r_temp; + struct nvfx_reg *r_const; struct nvfx_reg *imm; unsigned nr_imm; @@ -152,6 +153,18 @@ emit_src(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, uint32_t *hw, int pos, (src.swz[2] << NVFX_VP(SRC_SWZ_Z_SHIFT)) | (src.swz[3] << NVFX_VP(SRC_SWZ_W_SHIFT))); + if(src.indirect) { + if(src.reg.type == NVFXSR_CONST) + hw[3] |= NVFX_VP(INST_INDEX_CONST); + else if(src.reg.type == NVFXSR_INPUT) + hw[0] |= NVFX_VP(INST_INDEX_INPUT); + else + assert(0); + if(src.indirect_reg) + hw[0] |= NVFX_VP(INST_ADDR_REG_SELECT_1); + hw[0] |= src.indirect_swz << NVFX_VP(INST_ADDR_SWZ_SHIFT); + } + switch (pos) { case 0: hw[1] |= ((sr & NVFX_VP(SRC0_HIGH_MASK)) >> @@ -317,6 +330,9 @@ nvfx_vp_emit(struct nvfx_vpc *vpc, struct nvfx_insn insn) emit_src(nvfx, vpc, hw, 0, insn.src[0]); emit_src(nvfx, vpc, hw, 1, insn.src[1]); emit_src(nvfx, vpc, hw, 2, insn.src[2]); + +// if(insn.src[0].indirect || op == NVFX_VP_INST_VEC_OP_ARL) +// hw[3] |= NV40_VP_INST_SCA_RESULT; } static inline struct nvfx_src @@ -328,7 +344,7 @@ tgsi_src(struct nvfx_vpc *vpc, const struct tgsi_full_src_register *fsrc) { src.reg = nvfx_reg(NVFXSR_INPUT, fsrc->Register.Index); break; case TGSI_FILE_CONSTANT: - src.reg = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0); + src.reg = vpc->r_const[fsrc->Register.Index]; break; case TGSI_FILE_IMMEDIATE: src.reg = vpc->imm[fsrc->Register.Index]; @@ -339,7 +355,7 @@ tgsi_src(struct nvfx_vpc *vpc, const struct tgsi_full_src_register *fsrc) { default: NOUVEAU_ERR("bad src file\n"); src.reg.index = 0; - src.reg.type = 0; + src.reg.type = -1; break; } @@ -349,6 +365,22 @@ tgsi_src(struct nvfx_vpc *vpc, const struct tgsi_full_src_register *fsrc) { src.swz[1] = fsrc->Register.SwizzleY; src.swz[2] = fsrc->Register.SwizzleZ; src.swz[3] = fsrc->Register.SwizzleW; + src.indirect = 0; + + if(fsrc->Register.Indirect) { + if(fsrc->Indirect.File == TGSI_FILE_ADDRESS && + (fsrc->Register.File == TGSI_FILE_CONSTANT || fsrc->Register.File == TGSI_FILE_INPUT)) + { + src.indirect = 1; + src.indirect_reg = fsrc->Indirect.Index; + src.indirect_swz = fsrc->Indirect.SwizzleX; + } + else + { + src.reg.index = 0; + src.reg.type = -1; + } + } return src; } @@ -461,6 +493,15 @@ nvfx_vertprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, } } + for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { + if(src[i].reg.type < 0) + return FALSE; + } + + if(finst->Dst[0].Register.File == TGSI_FILE_ADDRESS && + finst->Instruction.Opcode != TGSI_OPCODE_ARL) + return FALSE; + dst = tgsi_dst(vpc, &finst->Dst[0]); mask = tgsi_mask(finst->Dst[0].Register.WriteMask); @@ -761,7 +802,7 @@ static boolean nvfx_vertprog_prepare(struct nvfx_context* nvfx, struct nvfx_vpc *vpc) { struct tgsi_parse_context p; - int high_temp = -1, high_addr = -1, nr_imm = 0, i; + int high_const = -1, high_temp = -1, high_addr = -1, nr_imm = 0, i; struct util_semantic_set set; unsigned char sem_layout[8]; unsigned num_outputs; @@ -814,14 +855,18 @@ nvfx_vertprog_prepare(struct nvfx_context* nvfx, struct nvfx_vpc *vpc) fdec->Range.Last; } break; -#if 0 /* this would be nice.. except gallium doesn't track it */ case TGSI_FILE_ADDRESS: if (fdec->Range.Last > high_addr) { high_addr = fdec->Range.Last; } break; -#endif + case TGSI_FILE_CONSTANT: + if (fdec->Range.Last > high_const) { + high_const = + fdec->Range.Last; + } + break; case TGSI_FILE_OUTPUT: if (!nvfx_vertprog_parse_decl_output(nvfx, vpc, fdec)) return FALSE; @@ -831,23 +876,6 @@ nvfx_vertprog_prepare(struct nvfx_context* nvfx, struct nvfx_vpc *vpc) } } break; -#if 1 /* yay, parse instructions looking for address regs instead */ - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - const struct tgsi_full_instruction *finst; - const struct tgsi_full_dst_register *fdst; - - finst = &p.FullToken.FullInstruction; - fdst = &finst->Dst[0]; - - if (fdst->Register.File == TGSI_FILE_ADDRESS) { - if (fdst->Register.Index > high_addr) - high_addr = fdst->Register.Index; - } - - } - break; -#endif default: break; } @@ -868,7 +896,13 @@ nvfx_vertprog_prepare(struct nvfx_context* nvfx, struct nvfx_vpc *vpc) if (++high_addr) { vpc->r_address = CALLOC(high_addr, sizeof(struct nvfx_reg)); for (i = 0; i < high_addr; i++) - vpc->r_address[i] = temp(vpc); + vpc->r_address[i] = nvfx_reg(NVFXSR_TEMP, i); + } + + if(++high_const) { + vpc->r_const = CALLOC(high_const, sizeof(struct nvfx_reg)); + for (i = 0; i < high_const; i++) + vpc->r_const[i] = constant(vpc, i, 0, 0, 0, 0); } vpc->r_temps_discard = 0; @@ -1037,6 +1071,8 @@ out_err: FREE(vpc->r_temp); if (vpc->r_address) FREE(vpc->r_address); + if (vpc->r_const) + FREE(vpc->r_const); if (vpc->imm) FREE(vpc->imm); FREE(vpc); @@ -1116,6 +1152,8 @@ nvfx_vertprog_validate(struct nvfx_context *nvfx) } } + //printf("start at %u nc %u\n", vp->data->start, vp->nr_consts); + /*XXX: handle this some day */ assert(vp->data->start >= vp->data_start_min); @@ -1161,6 +1199,8 @@ nvfx_vertprog_validate(struct nvfx_context *nvfx) struct nvfx_relocation* reloc = (struct nvfx_relocation*)((char*)vp->const_relocs.data + i); struct nvfx_vertex_program_exec *vpi = &vp->insns[reloc->location]; + //printf("reloc %i to %i + %i\n", reloc->location, vp->data->start, reloc->target); + vpi->data[1] &= ~NVFX_VP(INST_CONST_SRC_MASK); vpi->data[1] |= (reloc->target + vp->data->start) << @@ -1178,6 +1218,16 @@ nvfx_vertprog_validate(struct nvfx_context *nvfx) if (constbuf) map = (float*)nvfx_buffer(constbuf)->data; + /* + for (i = 0; i < 512; i++) { + float v[4] = {0.1, 0,2, 0.3, 0.4}; + BEGIN_RING(chan, eng3d, NV34TCL_VP_UPLOAD_CONST_ID, 5); + OUT_RING (chan, i); + OUT_RINGp (chan, (uint32_t *)v, 4); + printf("frob %i\n", i); + } + */ + for (i = nvfx->use_vp_clipping ? 6 : 0; i < vp->nr_consts; i++) { struct nvfx_vertex_program_data *vpd = &vp->consts[i]; @@ -1190,6 +1240,8 @@ nvfx_vertprog_validate(struct nvfx_context *nvfx) 4 * sizeof(float)); } + //printf("upload into %i + %i: %f %f %f %f\n", vp->data->start, i, vpd->value[0], vpd->value[1], vpd->value[2], vpd->value[3]); + BEGIN_RING(chan, eng3d, NV34TCL_VP_UPLOAD_CONST_ID, 5); OUT_RING (chan, i + vp->data->start); OUT_RINGp (chan, (uint32_t *)vpd->value, 4); @@ -1202,6 +1254,7 @@ nvfx_vertprog_validate(struct nvfx_context *nvfx) OUT_RING (chan, vp->exec->start); for (i = 0; i < vp->nr_insns; i++) { BEGIN_RING(chan, eng3d, NV34TCL_VP_UPLOAD_INST(0), 4); + //printf("%08x %08x %08x %08x\n", vp->insns[i].data[0], vp->insns[i].data[1], vp->insns[i].data[2], vp->insns[i].data[3]); OUT_RINGp (chan, vp->insns[i].data, 4); } vp->clip_nr = -1; |