mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-29 14:30:10 +01:00
glsl: Add methods to copy parts of one ir_constant into another.
- copy_masked_offset copies part of a constant into another, assign-like. - copy_offset copies a constant into (a subset of) another, funcall-return like. These methods are to be used to trace through assignments and function calls when computing a constant expression. Signed-off-by: Olivier Galibert <galibert@pobox.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net> [v1]
This commit is contained in:
parent
a270e86d38
commit
8ec01ba2ff
2 changed files with 114 additions and 0 deletions
|
|
@ -856,6 +856,95 @@ ir_constant::get_record_field(const char *name)
|
|||
return (ir_constant *) node;
|
||||
}
|
||||
|
||||
void
|
||||
ir_constant::copy_offset(ir_constant *src, int offset)
|
||||
{
|
||||
switch (this->type->base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
case GLSL_TYPE_INT:
|
||||
case GLSL_TYPE_FLOAT:
|
||||
case GLSL_TYPE_BOOL: {
|
||||
unsigned int size = src->type->components();
|
||||
assert (size <= this->type->components() - offset);
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
switch (this->type->base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
value.u[i+offset] = src->get_uint_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_INT:
|
||||
value.i[i+offset] = src->get_int_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_FLOAT:
|
||||
value.f[i+offset] = src->get_float_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_BOOL:
|
||||
value.b[i+offset] = src->get_bool_component(i);
|
||||
break;
|
||||
default: // Shut up the compiler
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GLSL_TYPE_STRUCT: {
|
||||
assert (src->type == this->type);
|
||||
this->components.make_empty();
|
||||
foreach_list(node, &src->components) {
|
||||
ir_constant *const orig = (ir_constant *) node;
|
||||
|
||||
this->components.push_tail(orig->clone(this, NULL));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GLSL_TYPE_ARRAY: {
|
||||
assert (src->type == this->type);
|
||||
for (unsigned i = 0; i < this->type->length; i++) {
|
||||
this->array_elements[i] = src->array_elements[i]->clone(this, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
|
||||
{
|
||||
assert (!type->is_array() && !type->is_record());
|
||||
|
||||
if (!type->is_vector() && !type->is_matrix()) {
|
||||
offset = 0;
|
||||
mask = 1;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
for (int i=0; i<4; i++) {
|
||||
if (mask & (1 << i)) {
|
||||
switch (this->type->base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
value.u[i+offset] = src->get_uint_component(id++);
|
||||
break;
|
||||
case GLSL_TYPE_INT:
|
||||
value.i[i+offset] = src->get_int_component(id++);
|
||||
break;
|
||||
case GLSL_TYPE_FLOAT:
|
||||
value.f[i+offset] = src->get_float_component(id++);
|
||||
break;
|
||||
case GLSL_TYPE_BOOL:
|
||||
value.b[i+offset] = src->get_bool_component(id++);
|
||||
break;
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ir_constant::has_value(const ir_constant *c) const
|
||||
|
|
|
|||
|
|
@ -1682,6 +1682,31 @@ public:
|
|||
|
||||
ir_constant *get_record_field(const char *name);
|
||||
|
||||
/**
|
||||
* Copy the values on another constant at a given offset.
|
||||
*
|
||||
* The offset is ignored for array or struct copies, it's only for
|
||||
* scalars or vectors into vectors or matrices.
|
||||
*
|
||||
* With identical types on both sides and zero offset it's clone()
|
||||
* without creating a new object.
|
||||
*/
|
||||
|
||||
void copy_offset(ir_constant *src, int offset);
|
||||
|
||||
/**
|
||||
* Copy the values on another constant at a given offset and
|
||||
* following an assign-like mask.
|
||||
*
|
||||
* The mask is ignored for scalars.
|
||||
*
|
||||
* Note that this function only handles what assign can handle,
|
||||
* i.e. at most a vector as source and a column of a matrix as
|
||||
* destination.
|
||||
*/
|
||||
|
||||
void copy_masked_offset(ir_constant *src, int offset, unsigned int mask);
|
||||
|
||||
/**
|
||||
* Determine whether a constant has the same value as another constant
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue