summaryrefslogtreecommitdiff
path: root/ir_to_mesa.cpp
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-05-06 10:38:40 -0700
committerEric Anholt <eric@anholt.net>2010-06-24 15:05:20 -0700
commit315c638b8cf0a92f9f0a8ee496e77e90e4b66d09 (patch)
treecc74bafe5e6c8a6cf5541611732a8e69abb0ceeb /ir_to_mesa.cpp
parentf30100c19c5f4e95e18c03292947de2dbd9e28cf (diff)
ir_to_mesa: Fix bugs in swizzle handling for scalar operations.
Looking at a vec2 / float codegen, the writemasks on the RCPs were wrong and the swizzle on the multiply by the RCP results was wrong.
Diffstat (limited to 'ir_to_mesa.cpp')
-rw-r--r--ir_to_mesa.cpp13
1 files changed, 7 insertions, 6 deletions
diff --git a/ir_to_mesa.cpp b/ir_to_mesa.cpp
index a01c50cbc2..35c24ca174 100644
--- a/ir_to_mesa.cpp
+++ b/ir_to_mesa.cpp
@@ -108,7 +108,7 @@ ir_to_mesa_emit_scalar_op1(struct mbtree *tree, enum prog_opcode op,
ir_to_mesa_src_reg src0)
{
int i, j;
- int done_mask = 0;
+ int done_mask = ~dst.writemask;
/* Mesa RCP is a scalar operation splatting results to all channels,
* like ARB_fp/vp. So emit as many RCPs as necessary to cover our
@@ -124,7 +124,7 @@ ir_to_mesa_emit_scalar_op1(struct mbtree *tree, enum prog_opcode op,
int src_swiz = GET_SWZ(src.swizzle, i);
for (j = i + 1; j < 4; j++) {
- if (GET_SWZ(src.swizzle, j) == src_swiz) {
+ if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
this_mask |= (1 << j);
}
}
@@ -179,16 +179,17 @@ ir_to_mesa_visitor::create_tree(int op,
void
ir_to_mesa_visitor::get_temp(struct mbtree *tree, int size)
{
- int swizzle = 0;
+ int swizzle[4];
int i;
ir_to_mesa_set_tree_reg(tree, PROGRAM_TEMPORARY, this->next_temp++);
for (i = 0; i < size; i++)
- swizzle |= 1 << i;
+ swizzle[i] = i;
for (; i < 4; i++)
- swizzle |= 1 << (size - 1);
- tree->src_reg.swizzle = swizzle;
+ swizzle[i] = size - 1;
+ tree->src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
+ swizzle[2], swizzle[3]);
tree->dst_reg.writemask = (1 << size) - 1;
}