summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-09-25 16:09:24 +0200
committerMarek Olšák <[email protected]>2012-09-27 19:14:44 +0200
commit836325bf7edd797e02ab0717a05ca5c51aa1ac93 (patch)
tree933b3f5e3c4ff000f04db7b76a97cff5ca2b213c /src/gallium/drivers/r600
parent933faae2b8669f459e7ab27d6bcbfb6f4136b6d5 (diff)
r600g: fix instance divisor on Cayman
Not sure if this is the best way to fix it. NOTE: This is a candidate for the stable branches.
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/r600_asm.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 58350c6f75d..63bd8e9058b 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -2758,31 +2758,47 @@ int r600_vertex_elements_build_fetch_shader(struct r600_context *rctx, struct r6
unsigned fetch_resource_start = rctx->chip_class >= EVERGREEN ? 0 : 160;
unsigned format, num_format, format_comp, endian;
uint32_t *bytecode;
- int i, r;
+ int i, j, r;
memset(&bc, 0, sizeof(bc));
r600_bytecode_init(&bc, rctx->chip_class, rctx->family);
for (i = 0; i < ve->count; i++) {
if (elements[i].instance_divisor > 1) {
- struct r600_bytecode_alu alu;
-
- memset(&alu, 0, sizeof(alu));
- alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT);
- alu.src[0].sel = 0;
- alu.src[0].chan = 3;
-
- alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
- alu.src[1].value = (1ll << 32) / elements[i].instance_divisor + 1;
-
- alu.dst.sel = i + 1;
- alu.dst.chan = 3;
- alu.dst.write = 1;
- alu.last = 1;
-
- if ((r = r600_bytecode_add_alu(&bc, &alu))) {
- r600_bytecode_clear(&bc);
- return r;
+ if (rctx->chip_class == CAYMAN) {
+ for (j = 0; j < 4; j++) {
+ struct r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(alu));
+ alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT);
+ alu.src[0].sel = 0;
+ alu.src[0].chan = 3;
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[1].value = (1ll << 32) / elements[i].instance_divisor + 1;
+ alu.dst.sel = i + 1;
+ alu.dst.chan = j;
+ alu.dst.write = j == 3;
+ alu.last = j == 3;
+ if ((r = r600_bytecode_add_alu(&bc, &alu))) {
+ r600_bytecode_clear(&bc);
+ return r;
+ }
+ }
+ } else {
+ struct r600_bytecode_alu alu;
+ memset(&alu, 0, sizeof(alu));
+ alu.inst = BC_INST(&bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT);
+ alu.src[0].sel = 0;
+ alu.src[0].chan = 3;
+ alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+ alu.src[1].value = (1ll << 32) / elements[i].instance_divisor + 1;
+ alu.dst.sel = i + 1;
+ alu.dst.chan = 3;
+ alu.dst.write = 1;
+ alu.last = 1;
+ if ((r = r600_bytecode_add_alu(&bc, &alu))) {
+ r600_bytecode_clear(&bc);
+ return r;
+ }
}
}
}