diff options
author | Tapani Pälli <[email protected]> | 2019-03-15 09:47:49 +0200 |
---|---|---|
committer | Tapani Pälli <[email protected]> | 2019-04-16 12:58:00 +0300 |
commit | 624789e3708c87ea2a4c8d2266266b489b421cba (patch) | |
tree | c59e3a43f0d8e7f0196237d4868046681c46fce6 /src/compiler | |
parent | 04508f57d1d36587f3cc048f0f5dae0611f9330c (diff) |
compiler/glsl: handle case where we have multiple users for types
Both Vulkan and OpenGL might be using glsl_types simultaneously or we
can also have multiple concurrent Vulkan instances using glsl_types.
Patch adds a one time init to track number of users and will release
types only when last user calls _glsl_type_singleton_decref().
This change fixes glsl_type memory leaks we have with anv driver.
v2: reuse hash_mutex, cleanup, apply fix also to radv driver and
rename helper functions (Jason)
v3: move init, destroy to happen on GL context init and destroy
Signed-off-by: Tapani Pälli <[email protected]>
Reviewed-by: Timothy Arceri <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/glsl/glsl_parser_extras.cpp | 20 | ||||
-rw-r--r-- | src/compiler/glsl/glsl_parser_extras.h | 2 | ||||
-rw-r--r-- | src/compiler/glsl/standalone.cpp | 3 | ||||
-rw-r--r-- | src/compiler/glsl_types.cpp | 32 | ||||
-rw-r--r-- | src/compiler/glsl_types.h | 10 |
5 files changed, 56 insertions, 11 deletions
diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index 0ffad2d25a0..b30c638cdc9 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -2325,6 +2325,24 @@ do_common_optimization(exec_list *ir, bool linked, extern "C" { /** + * To be called at GL context ctor. + */ +void +_mesa_init_shader_compiler_types(void) +{ + glsl_type_singleton_init_or_ref(); +} + +/** + * To be called at GL context dtor. + */ +void +_mesa_destroy_shader_compiler_types(void) +{ + glsl_type_singleton_decref(); +} + +/** * To be called at GL teardown time, this frees compiler datastructures. * * After calling this, any previously compiled shaders and shader @@ -2335,8 +2353,6 @@ void _mesa_destroy_shader_compiler(void) { _mesa_destroy_shader_compiler_caches(); - - _mesa_glsl_release_types(); } /** diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h index 8646ba6cadd..f92d2160aac 100644 --- a/src/compiler/glsl/glsl_parser_extras.h +++ b/src/compiler/glsl/glsl_parser_extras.h @@ -1010,6 +1010,8 @@ extern int glcpp_preprocess(void *ctx, const char **shader, char **info_log, struct _mesa_glsl_parse_state *state, struct gl_context *gl_ctx); +extern void _mesa_init_shader_compiler_types(void); +extern void _mesa_destroy_shader_compiler_types(void); extern void _mesa_destroy_shader_compiler(void); extern void _mesa_destroy_shader_compiler_caches(void); diff --git a/src/compiler/glsl/standalone.cpp b/src/compiler/glsl/standalone.cpp index 942b9ee4986..7b3d358ca96 100644 --- a/src/compiler/glsl/standalone.cpp +++ b/src/compiler/glsl/standalone.cpp @@ -132,6 +132,7 @@ static void initialize_context(struct gl_context *ctx, gl_api api) { initialize_context_to_defaults(ctx, api); + glsl_type_singleton_init_or_ref(); /* The standalone compiler needs to claim support for almost * everything in order to compile the built-in functions. @@ -617,6 +618,6 @@ standalone_compiler_cleanup(struct gl_shader_program *whole_program) delete whole_program->FragDataIndexBindings; ralloc_free(whole_program); - _mesa_glsl_release_types(); + glsl_type_singleton_decref(); _mesa_glsl_release_builtin_functions(); } diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 66241b34281..9938b3df450 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -37,6 +37,12 @@ hash_table *glsl_type::interface_types = NULL; hash_table *glsl_type::function_types = NULL; hash_table *glsl_type::subroutine_types = NULL; +/* There might be multiple users for types (e.g. application using OpenGL + * and Vulkan simultanously or app using multiple Vulkan instances). Counter + * is used to make sure we don't release the types if a user is still present. + */ +static uint32_t glsl_type_users = 0; + glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type, unsigned vector_elements, unsigned matrix_columns, const char *name, @@ -469,12 +475,26 @@ hash_free_type_function(struct hash_entry *entry) } void -_mesa_glsl_release_types(void) +glsl_type_singleton_init_or_ref() { - /* Should only be called during atexit (either when unloading shared - * object, or if process terminates), so no mutex-locking should be - * necessary. - */ + mtx_lock(&glsl_type::hash_mutex); + glsl_type_users++; + mtx_unlock(&glsl_type::hash_mutex); +} + +void +glsl_type_singleton_decref() +{ + mtx_lock(&glsl_type::hash_mutex); + + assert(glsl_type_users > 0); + + /* Do not release glsl_types if they are still used. */ + if (--glsl_type_users) { + mtx_unlock(&glsl_type::hash_mutex); + return; + } + if (glsl_type::explicit_matrix_types != NULL) { _mesa_hash_table_destroy(glsl_type::explicit_matrix_types, hash_free_type_function); @@ -505,6 +525,8 @@ _mesa_glsl_release_types(void) _mesa_hash_table_destroy(glsl_type::subroutine_types, hash_free_type_function); glsl_type::subroutine_types = NULL; } + + mtx_unlock(&glsl_type::hash_mutex); } diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index dd9ae657019..2fd93f7b945 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -47,10 +47,13 @@ struct _mesa_glsl_parse_state; struct glsl_symbol_table; extern void -_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); +glsl_type_singleton_init_or_ref(); + +extern void +glsl_type_singleton_decref(); extern void -_mesa_glsl_release_types(void); +_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); void encode_type_to_blob(struct blob *blob, const struct glsl_type *type); @@ -1062,8 +1065,9 @@ private: * data. */ /*@{*/ + friend void glsl_type_singleton_init_or_ref(void); + friend void glsl_type_singleton_decref(void); friend void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *); - friend void _mesa_glsl_release_types(void); /*@}*/ }; |