[Mesa-dev] [PATCH 04/19] glsl: Add support for linking uniform arrays of arrays
Timothy Arceri
t_arceri at yahoo.com.au
Sat Jun 20 05:33:01 PDT 2015
---
src/glsl/link_uniform_initializers.cpp | 51 ++++++++++++++++++++++++----------
src/glsl/link_uniforms.cpp | 28 +++++++++++--------
2 files changed, 52 insertions(+), 27 deletions(-)
diff --git a/src/glsl/link_uniform_initializers.cpp b/src/glsl/link_uniform_initializers.cpp
index 204acfa..6164bdd 100644
--- a/src/glsl/link_uniform_initializers.cpp
+++ b/src/glsl/link_uniform_initializers.cpp
@@ -100,6 +100,38 @@ copy_constant_to_storage(union gl_constant_value *storage,
}
void
+copy_constant_array_to_storage(struct gl_uniform_storage *const storage,
+ const ir_constant *val,
+ unsigned int *idx,
+ unsigned int *array_elements,
+ unsigned int boolean_true)
+{
+ if (val->type->fields.array->is_array()) {
+ for (unsigned int i = 0; i < val->type->length; i++) {
+ copy_constant_array_to_storage(storage, val->array_elements[i],
+ idx, array_elements, boolean_true);
+ }
+ } else {
+ const enum glsl_base_type base_type =
+ val->array_elements[0]->type->base_type;
+ const unsigned int elements = val->array_elements[0]->type->components();
+ unsigned dmul = (base_type == GLSL_TYPE_DOUBLE) ? 2 : 1;
+ unsigned int length = MIN2(val->type->length,
+ (storage->array_elements - *array_elements));
+
+ for (unsigned int i = 0; i < length; i++) {
+ copy_constant_to_storage(& storage->storage[*idx],
+ val->array_elements[i],
+ base_type,
+ elements,
+ boolean_true);
+ *idx += elements * dmul;
+ *array_elements = *array_elements + 1;
+ }
+ }
+}
+
+void
set_sampler_binding(gl_shader_program *prog, const char *name, int binding)
{
struct gl_uniform_storage *const storage =
@@ -178,7 +210,7 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
field_constant = (ir_constant *)field_constant->next;
}
return;
- } else if (type->is_array() && type->fields.array->is_record()) {
+ } else if (type->without_array()->is_record()) {
const glsl_type *const element_type = type->fields.array;
for (unsigned int i = 0; i < type->length; i++) {
@@ -201,22 +233,11 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
}
if (val->type->is_array()) {
- const enum glsl_base_type base_type =
- val->array_elements[0]->type->base_type;
- const unsigned int elements = val->array_elements[0]->type->components();
unsigned int idx = 0;
- unsigned dmul = (base_type == GLSL_TYPE_DOUBLE) ? 2 : 1;
+ unsigned int array_elements = 0;
- assert(val->type->length >= storage->array_elements);
- for (unsigned int i = 0; i < storage->array_elements; i++) {
- copy_constant_to_storage(& storage->storage[idx],
- val->array_elements[i],
- base_type,
- elements,
- boolean_true);
-
- idx += elements * dmul;
- }
+ copy_constant_array_to_storage(storage, val, &idx,
+ &array_elements, boolean_true);
} else {
copy_constant_to_storage(storage->storage,
val,
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 11ae06f..6b6b197 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -49,8 +49,8 @@ values_for_type(const glsl_type *type)
{
if (type->is_sampler()) {
return 1;
- } else if (type->is_array() && type->fields.array->is_sampler()) {
- return type->array_size();
+ } else if (type->is_array()) {
+ return type->array_size() * values_for_type(type->fields.array);
} else {
return type->component_slots();
}
@@ -71,6 +71,7 @@ void
program_resource_visitor::process(ir_variable *var)
{
const glsl_type *t = var->type;
+ const glsl_type *t_without_array = var->type->without_array();
const bool row_major =
var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
@@ -136,7 +137,7 @@ program_resource_visitor::process(ir_variable *var)
*/
recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
- } else if (t->without_array()->is_record()) {
+ } else if (t_without_array->is_record()) {
char *name = ralloc_strdup(NULL, var->name);
recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
@@ -144,8 +145,8 @@ program_resource_visitor::process(ir_variable *var)
char *name = ralloc_strdup(NULL, var->type->name);
recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
- } else if (t->is_array() && t->fields.array->is_interface()) {
- char *name = ralloc_strdup(NULL, var->type->fields.array->name);
+ } else if (t_without_array->is_interface()) {
+ char *name = ralloc_strdup(NULL, t_without_array->name);
recursion(var->type, &name, strlen(name), row_major, NULL, false);
ralloc_free(name);
} else {
@@ -216,8 +217,8 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
(*name)[name_length] = '\0';
this->leave_record(t, *name, row_major);
}
- } else if (t->is_array() && (t->fields.array->is_record()
- || t->fields.array->is_interface())) {
+ } else if (t->without_array()->is_record()
+ || t->without_array()->is_interface()) {
if (record_type == NULL && t->fields.array->is_record())
record_type = t->fields.array;
@@ -578,8 +579,12 @@ private:
const glsl_type *base_type;
if (type->is_array()) {
- this->uniforms[id].array_elements = type->length;
- base_type = type->fields.array;
+ this->uniforms[id].array_elements = type->length;
+ base_type = type->fields.array;
+ while (base_type->is_array()) {
+ this->uniforms[id].array_elements *= base_type->length;
+ base_type = base_type->fields.array;
+ }
} else {
this->uniforms[id].array_elements = 0;
base_type = type;
@@ -639,7 +644,7 @@ private:
if (type->is_array()) {
this->uniforms[id].array_stride =
- glsl_align(type->fields.array->std140_size(row_major), 16);
+ glsl_align(type->without_array()->std140_size(row_major), 16);
} else {
this->uniforms[id].array_stride = 0;
}
@@ -778,8 +783,7 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
if (var->type->is_record()) {
sentinel = '.';
- } else if (var->type->is_array()
- && var->type->fields.array->is_record()) {
+ } else if (var->type->without_array()->is_record()) {
sentinel = '[';
}
--
2.1.0
More information about the mesa-dev
mailing list