linker: Track uniform locations to new tracking structures
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 18 Oct 2011 18:54:48 +0000 (11:54 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 7 Nov 2011 21:33:16 +0000 (13:33 -0800)
This is just the infrastructure and the code.  It's not used yet.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Tested-by: Tom Stellard <thomas.stellard@amd.com>
src/glsl/link_uniforms.cpp
src/glsl/linker.h

index 7fe463f104f6cc75660e34ba82bfa9bab9974758..b9d5361b032297bda81a99d6528db86ed9ac08c4 100644 (file)
@@ -237,3 +237,98 @@ private:
 public:
    union gl_constant_value *values;
 };
+
+void
+link_assign_uniform_locations(struct gl_shader_program *prog)
+{
+   ralloc_free(prog->UniformStorage);
+   prog->UniformStorage = NULL;
+   prog->NumUserUniformStorage = 0;
+
+   if (prog->UniformHash != NULL) {
+      prog->UniformHash->clear();
+   } else {
+      prog->UniformHash = new string_to_uint_map;
+   }
+
+   for (unsigned i = 0; i < Elements(prog->SamplerUnits); i++) {
+      prog->SamplerUnits[i] = i;
+   }
+
+   /* First pass: Count the uniform resources used by the user-defined
+    * uniforms.  While this happens, each active uniform will have an index
+    * assigned to it.
+    *
+    * Note: this is *NOT* the index that is returned to the application by
+    * glGetUniformLocation.
+    */
+   count_uniform_size uniform_size(prog->UniformHash);
+   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+      if (prog->_LinkedShaders[i] == NULL)
+        continue;
+
+      foreach_list(node, prog->_LinkedShaders[i]->ir) {
+        ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+        if ((var == NULL) || (var->mode != ir_var_uniform))
+           continue;
+
+        /* FINISHME: Update code to process built-in uniforms!
+         */
+        if (strncmp("gl_", var->name, 3) == 0)
+           continue;
+
+        uniform_size.process(var);
+      }
+   }
+
+   const unsigned num_user_uniforms = uniform_size.num_active_uniforms;
+   const unsigned num_data_slots = uniform_size.num_values;
+
+   /* On the outside chance that there were no uniforms, bail out.
+    */
+   if (num_user_uniforms == 0)
+      return;
+
+   struct gl_uniform_storage *uniforms =
+      rzalloc_array(prog, struct gl_uniform_storage, num_user_uniforms);
+   union gl_constant_value *data =
+      rzalloc_array(uniforms, union gl_constant_value, num_data_slots);
+#ifndef NDEBUG
+   union gl_constant_value *data_end = &data[num_data_slots];
+#endif
+
+   parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data);
+
+   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+      if (prog->_LinkedShaders[i] == NULL)
+        continue;
+
+      foreach_list(node, prog->_LinkedShaders[i]->ir) {
+        ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+        if ((var == NULL) || (var->mode != ir_var_uniform))
+           continue;
+
+        /* FINISHME: Update code to process built-in uniforms!
+         */
+        if (strncmp("gl_", var->name, 3) == 0)
+           continue;
+
+        parcel.process(var);
+      }
+   }
+
+#ifndef NDEBUG
+   for (unsigned i = 0; i < num_user_uniforms; i++) {
+      assert(uniforms[i].storage != NULL);
+   }
+#endif
+
+   assert(parcel.values == data_end);
+
+   prog->NumUserUniformStorage = num_user_uniforms;
+   prog->UniformStorage = uniforms;
+
+   return;
+}
index 669549bf0c54eea74f20649024e8697800dbacc4..433c63be246131e453a37203285502d040d4f042 100644 (file)
@@ -34,6 +34,9 @@ extern void
 link_invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
                                   int generic_base);
 
+extern void
+link_assign_uniform_locations(struct gl_shader_program *prog);
+
 /**
  * Class for processing all of the leaf fields of an uniform
  *