summaryrefslogtreecommitdiffstats
path: root/src/glsl/link_atomics.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2015-08-30 21:08:22 +1000
committerTimothy Arceri <[email protected]>2015-10-15 21:21:27 +1100
commit2d7a98de18e4cdd69daa63b09b504d01ad4c9f50 (patch)
treea44708fc9fdcdcf6bf949f16524c84677fd2c70b /src/glsl/link_atomics.cpp
parent261a434996079b29a476a3c67e1e580cf3db76ba (diff)
glsl: add AoA support for atomic counters
This marks all counters in an AoA as active. For AoA all but the innermost array are treated as separate counters/uniforms. The Nvidia binary also goes further and finds inactive counters in the AoA, in future we should do this too, however this gets things working for the time being. This change also removes the use of UniformHash for atomic counters, this avoids having to generate name strings used as hash keys. Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/link_atomics.cpp')
-rw-r--r--src/glsl/link_atomics.cpp77
1 files changed, 54 insertions, 23 deletions
diff --git a/src/glsl/link_atomics.cpp b/src/glsl/link_atomics.cpp
index 100d03c4e8f..70ef0e1c891 100644
--- a/src/glsl/link_atomics.cpp
+++ b/src/glsl/link_atomics.cpp
@@ -33,7 +33,7 @@ namespace {
* Atomic counter as seen by the program.
*/
struct active_atomic_counter {
- unsigned id;
+ unsigned uniform_loc;
ir_variable *var;
};
@@ -52,7 +52,7 @@ namespace {
free(counters);
}
- void push_back(unsigned id, ir_variable *var)
+ void push_back(unsigned uniform_loc, ir_variable *var)
{
active_atomic_counter *new_counters;
@@ -66,7 +66,7 @@ namespace {
}
counters = new_counters;
- counters[num_counters].id = id;
+ counters[num_counters].uniform_loc = uniform_loc;
counters[num_counters].var = var;
num_counters++;
}
@@ -95,6 +95,50 @@ 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,
+ unsigned *uniform_loc, 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++) {
+ process_atomic_variable(t->fields.array, prog, uniform_loc,
+ var, buffers, num_buffers, offset,
+ shader_stage);
+ }
+ } else {
+ active_atomic_buffer *buf = &buffers[var->data.binding];
+ gl_uniform_storage *const storage =
+ &prog->UniformStorage[*uniform_loc];
+
+ /* 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(*uniform_loc, var);
+
+ buf->stage_references[shader_stage]++;
+ buf->size = MAX2(buf->size, *offset + t->atomic_size());
+
+ storage->offset = *offset;
+ *offset += t->atomic_size();
+
+ (*uniform_loc)++;
+ }
+ }
+
active_atomic_buffer *
find_active_atomic_counters(struct gl_context *ctx,
struct gl_shader_program *prog,
@@ -114,23 +158,10 @@ 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());
+ int offset = var->data.atomic.offset;
+ unsigned uniform_loc = var->data.location;
+ process_atomic_variable(var->type, prog, &uniform_loc,
+ var, buffers, num_buffers, &offset, i);
}
}
}
@@ -197,10 +228,10 @@ link_assign_atomic_counter_resources(struct gl_context *ctx,
/* Assign counter-specific fields. */
for (unsigned j = 0; j < ab.num_counters; j++) {
ir_variable *const var = ab.counters[j].var;
- const unsigned id = ab.counters[j].id;
- gl_uniform_storage *const storage = &prog->UniformStorage[id];
+ gl_uniform_storage *const storage =
+ &prog->UniformStorage[ab.counters[j].uniform_loc];
- mab.Uniforms[j] = id;
+ mab.Uniforms[j] = ab.counters[j].uniform_loc;
if (!var->data.explicit_binding)
var->data.binding = i;