summaryrefslogtreecommitdiffstats
path: root/src/glsl/link_atomics.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2015-10-27 06:58:15 +1100
committerTimothy Arceri <[email protected]>2015-10-27 07:03:05 +1100
commita3d0359aff7a9be90149c416844f330b4f9a15ed (patch)
tree8223f873bd216747a5df731094b7793efe341049 /src/glsl/link_atomics.cpp
parent711489648bcce5cd8fcf14e73e5affe069010c01 (diff)
glsl: keep track of intra-stage indices for atomics
This is more optimal as it means we no longer have to upload the same set of ABO surfaces to all stages in the program. This also fixes a bug where since commit c0cd5b var->data.binding was being used as a replacement for atomic buffer index, but they don't have to be the same value they just happened to end up the same when binding is 0. Reviewed-by: Francisco Jerez <[email protected]> Reviewed-by: Samuel Iglesias Gonsálvez <[email protected]> Cc: Ilia Mirkin <[email protected]> Cc: Alejandro Piñeiro <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90175
Diffstat (limited to 'src/glsl/link_atomics.cpp')
-rw-r--r--src/glsl/link_atomics.cpp43
1 files changed, 40 insertions, 3 deletions
diff --git a/src/glsl/link_atomics.cpp b/src/glsl/link_atomics.cpp
index 70ef0e1c891..cdcc06d53e2 100644
--- a/src/glsl/link_atomics.cpp
+++ b/src/glsl/link_atomics.cpp
@@ -198,6 +198,7 @@ link_assign_atomic_counter_resources(struct gl_context *ctx,
struct gl_shader_program *prog)
{
unsigned num_buffers;
+ unsigned num_atomic_buffers[MESA_SHADER_STAGES] = {};
active_atomic_buffer *abs =
find_active_atomic_counters(ctx, prog, &num_buffers);
@@ -242,13 +243,49 @@ link_assign_atomic_counter_resources(struct gl_context *ctx,
}
/* Assign stage-specific fields. */
- for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j)
- mab.StageReferences[j] =
- (ab.stage_references[j] ? GL_TRUE : GL_FALSE);
+ for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j) {
+ if (ab.stage_references[j]) {
+ mab.StageReferences[j] = GL_TRUE;
+ num_atomic_buffers[j]++;
+ } else {
+ mab.StageReferences[j] = GL_FALSE;
+ }
+ }
i++;
}
+ /* Store a list pointers to atomic buffers per stage and store the index
+ * to the intra-stage buffer list in uniform storage.
+ */
+ for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j) {
+ if (prog->_LinkedShaders[j] && num_atomic_buffers[j] > 0) {
+ prog->_LinkedShaders[j]->NumAtomicBuffers = num_atomic_buffers[j];
+ prog->_LinkedShaders[j]->AtomicBuffers =
+ rzalloc_array(prog, gl_active_atomic_buffer *,
+ num_atomic_buffers[j]);
+
+ unsigned intra_stage_idx = 0;
+ for (unsigned i = 0; i < num_buffers; i++) {
+ struct gl_active_atomic_buffer *atomic_buffer =
+ &prog->AtomicBuffers[i];
+ if (atomic_buffer->StageReferences[j]) {
+ prog->_LinkedShaders[j]->AtomicBuffers[intra_stage_idx] =
+ atomic_buffer;
+
+ for (unsigned u = 0; u < atomic_buffer->NumUniforms; u++) {
+ prog->UniformStorage[atomic_buffer->Uniforms[u]].opaque[j].index =
+ intra_stage_idx;
+ prog->UniformStorage[atomic_buffer->Uniforms[u]].opaque[j].active =
+ true;
+ }
+
+ intra_stage_idx++;
+ }
+ }
+ }
+ }
+
delete [] abs;
assert(i == num_buffers);
}