diff options
author | Eric Anholt <eric@anholt.net> | 2010-05-06 10:38:40 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-06-24 15:05:20 -0700 |
commit | 315c638b8cf0a92f9f0a8ee496e77e90e4b66d09 (patch) | |
tree | cc74bafe5e6c8a6cf5541611732a8e69abb0ceeb | |
parent | f30100c19c5f4e95e18c03292947de2dbd9e28cf (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.
-rw-r--r-- | ir_to_mesa.cpp | 13 |
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; } |