--- src/glsl/link_atomics.cpp | 73 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 18 deletions(-)
diff --git a/src/glsl/link_atomics.cpp b/src/glsl/link_atomics.cpp index 100d03c..21f9af7 100644 --- a/src/glsl/link_atomics.cpp +++ b/src/glsl/link_atomics.cpp @@ -95,6 +95,56 @@ namespace { y->data.atomic.offset < x->data.atomic.offset + x->type->atomic_size())); } + void + process_atomic_variable(const glsl_type *t, struct gl_shader_program *prog, + char **name, size_t name_length, ir_variable *var, + active_atomic_buffer *const buffers, + unsigned *num_buffers, int *offset, + const unsigned shader_stage) + { + /* FIXME: Arrays of arrays get counted separately. For example: + * x1[3][3][2] = 9 counters + * x2[3][2] = 3 counters + * x3[2] = 1 counter + * + * However this code marks all the counters as active even when they + * might not be used. + */ + if (t->is_array() && t->fields.array->is_array()) { + for (unsigned i = 0; i < t->length; i++) { + size_t new_length = name_length; + + /* Append the subscript to the current variable name */ + ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); + + process_atomic_variable(t->fields.array, prog, name, new_length, + var, buffers, num_buffers, offset, + shader_stage); + } + } else { + unsigned id = 0; + bool found = prog->UniformHash->get(id, *name); + assert(found); + (void) found; + active_atomic_buffer *buf = &buffers[var->data.binding]; + gl_uniform_storage *const storage = &prog->UniformStorage[id]; + + /* If this is the first time the buffer is used, increment + * the counter of buffers used. + */ + if (buf->size == 0) + (*num_buffers)++; + + buf->push_back(id, var); + + buf->stage_references[shader_stage]++; + buf->size = MAX2(buf->size, *offset + t->atomic_size()); + + storage->offset = *offset; + *offset += t->atomic_size(); + } + } + active_atomic_buffer * find_active_atomic_counters(struct gl_context *ctx, struct gl_shader_program *prog, @@ -114,23 +164,11 @@ namespace { ir_variable *var = node->as_variable(); if (var && var->type->contains_atomic()) { - unsigned id = 0; - bool found = prog->UniformHash->get(id, var->name); - assert(found); - (void) found; - active_atomic_buffer *buf = &buffers[var->data.binding]; - - /* If this is the first time the buffer is used, increment - * the counter of buffers used. - */ - if (buf->size == 0) - (*num_buffers)++; - - buf->push_back(id, var); - - buf->stage_references[i]++; - buf->size = MAX2(buf->size, var->data.atomic.offset + - var->type->atomic_size()); + char *name = ralloc_strdup(NULL, var->name); + int offset = var->data.atomic.offset; + process_atomic_variable(var->type, prog, &name, strlen(name), + var, buffers, num_buffers, &offset, i); + ralloc_free(name); } } } @@ -205,7 +243,6 @@ link_assign_atomic_counter_resources(struct gl_context *ctx, var->data.binding = i; storage->atomic_buffer_index = i; - storage->offset = var->data.atomic.offset; storage->array_stride = (var->type->is_array() ? var->type->without_array()->atomic_size() : 0); } -- 2.4.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev