summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-06-28 12:26:19 -0700
committerEric Anholt <[email protected]>2010-06-28 12:26:19 -0700
commit904b5bfe9986a297dc71fe081ce0f2661d43b00b (patch)
tree509c7b02f776c824816657f0b393114a45fa59b6 /src
parentcbe52c8012659abe5d81cf1180659820e704d290 (diff)
ir_to_mesa: Add support for the pow expression.
Fixes glsl-algebraic-pow-two.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/shader/ir_to_mesa.cpp48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp
index 85aedd69676..30d05c39ef4 100644
--- a/src/mesa/shader/ir_to_mesa.cpp
+++ b/src/mesa/shader/ir_to_mesa.cpp
@@ -167,6 +167,12 @@ public:
ir_to_mesa_dst_reg dst,
ir_to_mesa_src_reg src0);
+ void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1);
+
void *mem_ctx;
};
@@ -309,10 +315,11 @@ ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
* to produce dest channels.
*/
void
-ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
enum prog_opcode op,
ir_to_mesa_dst_reg dst,
- ir_to_mesa_src_reg src0)
+ ir_to_mesa_src_reg orig_src0,
+ ir_to_mesa_src_reg orig_src1)
{
int i, j;
int done_mask = ~dst.writemask;
@@ -324,28 +331,48 @@ ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
for (i = 0; i < 4; i++) {
GLuint this_mask = (1 << i);
ir_to_mesa_instruction *inst;
- ir_to_mesa_src_reg src = src0;
+ ir_to_mesa_src_reg src0 = orig_src0;
+ ir_to_mesa_src_reg src1 = orig_src1;
if (done_mask & this_mask)
continue;
- GLuint src_swiz = GET_SWZ(src.swizzle, i);
+ GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
+ GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
for (j = i + 1; j < 4; j++) {
- if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
+ if (!(done_mask & (1 << j)) &&
+ GET_SWZ(src0.swizzle, j) == src0_swiz &&
+ GET_SWZ(src1.swizzle, j) == src1_swiz) {
this_mask |= (1 << j);
}
}
- src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,
- src_swiz, src_swiz);
+ src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
+ src0_swiz, src0_swiz);
+ src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
+ src1_swiz, src1_swiz);
- inst = ir_to_mesa_emit_op1(ir, op,
+ inst = ir_to_mesa_emit_op2(ir, op,
dst,
- src);
+ src0,
+ src1);
inst->dst_reg.writemask = this_mask;
done_mask |= this_mask;
}
}
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0)
+{
+ ir_to_mesa_src_reg undef;
+
+ undef.swizzle = SWIZZLE_XXXX;
+
+ ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
+}
+
struct ir_to_mesa_src_reg
ir_to_mesa_visitor::src_reg_for_float(float val)
{
@@ -711,6 +738,9 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_binop_max:
ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
break;
+ case ir_binop_pow:
+ ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
+ break;
default:
ir_print_visitor v;
printf("Failed to get tree for expression:\n");