Mesa (master): glsl: Clear the static values of builtin function profiles at release.

Eric Anholt anholt at kemper.freedesktop.org
Mon Aug 30 20:13:03 UTC 2010


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

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Aug 30 12:20:25 2010 -0700

glsl: Clear the static values of builtin function profiles at release.

When releasing the builtin functions, we were just freeing the memory,
not telling the builtin function loader that we had freed its memory.
I wish I had done ARB_ES2_compatibility so we had regression testing
of this path.  Fixes segfault on changing video options in nexuiz.

---

 src/glsl/builtin_function.cpp                |  200 +++++++++-----------------
 src/glsl/builtins/tools/generate_builtins.py |   56 +++++---
 2 files changed, 104 insertions(+), 152 deletions(-)

diff --git a/src/glsl/builtin_function.cpp b/src/glsl/builtin_function.cpp
index 975e092..d3484cb 100644
--- a/src/glsl/builtin_function.cpp
+++ b/src/glsl/builtin_function.cpp
@@ -16759,183 +16759,117 @@ static const char *functions_for_EXT_texture_array_vert [] = {
    builtin_texture2DArray,
    builtin_texture2DArrayLod,
 };
+static gl_shader *builtin_profiles[10];
 
 void *builtin_mem_ctx = NULL;
 
 void
 _mesa_glsl_release_functions(void)
 {
-    talloc_free(builtin_mem_ctx);
-    builtin_mem_ctx = NULL;
+   talloc_free(builtin_mem_ctx);
+   builtin_mem_ctx = NULL;
+}
+
+static void
+_mesa_read_profile(struct _mesa_glsl_parse_state *state,
+		   exec_list *instructions,
+                   int profile_index,
+		   const char *prototypes,
+		   const char **functions,
+                   int count)
+{
+   gl_shader *sh = builtin_profiles[profile_index];
+
+   if (sh == NULL) {
+      sh = read_builtins(GL_VERTEX_SHADER, prototypes, functions, count);
+      talloc_steal(builtin_mem_ctx, sh);
+      builtin_profiles[profile_index] = sh;
+   }
+
+   import_prototypes(sh->ir, instructions, state->symbols, state);
+   state->builtins_to_link[state->num_builtins_to_link] = sh;
+   state->num_builtins_to_link++;
 }
 
 void
 _mesa_glsl_initialize_functions(exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state)
 {
-   if (builtin_mem_ctx == NULL)
+   if (builtin_mem_ctx == NULL) {
       builtin_mem_ctx = talloc_init("GLSL built-in functions");
+      memset(&builtin_profiles, 0, sizeof(builtin_profiles));
+   }
 
    state->num_builtins_to_link = 0;
 
    if (state->target == fragment_shader && state->language_version == 110) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_110_frag,
-                            functions_for_110_frag,
-                            Elements(functions_for_110_frag ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 0,
+                         prototypes_for_110_frag,
+                         functions_for_110_frag,
+                         Elements(functions_for_110_frag));
    }
 
    if (state->target == vertex_shader && state->language_version == 110) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_110_vert,
-                            functions_for_110_vert,
-                            Elements(functions_for_110_vert ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 1,
+                         prototypes_for_110_vert,
+                         functions_for_110_vert,
+                         Elements(functions_for_110_vert));
    }
 
    if (state->target == fragment_shader && state->language_version == 120) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_120_frag,
-                            functions_for_120_frag,
-                            Elements(functions_for_120_frag ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 2,
+                         prototypes_for_120_frag,
+                         functions_for_120_frag,
+                         Elements(functions_for_120_frag));
    }
 
    if (state->target == vertex_shader && state->language_version == 120) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_120_vert,
-                            functions_for_120_vert,
-                            Elements(functions_for_120_vert ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 3,
+                         prototypes_for_120_vert,
+                         functions_for_120_vert,
+                         Elements(functions_for_120_vert));
    }
 
    if (state->target == fragment_shader && state->language_version == 130) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_130_frag,
-                            functions_for_130_frag,
-                            Elements(functions_for_130_frag ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 4,
+                         prototypes_for_130_frag,
+                         functions_for_130_frag,
+                         Elements(functions_for_130_frag));
    }
 
    if (state->target == vertex_shader && state->language_version == 130) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_130_vert,
-                            functions_for_130_vert,
-                            Elements(functions_for_130_vert ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 5,
+                         prototypes_for_130_vert,
+                         functions_for_130_vert,
+                         Elements(functions_for_130_vert));
    }
 
    if (state->target == fragment_shader && state->ARB_texture_rectangle_enable) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_ARB_texture_rectangle_frag,
-                            functions_for_ARB_texture_rectangle_frag,
-                            Elements(functions_for_ARB_texture_rectangle_frag ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 6,
+                         prototypes_for_ARB_texture_rectangle_frag,
+                         functions_for_ARB_texture_rectangle_frag,
+                         Elements(functions_for_ARB_texture_rectangle_frag));
    }
 
    if (state->target == vertex_shader && state->ARB_texture_rectangle_enable) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_ARB_texture_rectangle_vert,
