mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 15:48:36 +02:00
ir_to_mesa: Add support for variable indexing of temporary arrays.
Fixes loop-01.vert, loop-02.vert.
This commit is contained in:
parent
4e5e0f018b
commit
bdbd9f112e
3 changed files with 38 additions and 7 deletions
|
|
@ -51,7 +51,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_to_mesa_src_reg ir_to_mesa_undef = {
|
ir_to_mesa_src_reg ir_to_mesa_undef = {
|
||||||
PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
|
PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, false,
|
||||||
};
|
};
|
||||||
|
|
||||||
ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
|
ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
|
||||||
|
|
@ -659,13 +659,11 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
|
||||||
*/
|
*/
|
||||||
assert(!var->type->is_matrix());
|
assert(!var->type->is_matrix());
|
||||||
|
|
||||||
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) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
|
|
||||||
assert(index); /* FINISHME: Handle variable indexing of builtins. */
|
tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
|
||||||
|
|
||||||
offset = index->value.i[0];
|
offset = index->value.i[0];
|
||||||
|
|
||||||
|
|
@ -677,11 +675,24 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
|
||||||
ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file,
|
ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file,
|
||||||
builtin_var_to_mesa_reg[i].index + offset);
|
builtin_var_to_mesa_reg[i].index + offset);
|
||||||
} else {
|
} else {
|
||||||
|
tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
|
||||||
this->get_temp_for_var(var, tree);
|
this->get_temp_for_var(var, tree);
|
||||||
assert(index); /* FINISHME: Handle variable indexing. */
|
|
||||||
|
|
||||||
tree->src_reg.index += index->value.i[0];
|
if (index) {
|
||||||
tree->dst_reg.index += index->value.i[0];
|
tree->src_reg.index += index->value.i[0];
|
||||||
|
tree->dst_reg.index += index->value.i[0];
|
||||||
|
} else {
|
||||||
|
/* Variable index array dereference. It eats the "vec4" of the
|
||||||
|
* base of the array and an index that offsets the Mesa register
|
||||||
|
* index.
|
||||||
|
*/
|
||||||
|
ir->array_index->accept(this);
|
||||||
|
|
||||||
|
tree->src_reg.reladdr = true;
|
||||||
|
tree = this->create_tree(MB_TERM_array_reference_vec4_vec4,
|
||||||
|
ir, tree, this->result);
|
||||||
|
this->get_temp(tree, ir->type->vector_elements);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. */
|
||||||
|
|
@ -841,6 +852,7 @@ mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
|
||||||
assert(reg.index < (1 << INST_INDEX_BITS) - 1);
|
assert(reg.index < (1 << INST_INDEX_BITS) - 1);
|
||||||
mesa_reg.Index = reg.index;
|
mesa_reg.Index = reg.index;
|
||||||
mesa_reg.Swizzle = reg.swizzle;
|
mesa_reg.Swizzle = reg.swizzle;
|
||||||
|
mesa_reg.RelAddr = reg.reladdr;
|
||||||
|
|
||||||
return mesa_reg;
|
return mesa_reg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ typedef struct ir_to_mesa_src_reg {
|
||||||
int file; /**< PROGRAM_* from Mesa */
|
int file; /**< PROGRAM_* from Mesa */
|
||||||
int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
|
int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
|
||||||
int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
|
int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
|
||||||
|
bool reladdr; /**< Register index should be offset by address reg. */
|
||||||
} ir_to_mesa_src_reg;
|
} ir_to_mesa_src_reg;
|
||||||
|
|
||||||
typedef struct ir_to_mesa_dst_reg {
|
typedef struct ir_to_mesa_dst_reg {
|
||||||
|
|
@ -145,6 +146,9 @@ public:
|
||||||
exec_list instructions;
|
exec_list instructions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern ir_to_mesa_src_reg ir_to_mesa_undef;
|
||||||
|
extern ir_to_mesa_dst_reg ir_to_mesa_undef_dst;
|
||||||
|
|
||||||
ir_to_mesa_instruction *
|
ir_to_mesa_instruction *
|
||||||
ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op);
|
ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
# generate in its trees.
|
# generate in its trees.
|
||||||
%term assign
|
%term assign
|
||||||
%term reference_vec4
|
%term reference_vec4
|
||||||
|
%term array_reference_vec4_vec4
|
||||||
%term exp_vec4
|
%term exp_vec4
|
||||||
%term exp2_vec4
|
%term exp2_vec4
|
||||||
%term log_vec4
|
%term log_vec4
|
||||||
|
|
@ -93,6 +94,20 @@
|
||||||
# so it can be used as an argument for pretty much anything.
|
# so it can be used as an argument for pretty much anything.
|
||||||
vec4: reference_vec4 0
|
vec4: reference_vec4 0
|
||||||
|
|
||||||
|
# A reference of a variable is just a vec4 register location,
|
||||||
|
# so it can be used as an argument for pretty much anything.
|
||||||
|
vec4: array_reference_vec4_vec4 1
|
||||||
|
{
|
||||||
|
ir_to_mesa_dst_reg address_reg = {PROGRAM_ADDRESS, 0, WRITEMASK_X};
|
||||||
|
|
||||||
|
ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_ARL,
|
||||||
|
address_reg,
|
||||||
|
tree->right->src_reg);
|
||||||
|
ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_MOV,
|
||||||
|
tree->dst_reg,
|
||||||
|
tree->left->src_reg);
|
||||||
|
}
|
||||||
|
|
||||||
# Here's the rule everyone will hit: Moving the result of an
|
# Here's the rule everyone will hit: Moving the result of an
|
||||||
# expression into a variable-dereference register location.
|
# expression into a variable-dereference register location.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue