glsl: Simplify the built-in function linking code.
Previously, we stored an array of up to 16 additional shaders to link,
as well as a count of how many each shader actually needed.
Since the built-in functions rewrite, all the built-ins are stored in a
single shader. So all we need is a boolean indicating whether a shader
needs to link against built-ins or not.
During linking, we can avoid creating the temporary array if none of the
shaders being linked need built-ins. Otherwise, it's simply a copy of
the array that has one additional element. This is much simpler.
This patch saves approximately 128 bytes of memory per gl_shader object.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 1366077..21c1bdd 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1405,36 +1405,38 @@
insertion_point, true, linked);
}
- /* Resolve initializers for global variables in the linked shader.
- */
- unsigned num_linking_shaders = num_shaders;
- for (unsigned i = 0; i < num_shaders; i++)
- num_linking_shaders += shader_list[i]->num_builtins_to_link;
-
- gl_shader **linking_shaders =
- (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *));
-
- memcpy(linking_shaders, shader_list,
- sizeof(linking_shaders[0]) * num_shaders);
-
- unsigned idx = num_shaders;
+ /* Check if any shader needs built-in functions. */
+ bool need_builtins = false;
for (unsigned i = 0; i < num_shaders; i++) {
- memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link,
- sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link);
- idx += shader_list[i]->num_builtins_to_link;
+ if (shader_list[i]->uses_builtin_functions) {
+ need_builtins = true;
+ break;
+ }
}
- assert(idx == num_linking_shaders);
+ bool ok;
+ if (need_builtins) {
+ /* Make a temporary array one larger than shader_list, which will hold
+ * the built-in function shader as well.
+ */
+ gl_shader **linking_shaders = (gl_shader **)
+ calloc(num_shaders + 1, sizeof(gl_shader *));
+ memcpy(linking_shaders, shader_list, num_shaders * sizeof(gl_shader *));
+ linking_shaders[num_shaders] = _mesa_glsl_get_builtin_function_shader();
- if (!link_function_calls(prog, linked, linking_shaders,
- num_linking_shaders)) {
- ctx->Driver.DeleteShader(ctx, linked);
+ ok = link_function_calls(prog, linked, linking_shaders, num_shaders + 1);
+
free(linking_shaders);
+ } else {
+ ok = link_function_calls(prog, linked, shader_list, num_shaders);
+ }
+
+
+ if (!ok) {
+ ctx->Driver.DeleteShader(ctx, linked);
return NULL;
}
- free(linking_shaders);
-
/* At this point linked should contain all of the linked IR, so
* validate it to make sure nothing went wrong.
*/