summaryrefslogtreecommitdiffstats
path: root/src/glsl/link_uniforms.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-10-27 16:34:06 -0700
committerKenneth Graunke <[email protected]>2014-11-06 16:20:01 -0800
commit0c0bfb2ead03789164cee364fbf405994d876ca3 (patch)
tree104685c6b0e7f46ef130440a95a171216e43b407 /src/glsl/link_uniforms.cpp
parent13786172181bf5a753c706a7f5c3eb5d448e244e (diff)
glsl: Add infrastructure for "hidden" uniforms.
In the compiler, we'd like to generate implicit uniforms for internal use. These should not be visible via the GL uniform introspection API. To support that, we add a new ir_variable::how_declared value of ir_var_hidden, and plumb that through to gl_uniform_storage. v2 (idr): Fix some memory management issues in move_hidden_uniforms_to_end. The comment block on the function has more details. Signed-off-by: Kenneth Graunke <[email protected]> Signed-off-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/link_uniforms.cpp')
-rw-r--r--src/glsl/link_uniforms.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 400e1347933..de2f6c9ac99 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -585,6 +585,8 @@ private:
this->uniforms[id].driver_storage = NULL;
this->uniforms[id].storage = this->values;
this->uniforms[id].atomic_buffer_index = -1;
+ this->uniforms[id].hidden =
+ current_var->data.how_declared == ir_var_hidden;
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
@@ -806,6 +808,50 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog)
}
}
+/**
+ * Sort the array of uniform storage so that the non-hidden uniforms are first
+ *
+ * This function sorts the list "in place." This is important because some of
+ * the storage accessible from \c uniforms has \c uniforms as its \c ralloc
+ * context. If \c uniforms is freed, some other storage will also be freed.
+ */
+static unsigned
+move_hidden_uniforms_to_end(struct gl_shader_program *prog,
+ struct gl_uniform_storage *uniforms,
+ unsigned num_elements)
+{
+ struct gl_uniform_storage *sorted_uniforms =
+ ralloc_array(prog, struct gl_uniform_storage, num_elements);
+ unsigned hidden_uniforms = 0;
+ unsigned j = 0;
+
+ /* Add the non-hidden uniforms. */
+ for (unsigned i = 0; i < num_elements; i++) {
+ if (!uniforms[i].hidden)
+ sorted_uniforms[j++] = uniforms[i];
+ }
+
+ /* Add and count the hidden uniforms. */
+ for (unsigned i = 0; i < num_elements; i++) {
+ if (uniforms[i].hidden) {
+ sorted_uniforms[j++] = uniforms[i];
+ hidden_uniforms++;
+ }
+ }
+
+ assert(prog->UniformHash != NULL);
+ prog->UniformHash->clear();
+ for (unsigned i = 0; i < num_elements; i++) {
+ if (sorted_uniforms[i].name != NULL)
+ prog->UniformHash->put(i, sorted_uniforms[i].name);
+ }
+
+ memcpy(uniforms, sorted_uniforms, sizeof(uniforms[0]) * num_elements);
+ ralloc_free(sorted_uniforms);
+
+ return hidden_uniforms;
+}
+
void
link_assign_uniform_locations(struct gl_shader_program *prog,
unsigned int boolean_true)
@@ -926,6 +972,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
}
+ const unsigned hidden_uniforms =
+ move_hidden_uniforms_to_end(prog, uniforms, num_user_uniforms);
+
/* Reserve all the explicit locations of the active uniforms. */
for (unsigned i = 0; i < num_user_uniforms; i++) {
if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) {
@@ -978,6 +1027,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
#endif
prog->NumUserUniformStorage = num_user_uniforms;
+ prog->NumHiddenUniforms = hidden_uniforms;
prog->UniformStorage = uniforms;
link_set_image_access_qualifiers(prog);