}
}
+static void
+ir_to_mesa_set_tree_reg(struct mbtree *tree, int file, int index)
+{
+ tree->dst_reg.file = file;
+ tree->dst_reg.index = index;
+
+ tree->src_reg.file = file;
+ tree->src_reg.index = index;
+}
+
struct mbtree *
ir_to_mesa_visitor::create_tree(int op,
ir_instruction *ir,
tree->right = right;
tree->v = this;
tree->src_reg.swizzle = SWIZZLE_XYZW;
+ tree->dst_reg.writemask = WRITEMASK_XYZW;
+ ir_to_mesa_set_tree_reg(tree, PROGRAM_UNDEFINED, 0);
tree->ir = ir;
return tree;
void
ir_to_mesa_visitor::get_temp(struct mbtree *tree)
{
- tree->src_reg.file = PROGRAM_TEMPORARY;
- tree->src_reg.index = this->next_temp++;
+ ir_to_mesa_set_tree_reg(tree, PROGRAM_TEMPORARY, this->next_temp++);
}
void
entry = (temp_entry *)iter.get();
if (entry->var == var) {
- tree->src_reg.file = entry->file;
- tree->src_reg.index = entry->index;
+ ir_to_mesa_set_tree_reg(tree, entry->file, entry->index);
return;
}
}
entry = new temp_entry(var, PROGRAM_TEMPORARY, this->next_temp++);
this->variable_storage.push_tail(entry);
- tree->src_reg.file = entry->file;
- tree->src_reg.index = entry->index;
+ ir_to_mesa_set_tree_reg(tree, entry->file, entry->index);
}
static void
int i;
int swizzle[4];
- /* FINISHME: Handle swizzles on the left side of an assignment. */
+ /* Note that this is only swizzles in expressions, not those on the left
+ * hand side of an assignment, which do write masking. See ir_assignment
+ * for that.
+ */
ir->val->accept(this);
assert(this->result);
*/
assert(!var->type->is_matrix());
- tree = this->create_tree(MB_TERM_reference_vec4, NULL, NULL);
+ tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
if (strncmp(var->name, "gl_", 3) == 0) {
if (strcmp(var->name, "gl_FragColor") == 0) {
- tree->src_reg.file = PROGRAM_INPUT;
- tree->src_reg.index = FRAG_ATTRIB_COL0;
+ ir_to_mesa_set_tree_reg(tree, PROGRAM_INPUT, FRAG_ATTRIB_COL0);
} else {
assert(0);
}
ir_variable *var = ir->array->as_variable();
ir_constant *index = ir->array_index->constant_expression_value();
- char *name;
assert(var);
assert(index);
assert(strcmp(var->name, "gl_TexCoord") == 0);
- asprintf(&name, "fragment.texcoord[%d]", index->value.i[0]);
tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
- tree->src_reg.file = PROGRAM_INPUT;
- tree->src_reg.index = FRAG_ATTRIB_TEX0 + index->value.i[0];
- tree->reg_name = name;
+ ir_to_mesa_set_tree_reg(tree, PROGRAM_INPUT,
+ FRAG_ATTRIB_TEX0 + index->value.i[0]);
/* If the type is smaller than a vec4, replicate the last channel out. */
tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
this->result = tree;
}
+static struct mbtree *
+get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
+{
+ struct mbtree *tree = NULL;
+ ir_dereference *deref;
+ ir_swizzle *swiz;
+
+ if ((deref = ir->as_dereference())) {
+ ir->accept(v);
+ tree = v->result;
+ } else if ((swiz = ir->as_swizzle())) {
+ tree = get_assignment_lhs(swiz->val, v);
+ tree->dst_reg.writemask = 0;
+ if (swiz->mask.num_components >= 1)
+ tree->dst_reg.writemask |= (1 << swiz->mask.x);
+ if (swiz->mask.num_components >= 2)
+ tree->dst_reg.writemask |= (1 << swiz->mask.y);
+ if (swiz->mask.num_components >= 3)
+ tree->dst_reg.writemask |= (1 << swiz->mask.z);
+ if (swiz->mask.num_components >= 4)
+ tree->dst_reg.writemask |= (1 << swiz->mask.w);
+ }
+
+ assert(tree);
+
+ return tree;
+}
+
void
ir_to_mesa_visitor::visit(ir_dereference_record *ir)
{
{
struct mbtree *l, *r, *t;
- ir->lhs->accept(this);
- l = this->result;
+ l = get_assignment_lhs(ir->lhs, this);
+
ir->rhs->accept(this);
r = this->result;
assert(l);
*/
/* FINISHME: Do something with the constant values for now.
*/
- tree->src_reg.file = PROGRAM_CONSTANT;
- tree->src_reg.index = this->next_constant++;
+ ir_to_mesa_set_tree_reg(tree, PROGRAM_CONSTANT, this->next_constant++);
tree->src_reg.swizzle = SWIZZLE_NOOP;
this->result = tree;
stmt: assign(vec4, vec4) 1
{
ir_to_mesa_emit_op1(tree, OPCODE_MOV,
- ir_to_mesa_dst_reg_from_src(tree->left->src_reg),
+ tree->left->dst_reg,
tree->right->src_reg);
}
reg.swizzle = MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
ir_to_mesa_emit_op1(tree, OPCODE_MOV,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
reg);
}
vec4: add_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_op2(tree, OPCODE_ADD,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg,
tree->right->src_reg);
}
vec4: sub_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_op2(tree, OPCODE_SUB,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg,
tree->right->src_reg);
}
vec4: mul_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_op2(tree, OPCODE_MUL,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg,
tree->right->src_reg);
}
vec4: dp4_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_op2(tree, OPCODE_DP4,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg,
tree->right->src_reg);
tree->src_reg.swizzle = SWIZZLE_XXXX;
vec4: dp3_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_op2(tree, OPCODE_DP3,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg,
tree->right->src_reg);
tree->src_reg.swizzle = SWIZZLE_XXXX;
vec4: dp2_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_op2(tree, OPCODE_DP2,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg,
tree->right->src_reg);
tree->src_reg.swizzle = SWIZZLE_XXXX;
vec4: div_vec4_vec4(vec4, vec4) 1
{
ir_to_mesa_emit_scalar_op1(tree, OPCODE_RCP,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg);
ir_to_mesa_emit_op2(tree, OPCODE_MUL,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->src_reg,
tree->left->src_reg);
}
vec4: sqrt_vec4(vec4) 1
{
ir_to_mesa_emit_scalar_op1(tree, OPCODE_RSQ,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->left->src_reg);
ir_to_mesa_emit_op1(tree, OPCODE_RCP,
- ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->dst_reg,
tree->src_reg);
}