diff options
author | Roy Spliet <[email protected]> | 2012-07-19 01:56:35 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2012-07-20 20:31:40 +0200 |
commit | 542bd6941f5a56f7a3aa84b44d92591488b146bf (patch) | |
tree | d9f09d08d1681332bd69fe3933c7719261a19b68 /src | |
parent | 248e6f03313afdfd3c23be269b0da7a1aa31cff2 (diff) |
nv30: Support negative offsets in indirect constant access.
Fixes piglit vp-address-01 amongst several others.
Signed-off-by: Roy Spliet <[email protected]>
Reviewed-by: Lucas Stach <[email protected]>
Tested-by: Lucas Stach <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/nv30/nv30_state.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nv30_vertprog.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nvfx_shader.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv30/nvfx_vertprog.c | 13 |
4 files changed, 15 insertions, 8 deletions
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h index 964676a90e1..e27e16fae82 100644 --- a/src/gallium/drivers/nv30/nv30_state.h +++ b/src/gallium/drivers/nv30/nv30_state.h @@ -63,7 +63,7 @@ struct nv30_sampler_view { struct nv30_shader_reloc { unsigned location; - unsigned target; + int target; }; struct nv30_vertprog_exec { diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index 9b5ba35fe1e..06e1b8cdf35 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -149,8 +149,8 @@ nv30_vertprog_validate(struct nv30_context *nv30) inst = vp->insns[reloc->location].data; target = vp->data->start + reloc->target; - inst[1] &= ~0x0003fc000; - inst[1] |= target << 14; + inst[1] &= ~0x0007fc000; + inst[1] |= (target & 0x1ff) << 14; reloc++; } } else { @@ -159,7 +159,7 @@ nv30_vertprog_validate(struct nv30_context *nv30) target = vp->data->start + reloc->target; inst[1] &= ~0x0001ff000; - inst[1] |= target << 12; + inst[1] |= (target & 0x1ff) << 12; reloc++; } } diff --git a/src/gallium/drivers/nv30/nvfx_shader.h b/src/gallium/drivers/nv30/nvfx_shader.h index e343bf01698..987e1b043dd 100644 --- a/src/gallium/drivers/nv30/nvfx_shader.h +++ b/src/gallium/drivers/nv30/nvfx_shader.h @@ -416,7 +416,7 @@ struct nvfx_reg { int8_t type; - uint32_t index; + int32_t index; }; struct nvfx_src { diff --git a/src/gallium/drivers/nv30/nvfx_vertprog.c b/src/gallium/drivers/nv30/nvfx_vertprog.c index f41f82d49ed..827d518cb54 100644 --- a/src/gallium/drivers/nv30/nvfx_vertprog.c +++ b/src/gallium/drivers/nv30/nvfx_vertprog.c @@ -135,12 +135,13 @@ emit_src(struct nv30_context *nv30, struct nvfx_vpc *vpc, uint32_t *hw, case NVFXSR_CONST: sr |= (NVFX_VP(SRC_REG_TYPE_CONST) << NVFX_VP(SRC_REG_TYPE_SHIFT)); - if (src.reg.index < 512) { + if (src.reg.index < 256 && src.reg.index >= -256) { reloc.location = vp->nr_insns - 1; reloc.target = src.reg.index; util_dynarray_append(&vp->const_relocs, struct nvfx_relocation, reloc); } else { - hw[1] |= (src.reg.index - 512) << NVFX_VP(INST_CONST_SRC_SHIFT); + hw[1] |= (src.reg.index << NVFX_VP(INST_CONST_SRC_SHIFT)) & + NVFX_VP(INST_CONST_SRC_MASK); } break; case NVFXSR_NONE: @@ -169,6 +170,7 @@ emit_src(struct nv30_context *nv30, struct nvfx_vpc *vpc, uint32_t *hw, 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); @@ -367,7 +369,12 @@ 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 = vpc->r_const[fsrc->Register.Index]; + if(fsrc->Register.Indirect) { + src.reg = vpc->r_const[0]; + src.reg.index = fsrc->Register.Index; + } else { + src.reg = vpc->r_const[fsrc->Register.Index]; + } break; case TGSI_FILE_IMMEDIATE: src.reg = vpc->imm[fsrc->Register.Index]; |