Module: Mesa
Branch: master
Commit: 0c0bfb2ead03789164cee364fbf405994d876ca3
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=0c0bfb2ead03789164cee364fbf405994d876ca3

Author: Kenneth Graunke <[email protected]>
Date:   Mon Oct 27 16:34:06 2014 -0700

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]>

---

 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 5c7faf6..a0f48b2 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -342,6 +342,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 be79ed3..7389baa 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.
          */

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to