-                            functions_for_ARB_texture_rectangle_vert,
-                            Elements(functions_for_ARB_texture_rectangle_vert ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 7,
+                         prototypes_for_ARB_texture_rectangle_vert,
+                         functions_for_ARB_texture_rectangle_vert,
+                         Elements(functions_for_ARB_texture_rectangle_vert));
    }
 
    if (state->target == fragment_shader && state->EXT_texture_array_enable) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_EXT_texture_array_frag,
-                            functions_for_EXT_texture_array_frag,
-                            Elements(functions_for_EXT_texture_array_frag ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 8,
+                         prototypes_for_EXT_texture_array_frag,
+                         functions_for_EXT_texture_array_frag,
+                         Elements(functions_for_EXT_texture_array_frag));
    }
 
    if (state->target == vertex_shader && state->EXT_texture_array_enable) {
-      static gl_shader *sh = NULL;
-      if (sh == NULL) {
-         sh = read_builtins(GL_VERTEX_SHADER,
-                            prototypes_for_EXT_texture_array_vert,
-                            functions_for_EXT_texture_array_vert,
-                            Elements(functions_for_EXT_texture_array_vert ));
-         talloc_steal(builtin_mem_ctx, sh);
-      }
-
-      import_prototypes(sh->ir, instructions, state->symbols,
-                        state);
-      state->builtins_to_link[state->num_builtins_to_link] = sh;
-      state->num_builtins_to_link++;
+      _mesa_read_profile(state, instructions, 9,
+                         prototypes_for_EXT_texture_array_vert,
+                         functions_for_EXT_texture_array_vert,
+                         Elements(functions_for_EXT_texture_array_vert));
    }
 
 }
diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py
index ab5b377..5accc1b 100755
--- a/src/glsl/builtins/tools/generate_builtins.py
+++ b/src/glsl/builtins/tools/generate_builtins.py
@@ -1,5 +1,5 @@
 #!/usr/bin/python
-# -*- coding: UTF-8 -*-
+# -*- coding: utf-8 -*-
 
 import re
 from glob import glob
@@ -168,27 +168,54 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne
     write_function_definitions()
     write_profiles()
 
+    profiles = get_profile_list()
+
+    print 'static gl_shader *builtin_profiles[%d];' % len(profiles)
+
     print """
 void *builtin_mem_ctx = NULL;
 
 void
 _mesa_glsl_release_functions(void)
 {
-    talloc_free(builtin_mem_ctx);
-    builtin_mem_ctx = NULL;
+   talloc_free(builtin_mem_ctx);
+   builtin_mem_ctx = NULL;
+}
+
+static void
+_mesa_read_profile(struct _mesa_glsl_parse_state *state,
+		   exec_list *instructions,
+                   int profile_index,
+		   const char *prototypes,
+		   const char **functions,
+                   int count)
+{
+   gl_shader *sh = builtin_profiles[profile_index];
+
+   if (sh == NULL) {
+      sh = read_builtins(GL_VERTEX_SHADER, prototypes, functions, count);
+      talloc_steal(builtin_mem_ctx, sh);
+      builtin_profiles[profile_index] = sh;
+   }
+
+   import_prototypes(sh->ir, instructions, state->symbols, state);
+   state->builtins_to_link[state->num_builtins_to_link] = sh;
+   state->num_builtins_to_link++;
 }
 
 void
 _mesa_glsl_initialize_functions(exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state)
 {
-   if (builtin_mem_ctx == NULL)
+   if (builtin_mem_ctx == NULL) {
       builtin_mem_ctx = talloc_init("GLSL built-in functions");
+      memset(&builtin_profiles, 0, sizeof(builtin_profiles));
+   }
 
    state->num_builtins_to_link = 0;
 """
 
-    profiles = get_profile_list()
+    i=0
     for (filename, profile) in profiles:
         if profile.endswith('_vert'):
             check = 'state->target == vertex_shader && '
@@ -202,21 +229,12 @@ _mesa_glsl_initialize_functions(exec_list *instructions,
             check += 'state->' + version + '_enable'
 
         print '   if (' + check + ') {'
-        print '      static gl_shader *sh = NULL;'
-        print '      if (sh == NULL) {'
-        print '         sh = read_builtins(GL_VERTEX_SHADER,'
-        print '                            prototypes_for_' + profile + ','
-        print '                            functions_for_' + profile + ','
-        print '                            Elements(functions_for_' + profile,
-        print '));'
-        print '         talloc_steal(builtin_mem_ctx, sh);'
-        print '      }'
-        print
-        print '      import_prototypes(sh->ir, instructions, state->symbols,'
-        print '                        state);'
-        print '      state->builtins_to_link[state->num_builtins_to_link] = sh;'
-        print '      state->num_builtins_to_link++;'
+        print '      _mesa_read_profile(state, instructions, %d,' % i
+        print '                         prototypes_for_' + profile + ','
+        print '                         functions_for_' + profile + ','
+        print '                         Elements(functions_for_' + profile + '));'
         print '   }'
         print
+        i = i + 1
     print '}'
 




More information about the mesa-commit mailing list