summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/program/ir_to_mesa.cpp127
1 files changed, 97 insertions, 30 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index af306f05d8b..ba0934c446d 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -252,9 +252,13 @@ public:
GLboolean try_emit_mad(ir_expression *ir,
int mul_operand);
+ int add_uniform(const char *name,
+ const glsl_type *type,
+ ir_constant *constant);
void add_aggregate_uniform(ir_instruction *ir,
const char *name,
const struct glsl_type *type,
+ ir_constant *constant,
struct ir_to_mesa_dst_reg temp);
int *sampler_map;
@@ -1246,6 +1250,83 @@ get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
return NULL;
}
+int
+ir_to_mesa_visitor::add_uniform(const char *name,
+ const glsl_type *type,
+ ir_constant *constant)
+{
+ int len;
+
+ if (type->is_vector() ||
+ type->is_scalar()) {
+ len = type->vector_elements;
+ } else {
+ len = type_size(type) * 4;
+ }
+
+ float *values = NULL;
+ if (constant && type->is_array()) {
+ values = (float *)malloc(type->length * 4 * sizeof(float));
+
+ assert(type->fields.array->is_scalar() ||
+ type->fields.array->is_vector() ||
+ !"FINISHME: uniform array initializers for non-vector");
+
+ for (unsigned int i = 0; i < type->length; i++) {
+ ir_constant *element = constant->array_elements[i];
+ unsigned int c;
+
+ for (c = 0; c < type->fields.array->vector_elements; c++) {
+ switch (type->fields.array->base_type) {
+ case GLSL_TYPE_FLOAT:
+ values[4 * i + c] = element->value.f[c];
+ break;
+ case GLSL_TYPE_INT:
+ values[4 * i + c] = element->value.i[c];
+ break;
+ case GLSL_TYPE_UINT:
+ values[4 * i + c] = element->value.u[c];
+ break;
+ case GLSL_TYPE_BOOL:
+ values[4 * i + c] = element->value.b[c];
+ break;
+ default:
+ assert(!"not reached");
+ }
+ }
+ }
+ } else if (constant) {
+ values = (float *)malloc(16 * sizeof(float));
+ for (unsigned int i = 0; i < type->components(); i++) {
+ switch (type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ values[i] = constant->value.f[i];
+ break;
+ case GLSL_TYPE_INT:
+ values[i] = constant->value.i[i];
+ break;
+ case GLSL_TYPE_UINT:
+ values[i] = constant->value.u[i];
+ break;
+ case GLSL_TYPE_BOOL:
+ values[i] = constant->value.b[i];
+ break;
+ default:
+ assert(!"not reached");
+ }
+ }
+ }
+
+ int loc = _mesa_add_uniform(this->prog->Parameters,
+ name,
+ len,
+ type->gl_type,
+ values);
+ free(values);
+
+ return loc;
+}
+
/* Recursively add all the members of the aggregate uniform as uniform names
* to Mesa, moving those uniforms to our structured temporary.
*/
@@ -1253,20 +1334,29 @@ void
ir_to_mesa_visitor::add_aggregate_uniform(ir_instruction *ir,
const char *name,
const struct glsl_type *type,
+ ir_constant *constant,
struct ir_to_mesa_dst_reg temp)
{
int loc;
if (type->is_record()) {
void *mem_ctx = talloc_new(NULL);
+ ir_constant *field_constant = NULL;
+
+ if (constant)
+ field_constant = (ir_constant *)constant->components.get_head();
for (unsigned int i = 0; i < type->length; i++) {
const glsl_type *field_type = type->fields.structure[i].type;
+
add_aggregate_uniform(ir,
talloc_asprintf(mem_ctx, "%s.%s", name,
type->fields.structure[i].name),
- field_type, temp);
+ field_type, field_constant, temp);
temp.index += type_size(field_type);
+
+ if (constant)
+ field_constant = (ir_constant *)field_constant->next;
}
talloc_free(mem_ctx);
@@ -1276,21 +1366,7 @@ ir_to_mesa_visitor::add_aggregate_uniform(ir_instruction *ir,
assert(type->is_vector() || type->is_scalar() || !"FINISHME: other types");
- int len;
-
- if (type->is_vector() ||
- type->is_scalar()) {
- len = type->vector_elements;
- } else {
- len = type_size(type) * 4;
- }
-
- loc = _mesa_add_uniform(this->prog->Parameters,
- name,
- len,
- type->gl_type,
- NULL);
-
+ loc = add_uniform(name, type, constant);
ir_to_mesa_src_reg uniform(PROGRAM_UNIFORM, loc, type);
@@ -1307,7 +1383,6 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
{
variable_storage *entry = find_variable_storage(ir->var);
unsigned int loc;
- int len;
if (!entry) {
switch (ir->var->mode) {
@@ -1350,22 +1425,14 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
this->variables.push_tail(entry);
add_aggregate_uniform(ir->var, ir->var->name, ir->var->type,
- ir_to_mesa_dst_reg_from_src(temp));
+ ir->var->constant_value,
+ ir_to_mesa_dst_reg_from_src(temp));
break;
}
- if (ir->var->type->is_vector() ||
- ir->var->type->is_scalar()) {
- len = ir->var->type->vector_elements;
- } else {
- len = type_size(ir->var->type) * 4;
- }
-
- loc = _mesa_add_uniform(this->prog->Parameters,
- ir->var->name,
- len,
- ir->var->type->gl_type,
- NULL);
+ loc = add_uniform(ir->var->name,
+ ir->var->type,
+ ir->var->constant_value);
/* Always mark the uniform used at this point. If it isn't
* used, dead code elimination should have nuked the decl already.