diff options
author | Eric Anholt <eric@anholt.net> | 2010-07-20 11:14:33 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-07-20 11:28:33 -0700 |
commit | 18ab797d3aff776833fac1bd0ea01a2750f377b1 (patch) | |
tree | 90a7be77a103d293b02668e65eaf2ed5df266313 | |
parent | cd6764ed6ec5ae1a4bce636feaf9d4b18ff3ccf3 (diff) |
ir_to_mesa: Fix swizzled writemasks with swapped component ordering.
I hadn't noticed you could do this, but glsl1 tests caught it. Fixes:
glsl1-Swizzled writemask
glsl1-Swizzled writemask (2)
glsl1-Swizzled writemask (rgba)
glsl1-Swizzled writemask (stpq)
-rw-r--r-- | src/mesa/shader/ir_to_mesa.cpp | 61 |
1 files changed, 27 insertions, 34 deletions
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index 557f5d319d..848fb0fb6c 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -1263,7 +1263,8 @@ ir_to_mesa_visitor::visit(ir_dereference_record *ir) * those, then go use ir_dereference to handle the rest. */ static struct ir_to_mesa_dst_reg -get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v) +get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v, + ir_to_mesa_src_reg *r) { struct ir_to_mesa_dst_reg dst_reg; ir_swizzle *swiz; @@ -1281,41 +1282,35 @@ get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v) dst_reg = ir_to_mesa_dst_reg_from_src(v->result); if ((swiz = ir->as_swizzle())) { - dst_reg.writemask = 0; - if (swiz->mask.num_components >= 1) - dst_reg.writemask |= (1 << swiz->mask.x); - if (swiz->mask.num_components >= 2) - dst_reg.writemask |= (1 << swiz->mask.y); - if (swiz->mask.num_components >= 3) - dst_reg.writemask |= (1 << swiz->mask.z); - if (swiz->mask.num_components >= 4) - dst_reg.writemask |= (1 << swiz->mask.w); - } - - return dst_reg; -} + int swizzles[4] = { + swiz->mask.x, + swiz->mask.y, + swiz->mask.z, + swiz->mask.w + }; + int new_r_swizzle[4]; + int orig_r_swizzle = r->swizzle; + int i; -static GLuint -reswizzle_for_writemask(GLuint writemask, GLuint swizzle) -{ - int new_swizzle[4], pos = 0; - int i; + for (i = 0; i < 4; i++) { + new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0); + } - /* reswizzle the rhs so the components are in place for the - * components we'll assign to the lhs. - */ - for (i = 0; i < 4; i++) { - if (writemask & (1 << i)) { - new_swizzle[i] = GET_SWZ(swizzle, pos++); - } else { - new_swizzle[i] = GET_SWZ(swizzle, 0); + dst_reg.writemask = 0; + for (i = 0; i < 4; i++) { + if (i < swiz->mask.num_components) { + dst_reg.writemask |= 1 << swizzles[i]; + new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i); + } } + + r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0], + new_r_swizzle[1], + new_r_swizzle[2], + new_r_swizzle[3]); } - return MAKE_SWIZZLE4(new_swizzle[0], - new_swizzle[1], - new_swizzle[2], - new_swizzle[3]); + return dst_reg; } void @@ -1328,12 +1323,10 @@ ir_to_mesa_visitor::visit(ir_assignment *ir) assert(!ir->lhs->type->is_array()); assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT); - l = get_assignment_lhs(ir->lhs, this); - ir->rhs->accept(this); r = this->result; - r.swizzle = reswizzle_for_writemask(l.writemask, r.swizzle); + l = get_assignment_lhs(ir->lhs, this, &r); assert(l.file != PROGRAM_UNDEFINED); assert(r.file != PROGRAM_UNDEFINED); |