[Mesa-dev] [PATCH v2 1/2] glsl: Add infrastructure for "hidden" uniforms.
Kenneth Graunke
kenneth at whitecape.org
Wed Oct 29 17:16:31 PDT 2014
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 <kenneth at whitecape.org>
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
src/glsl/ir.h | 6 ++++++
src/glsl/ir_uniform.h | 6 ++++++
src/glsl/link_uniforms.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++
src/mesa/main/mtypes.h | 1 +
src/mesa/main/shaderapi.c | 6 ++++--
5 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 90c443c..a7c4c6b 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -359,6 +359,12 @@ enum ir_var_declaration_type {
* re-declared by the shader.
*/
ir_var_declared_implicitly,
+
+ /**
+ * Variable is implicitly generated by the compiler and should not be
+ * visible via the API.
+ */
+ ir_var_hidden,
};
/**
diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h
index b9ecf7c..21b5d05 100644
--- a/src/glsl/ir_uniform.h
+++ b/src/glsl/ir_uniform.h
@@ -175,6 +175,12 @@ struct gl_uniform_storage {
* arrays this is the first element in the array.
*/
unsigned remap_location;
+
+ /**
+ * This is a compiler-generated uniform that should not be advertised
+ * via the API.
+ */
+ bool hidden;
};
#ifdef __cplusplus
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 400e134..de2f6c9 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);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 35f5f69..7583f2c 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2843,6 +2843,7 @@ struct gl_shader_program
/* post-link info: */
unsigned NumUserUniformStorage;
+ unsigned NumHiddenUniforms;
struct gl_uniform_storage *UniformStorage;
/**
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 2be9092..6657820 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -565,13 +565,15 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
*params = _mesa_longest_attribute_name_length(shProg);
return;
case GL_ACTIVE_UNIFORMS:
- *params = shProg->NumUserUniformStorage;
+ *params = shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
return;
case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
unsigned i;
GLint max_len = 0;
+ const unsigned num_uniforms =
+ shProg->NumUserUniformStorage - shProg->NumHiddenUniforms;
- for (i = 0; i < shProg->NumUserUniformStorage; i++) {
+ for (i = 0; i < num_uniforms; i++) {
/* Add one for the terminating NUL character for a non-array, and
* 4 for the "[0]" and the NUL for an array.
*/
--
2.1.2
More information about the mesa-dev
mailing list