[Mesa-dev] [PATCH 54/65] glsl: don't lose uniform values when falling back to full compile
Timothy Arceri
timothy.arceri at collabora.com
Fri Apr 29 13:33:53 UTC 2016
Here we skip the recreation of uniform storage if we are relinking
after a cache miss.
---
src/compiler/glsl/link_uniforms.cpp | 32 +++++++++++++++++++++-------
src/compiler/glsl/linker.cpp | 3 ++-
src/compiler/glsl/linker.h | 2 +-
src/compiler/glsl/main.cpp | 2 +-
src/compiler/glsl/standalone_scaffolding.cpp | 3 ++-
src/compiler/glsl/standalone_scaffolding.h | 2 +-
src/mesa/main/shaderobj.c | 9 ++++----
src/mesa/main/shaderobj.h | 3 ++-
src/mesa/program/ir_to_mesa.cpp | 2 +-
9 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index 8c27030..fc566ac 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -995,11 +995,13 @@ void
link_assign_uniform_locations(struct gl_shader_program *prog,
unsigned int boolean_true,
unsigned int num_explicit_uniform_locs,
- unsigned int max_uniform_locs)
+ unsigned int max_uniform_locs, bool skip_cache)
{
- ralloc_free(prog->UniformStorage);
- prog->UniformStorage = NULL;
- prog->NumUniformStorage = 0;
+ if (!skip_cache) {
+ ralloc_free(prog->UniformStorage);
+ prog->UniformStorage = NULL;
+ prog->NumUniformStorage = 0;
+ }
if (prog->UniformHash != NULL) {
prog->UniformHash->clear();
@@ -1074,10 +1076,17 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
if (num_uniforms == 0)
return;
- struct gl_uniform_storage *uniforms =
- rzalloc_array(prog, struct gl_uniform_storage, num_uniforms);
- union gl_constant_value *data =
- rzalloc_array(uniforms, union gl_constant_value, num_data_slots);
+ struct gl_uniform_storage *uniforms;
+ union gl_constant_value *data;
+
+ if (prog->UniformStorage == NULL) {
+ uniforms = rzalloc_array(prog, struct gl_uniform_storage, num_uniforms);
+ data = rzalloc_array(uniforms, union gl_constant_value, num_data_slots);
+ } else {
+ uniforms = prog->UniformStorage;
+ data = prog->UniformDataSlots;
+ }
+
#ifndef NDEBUG
union gl_constant_value *data_end = &data[num_data_slots];
#endif
@@ -1112,6 +1121,13 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
}
+ /* If this is a fallback compile for a cache miss we already have the
+ * correct uniform mappings and we don't want to reinitialise uniforms so
+ * just return now.
+ */
+ if (skip_cache && prog->UniformStorage)
+ return;
+
/* Reserve all the explicit locations of the active uniforms. */
for (unsigned i = 0; i < num_uniforms; i++) {
if (uniforms[i].type->is_subroutine() ||
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index c493de2..45b8e46 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -4773,7 +4773,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog,
update_array_sizes(prog);
link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue,
num_explicit_uniform_locs,
- ctx->Const.MaxUserAssignableUniformLocations);
+ ctx->Const.MaxUserAssignableUniformLocations,
+ skip_cache);
link_assign_atomic_counter_resources(ctx, prog);
store_fragdepth_layout(prog);
diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h
index f026732..6b68c41 100644
--- a/src/compiler/glsl/linker.h
+++ b/src/compiler/glsl/linker.h
@@ -37,7 +37,7 @@ extern void
link_assign_uniform_locations(struct gl_shader_program *prog,
unsigned int boolean_true,
unsigned int num_explicit_uniform_locs,
- unsigned int max_uniform_locs);
+ unsigned int max_uniform_locs, bool skip_cache);
extern void
link_set_uniform_initializers(struct gl_shader_program *prog,
diff --git a/src/compiler/glsl/main.cpp b/src/compiler/glsl/main.cpp
index 97cedb5..1d3c5a3 100644
--- a/src/compiler/glsl/main.cpp
+++ b/src/compiler/glsl/main.cpp
@@ -424,7 +424,7 @@ main(int argc, char **argv)
}
if ((status == EXIT_SUCCESS) && do_link) {
- _mesa_clear_shader_program_data(whole_program);
+ _mesa_clear_shader_program_data(whole_program, false);
link_shaders(ctx, whole_program, true);
status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp
index fffe6cc..886a1bb 100644
--- a/src/compiler/glsl/standalone_scaffolding.cpp
+++ b/src/compiler/glsl/standalone_scaffolding.cpp
@@ -114,7 +114,8 @@ _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
}
void
-_mesa_clear_shader_program_data(struct gl_shader_program *shProg)
+_mesa_clear_shader_program_data(struct gl_shader_program *shProg,
+ bool skip_cache)
{
shProg->NumUniformStorage = 0;
shProg->UniformStorage = NULL;
diff --git a/src/compiler/glsl/standalone_scaffolding.h b/src/compiler/glsl/standalone_scaffolding.h
index 38bd76a..5c6e72c 100644
--- a/src/compiler/glsl/standalone_scaffolding.h
+++ b/src/compiler/glsl/standalone_scaffolding.h
@@ -53,7 +53,7 @@ extern "C" void
_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh);
extern "C" void
-_mesa_clear_shader_program_data(struct gl_shader_program *);
+_mesa_clear_shader_program_data(struct gl_shader_program *, bool skip_cache);
extern "C" void
_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 274cb12..49a155c 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -265,11 +265,12 @@ _mesa_new_shader_program(GLuint name)
* Clear (free) the shader program state that gets produced by linking.
*/
void
-_mesa_clear_shader_program_data(struct gl_shader_program *shProg)
+_mesa_clear_shader_program_data(struct gl_shader_program *shProg,
+ bool skip_cache)
{
unsigned i;
- if (shProg->UniformStorage) {
+ if (shProg->UniformStorage && !skip_cache) {
for (i = 0; i < shProg->NumUniformStorage; ++i)
_mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]);
ralloc_free(shProg->UniformStorage);
@@ -277,7 +278,7 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
shProg->UniformStorage = NULL;
}
- if (shProg->UniformRemapTable) {
+ if (shProg->UniformRemapTable && !skip_cache) {
ralloc_free(shProg->UniformRemapTable);
shProg->NumUniformRemapTable = 0;
shProg->UniformRemapTable = NULL;
@@ -325,7 +326,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx,
assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
- _mesa_clear_shader_program_data(shProg);
+ _mesa_clear_shader_program_data(shProg, false);
if (shProg->AttributeBindings) {
string_to_uint_map_dtor(shProg->AttributeBindings);
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
index 53836f1..388de39 100644
--- a/src/mesa/main/shaderobj.h
+++ b/src/mesa/main/shaderobj.h
@@ -96,7 +96,8 @@ extern struct gl_shader_program *
_mesa_new_shader_program(GLuint name);
extern void
-_mesa_clear_shader_program_data(struct gl_shader_program *shProg);
+_mesa_clear_shader_program_data(struct gl_shader_program *shProg,
+ bool skip_cache);
extern void
_mesa_free_shader_program_data(struct gl_context *ctx,
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index fa034ab..4f4cbaf 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2992,7 +2992,7 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog,
{
unsigned int i;
- _mesa_clear_shader_program_data(prog);
+ _mesa_clear_shader_program_data(prog, skip_cache);
prog->LinkStatus = GL_TRUE;
--
2.5.5
More information about the mesa-dev
mailing list