ir_to_mesa: Handle swizzles on LHS of assignment (writemasks).
This commit is contained in:
@@ -139,6 +139,16 @@ ir_to_mesa_emit_scalar_op1(struct mbtree *tree, enum prog_opcode op,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 *
|
struct mbtree *
|
||||||
ir_to_mesa_visitor::create_tree(int op,
|
ir_to_mesa_visitor::create_tree(int op,
|
||||||
ir_instruction *ir,
|
ir_instruction *ir,
|
||||||
@@ -153,6 +163,8 @@ ir_to_mesa_visitor::create_tree(int op,
|
|||||||
tree->right = right;
|
tree->right = right;
|
||||||
tree->v = this;
|
tree->v = this;
|
||||||
tree->src_reg.swizzle = SWIZZLE_XYZW;
|
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;
|
tree->ir = ir;
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
@@ -167,8 +179,7 @@ ir_to_mesa_visitor::create_tree(int op,
|
|||||||
void
|
void
|
||||||
ir_to_mesa_visitor::get_temp(struct mbtree *tree)
|
ir_to_mesa_visitor::get_temp(struct mbtree *tree)
|
||||||
{
|
{
|
||||||
tree->src_reg.file = PROGRAM_TEMPORARY;
|
ir_to_mesa_set_tree_reg(tree, PROGRAM_TEMPORARY, this->next_temp++);
|
||||||
tree->src_reg.index = this->next_temp++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -180,8 +191,7 @@ ir_to_mesa_visitor::get_temp_for_var(ir_variable *var, struct mbtree *tree)
|
|||||||
entry = (temp_entry *)iter.get();
|
entry = (temp_entry *)iter.get();
|
||||||
|
|
||||||
if (entry->var == var) {
|
if (entry->var == var) {
|
||||||
tree->src_reg.file = entry->file;
|
ir_to_mesa_set_tree_reg(tree, entry->file, entry->index);
|
||||||
tree->src_reg.index = entry->index;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,8 +199,7 @@ ir_to_mesa_visitor::get_temp_for_var(ir_variable *var, struct mbtree *tree)
|
|||||||
entry = new temp_entry(var, PROGRAM_TEMPORARY, this->next_temp++);
|
entry = new temp_entry(var, PROGRAM_TEMPORARY, this->next_temp++);
|
||||||
this->variable_storage.push_tail(entry);
|
this->variable_storage.push_tail(entry);
|
||||||
|
|
||||||
tree->src_reg.file = entry->file;
|
ir_to_mesa_set_tree_reg(tree, entry->file, entry->index);
|
||||||
tree->src_reg.index = entry->index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -351,7 +360,10 @@ ir_to_mesa_visitor::visit(ir_swizzle *ir)
|
|||||||
int i;
|
int i;
|
||||||
int swizzle[4];
|
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);
|
ir->val->accept(this);
|
||||||
assert(this->result);
|
assert(this->result);
|
||||||
@@ -410,12 +422,11 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
|
|||||||
*/
|
*/
|
||||||
assert(!var->type->is_matrix());
|
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 (strncmp(var->name, "gl_", 3) == 0) {
|
||||||
if (strcmp(var->name, "gl_FragColor") == 0) {
|
if (strcmp(var->name, "gl_FragColor") == 0) {
|
||||||
tree->src_reg.file = PROGRAM_INPUT;
|
ir_to_mesa_set_tree_reg(tree, PROGRAM_INPUT, FRAG_ATTRIB_COL0);
|
||||||
tree->src_reg.index = FRAG_ATTRIB_COL0;
|
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@@ -442,17 +453,14 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
|
|||||||
|
|
||||||
ir_variable *var = ir->array->as_variable();
|
ir_variable *var = ir->array->as_variable();
|
||||||
ir_constant *index = ir->array_index->constant_expression_value();
|
ir_constant *index = ir->array_index->constant_expression_value();
|
||||||
char *name;
|
|
||||||
|
|
||||||
assert(var);
|
assert(var);
|
||||||
assert(index);
|
assert(index);
|
||||||
assert(strcmp(var->name, "gl_TexCoord") == 0);
|
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 = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
|
||||||
tree->src_reg.file = PROGRAM_INPUT;
|
ir_to_mesa_set_tree_reg(tree, PROGRAM_INPUT,
|
||||||
tree->src_reg.index = FRAG_ATTRIB_TEX0 + index->value.i[0];
|
FRAG_ATTRIB_TEX0 + index->value.i[0]);
|
||||||
tree->reg_name = name;
|
|
||||||
|
|
||||||
/* If the type is smaller than a vec4, replicate the last channel out. */
|
/* If the type is smaller than a vec4, replicate the last channel out. */
|
||||||
tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
|
tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
|
||||||
@@ -460,6 +468,34 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
|
|||||||
this->result = tree;
|
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
|
void
|
||||||
ir_to_mesa_visitor::visit(ir_dereference_record *ir)
|
ir_to_mesa_visitor::visit(ir_dereference_record *ir)
|
||||||
{
|
{
|
||||||
@@ -472,8 +508,8 @@ ir_to_mesa_visitor::visit(ir_assignment *ir)
|
|||||||
{
|
{
|
||||||
struct mbtree *l, *r, *t;
|
struct mbtree *l, *r, *t;
|
||||||
|
|
||||||
ir->lhs->accept(this);
|
l = get_assignment_lhs(ir->lhs, this);
|
||||||
l = this->result;
|
|
||||||
ir->rhs->accept(this);
|
ir->rhs->accept(this);
|
||||||
r = this->result;
|
r = this->result;
|
||||||
assert(l);
|
assert(l);
|
||||||
@@ -504,8 +540,7 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
|
|||||||
*/
|
*/
|
||||||
/* FINISHME: Do something with the constant values for now.
|
/* FINISHME: Do something with the constant values for now.
|
||||||
*/
|
*/
|
||||||
tree->src_reg.file = PROGRAM_CONSTANT;
|
ir_to_mesa_set_tree_reg(tree, PROGRAM_CONSTANT, this->next_constant++);
|
||||||
tree->src_reg.index = this->next_constant++;
|
|
||||||
tree->src_reg.swizzle = SWIZZLE_NOOP;
|
tree->src_reg.swizzle = SWIZZLE_NOOP;
|
||||||
|
|
||||||
this->result = tree;
|
this->result = tree;
|
||||||
|
@@ -69,6 +69,8 @@ struct mbtree {
|
|||||||
/** Pointer to the ir source this tree came from for debugging */
|
/** Pointer to the ir source this tree came from for debugging */
|
||||||
ir_instruction *ir;
|
ir_instruction *ir;
|
||||||
|
|
||||||
|
ir_to_mesa_dst_reg dst_reg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the representation of this tree node's results as a
|
* This is the representation of this tree node's results as a
|
||||||
* source register for its consumer.
|
* source register for its consumer.
|
||||||
|
@@ -105,7 +105,7 @@ vec4: reference_vec4 0
|
|||||||
stmt: assign(vec4, vec4) 1
|
stmt: assign(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op1(tree, OPCODE_MOV,
|
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);
|
tree->right->src_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,14 +126,14 @@ vec4: swizzle_vec4(vec4) 1
|
|||||||
reg.swizzle = MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
|
reg.swizzle = MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
|
||||||
|
|
||||||
ir_to_mesa_emit_op1(tree, OPCODE_MOV,
|
ir_to_mesa_emit_op1(tree, OPCODE_MOV,
|
||||||
ir_to_mesa_dst_reg_from_src(tree->src_reg),
|
tree->dst_reg,
|
||||||
reg);
|
reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4: add_vec4_vec4(vec4, vec4) 1
|
vec4: add_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_ADD,
|
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->left->src_reg,
|
||||||
tree->right->src_reg);
|
tree->right->src_reg);
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ vec4: add_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: sub_vec4_vec4(vec4, vec4) 1
|
vec4: sub_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_SUB,
|
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->left->src_reg,
|
||||||
tree->right->src_reg);
|
tree->right->src_reg);
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ vec4: sub_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: mul_vec4_vec4(vec4, vec4) 1
|
vec4: mul_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_MUL,
|
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->left->src_reg,
|
||||||
tree->right->src_reg);
|
tree->right->src_reg);
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ vec4: mul_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: dp4_vec4_vec4(vec4, vec4) 1
|
vec4: dp4_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_DP4,
|
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->left->src_reg,
|
||||||
tree->right->src_reg);
|
tree->right->src_reg);
|
||||||
tree->src_reg.swizzle = SWIZZLE_XXXX;
|
tree->src_reg.swizzle = SWIZZLE_XXXX;
|
||||||
@@ -166,7 +166,7 @@ vec4: dp4_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: dp3_vec4_vec4(vec4, vec4) 1
|
vec4: dp3_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_DP3,
|
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->left->src_reg,
|
||||||
tree->right->src_reg);
|
tree->right->src_reg);
|
||||||
tree->src_reg.swizzle = SWIZZLE_XXXX;
|
tree->src_reg.swizzle = SWIZZLE_XXXX;
|
||||||
@@ -176,7 +176,7 @@ vec4: dp3_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: dp2_vec4_vec4(vec4, vec4) 1
|
vec4: dp2_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_DP2,
|
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->left->src_reg,
|
||||||
tree->right->src_reg);
|
tree->right->src_reg);
|
||||||
tree->src_reg.swizzle = SWIZZLE_XXXX;
|
tree->src_reg.swizzle = SWIZZLE_XXXX;
|
||||||
@@ -185,11 +185,11 @@ vec4: dp2_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: div_vec4_vec4(vec4, vec4) 1
|
vec4: div_vec4_vec4(vec4, vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_scalar_op1(tree, OPCODE_RCP,
|
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);
|
tree->left->src_reg);
|
||||||
|
|
||||||
ir_to_mesa_emit_op2(tree, OPCODE_MUL,
|
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->src_reg,
|
||||||
tree->left->src_reg);
|
tree->left->src_reg);
|
||||||
}
|
}
|
||||||
@@ -197,11 +197,11 @@ vec4: div_vec4_vec4(vec4, vec4) 1
|
|||||||
vec4: sqrt_vec4(vec4) 1
|
vec4: sqrt_vec4(vec4) 1
|
||||||
{
|
{
|
||||||
ir_to_mesa_emit_scalar_op1(tree, OPCODE_RSQ,
|
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);
|
tree->left->src_reg);
|
||||||
|
|
||||||
ir_to_mesa_emit_op1(tree, OPCODE_RCP,
|
ir_to_mesa_emit_op1(tree, OPCODE_RCP,
|
||||||
ir_to_mesa_dst_reg_from_src(tree->src_reg),
|
tree->dst_reg,
|
||||||
tree->src_reg);
|
tree->src_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user