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:
committed by
Kenneth Graunke
parent
a270e86d38
commit
8ec01ba2ff
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user