glsl: builtin: always return clones of the builtins
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Tue, 7 Mar 2017 18:37:58 +0000 (18:37 +0000)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Thu, 9 Mar 2017 08:30:36 +0000 (08:30 +0000)
Builtins are created once and allocated using their own private ralloc
context. When reparenting IR that includes builtins, we might be steal
bits of builtins. This is problematic because these builtins might now
be freed when the shader that includes then last is disposed. This
might also lead to inconsistent ralloc trees/lists if shaders are
created on multiple threads.

Rather than including builtins directly into a shader's IR, we should
include clones of them in the ralloc context of the shader that
requires them. This fixes double free issues we've been seeing when
running shader-db on a big multicore (72 threads) server.

v2: Also rename _mesa_glsl_find_builtin_function_by_name() to better
    reflect how this function is used. (Ken)

v3: Rename ctx to mem_ctx (Ken)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/builtin_functions.cpp
src/compiler/glsl/builtin_functions.h

index 59d03c9c9625dd2c016ae41f7137bd6e77c844ff..27dc21fffecec25479dbadbd87f1954df5ef014e 100644 (file)
@@ -5653,7 +5653,7 @@ ast_function::hir(exec_list *instructions,
    if (state->es_shader && state->language_version >= 300) {
       /* Local shader has no exact candidates; check the built-ins. */
       _mesa_glsl_initialize_builtin_functions();
-      if (_mesa_glsl_find_builtin_function_by_name(name)) {
+      if (_mesa_glsl_has_builtin_function(name)) {
          YYLTYPE loc = this->get_location();
          _mesa_glsl_error(& loc, state,
                           "A shader cannot redefine or overload built-in "
index e03a50c84381204fe0a73a6e0a1ad31496994def..e30509a4acd78f1525507251bc3fdba83b9b70ff 100644 (file)
@@ -62,6 +62,7 @@
 #include "program/prog_instruction.h"
 #include <math.h>
 #include "builtin_functions.h"
+#include "util/hash_table.h"
 
 #define M_PIf   ((float) M_PI)
 #define M_PI_2f ((float) M_PI_2)
@@ -6002,21 +6003,32 @@ ir_function_signature *
 _mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
                                  const char *name, exec_list *actual_parameters)
 {
-   ir_function_signature * s;
+   ir_function_signature *s;
    mtx_lock(&builtins_lock);
    s = builtins.find(state, name, actual_parameters);
    mtx_unlock(&builtins_lock);
-   return s;
+
+   if (s == NULL)
+      return NULL;
+
+   struct hash_table *ht =
+      _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
+   void *mem_ctx = state;
+   ir_function *f = s->function()->clone(mem_ctx, ht);
+   _mesa_hash_table_destroy(ht, NULL);
+
+   return f->matching_signature(state, actual_parameters, true);
 }
 
-ir_function *
-_mesa_glsl_find_builtin_function_by_name(const char *name)
+bool
+_mesa_glsl_has_builtin_function(const char *name)
 {
    ir_function *f;
    mtx_lock(&builtins_lock);
    f = builtins.shader->symbols->get_function(name);
    mtx_unlock(&builtins_lock);
-   return f;
+
+   return f != NULL;
 }
 
 gl_shader *
index 7ae211b48aa070e0da781ad38e699b919754d188..14a52b9402710d7722788914265abef8aaa2b4ef 100644 (file)
@@ -31,8 +31,8 @@ extern ir_function_signature *
 _mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
                                  const char *name, exec_list *actual_parameters);
 
-extern ir_function *
-_mesa_glsl_find_builtin_function_by_name(const char *name);
+extern bool
+_mesa_glsl_has_builtin_function(const char *name);
 
 extern gl_shader *
 _mesa_glsl_get_builtin_function_shader(void);