From: Ian Romanick <ian.d.roman...@intel.com> This should fix some problems related to compiling shaders in different contextes from multiple threads.
Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54773 Cc: w_tresspass...@yahoo.co.jp --- src/glsl/builtin_types.h | 16 ++++++++-------- src/glsl/glsl_types.cpp | 36 +++++++++++++++++++++++++++++++----- src/glsl/glsl_types.h | 4 ++-- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/glsl/builtin_types.h b/src/glsl/builtin_types.h index d75c562..59ad915 100644 --- a/src/glsl/builtin_types.h +++ b/src/glsl/builtin_types.h @@ -92,7 +92,7 @@ static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = { const glsl_type glsl_type::builtin_structure_types[] = { glsl_type(gl_DepthRangeParameters_fields, Elements(gl_DepthRangeParameters_fields), - "gl_DepthRangeParameters"), + "gl_DepthRangeParameters", false), }; /*@}*/ @@ -158,25 +158,25 @@ static const struct glsl_struct_field gl_FogParameters_fields[] = { const glsl_type glsl_type::builtin_110_deprecated_structure_types[] = { glsl_type(gl_PointParameters_fields, Elements(gl_PointParameters_fields), - "gl_PointParameters"), + "gl_PointParameters", false), glsl_type(gl_MaterialParameters_fields, Elements(gl_MaterialParameters_fields), - "gl_MaterialParameters"), + "gl_MaterialParameters", false), glsl_type(gl_LightSourceParameters_fields, Elements(gl_LightSourceParameters_fields), - "gl_LightSourceParameters"), + "gl_LightSourceParameters", false), glsl_type(gl_LightModelParameters_fields, Elements(gl_LightModelParameters_fields), - "gl_LightModelParameters"), + "gl_LightModelParameters", false), glsl_type(gl_LightModelProducts_fields, Elements(gl_LightModelProducts_fields), - "gl_LightModelProducts"), + "gl_LightModelProducts", false), glsl_type(gl_LightProducts_fields, Elements(gl_LightProducts_fields), - "gl_LightProducts"), + "gl_LightProducts", false), glsl_type(gl_FogParameters_fields, Elements(gl_FogParameters_fields), - "gl_FogParameters"), + "gl_FogParameters", false), }; /*@}*/ diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 2aa51f0..f51d10c 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -35,6 +35,7 @@ extern "C" { hash_table *glsl_type::array_types = NULL; hash_table *glsl_type::record_types = NULL; void *glsl_type::mem_ctx = NULL; +_glthread_DECLARE_STATIC_MUTEX(type_mutex); void glsl_type::init_ralloc_type_ctx(void) @@ -55,8 +56,11 @@ glsl_type::glsl_type(GLenum gl_type, vector_elements(vector_elements), matrix_columns(matrix_columns), length(0) { + _glthread_LOCK_MUTEX(type_mutex); init_ralloc_type_ctx(); this->name = ralloc_strdup(this->mem_ctx, name); + _glthread_UNLOCK_MUTEX(type_mutex); + /* Neither dimension is zero or both dimensions are zero. */ assert((vector_elements == 0) == (matrix_columns == 0)); @@ -73,13 +77,16 @@ glsl_type::glsl_type(GLenum gl_type, vector_elements(0), matrix_columns(0), length(0) { + _glthread_LOCK_MUTEX(type_mutex); init_ralloc_type_ctx(); this->name = ralloc_strdup(this->mem_ctx, name); + _glthread_UNLOCK_MUTEX(type_mutex); + memset(& fields, 0, sizeof(fields)); } glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, - const char *name) : + const char *name, bool already_locked) : base_type(GLSL_TYPE_STRUCT), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), @@ -88,6 +95,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, { unsigned int i; + if (!already_locked) + _glthread_LOCK_MUTEX(type_mutex); init_ralloc_type_ctx(); this->name = ralloc_strdup(this->mem_ctx, name); this->fields.structure = ralloc_array(this->mem_ctx, @@ -97,6 +106,9 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, this->fields.structure[i].name = ralloc_strdup(this->fields.structure, fields[i].name); } + + if (!already_locked) + _glthread_UNLOCK_MUTEX(type_mutex); } static void @@ -350,6 +362,7 @@ const glsl_type *glsl_type::get_scalar_type() const void _mesa_glsl_release_types(void) { + _glthread_LOCK_MUTEX(type_mutex); if (glsl_type::array_types != NULL) { hash_table_dtor(glsl_type::array_types); glsl_type::array_types = NULL; @@ -359,10 +372,12 @@ _mesa_glsl_release_types(void) hash_table_dtor(glsl_type::record_types); glsl_type::record_types = NULL; } + _glthread_UNLOCK_MUTEX(type_mutex); } -glsl_type::glsl_type(const glsl_type *array, unsigned length) : +glsl_type::glsl_type(const glsl_type *array, unsigned length, + bool already_locked) : base_type(GLSL_TYPE_ARRAY), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), @@ -381,8 +396,15 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) : * NUL. */ const unsigned name_length = strlen(array->name) + 10 + 3; + + if (!already_locked) + _glthread_LOCK_MUTEX(type_mutex); + char *const n = (char *) ralloc_size(this->mem_ctx, name_length); + if (!already_locked) + _glthread_UNLOCK_MUTEX(type_mutex); + if (length == 0) snprintf(n, name_length, "%s[]", array->name); else @@ -454,6 +476,7 @@ const glsl_type * glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) { + _glthread_LOCK_MUTEX(type_mutex); if (array_types == NULL) { array_types = hash_table_ctor(64, hash_table_string_hash, hash_table_string_compare); @@ -469,10 +492,11 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) const glsl_type *t = (glsl_type *) hash_table_find(array_types, key); if (t == NULL) { - t = new glsl_type(base, array_size); + t = new glsl_type(base, array_size, true); hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key)); } + _glthread_UNLOCK_MUTEX(type_mutex); assert(t->base_type == GLSL_TYPE_ARRAY); assert(t->length == array_size); @@ -535,7 +559,8 @@ glsl_type::get_record_instance(const glsl_struct_field *fields, unsigned num_fields, const char *name) { - const glsl_type key(fields, num_fields, name); + _glthread_LOCK_MUTEX(type_mutex); + const glsl_type key(fields, num_fields, name, true); if (record_types == NULL) { record_types = hash_table_ctor(64, record_key_hash, record_key_compare); @@ -543,10 +568,11 @@ glsl_type::get_record_instance(const glsl_struct_field *fields, const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key); if (t == NULL) { - t = new glsl_type(fields, num_fields, name); + t = new glsl_type(fields, num_fields, name, true); hash_table_insert(record_types, (void *) t, t); } + _glthread_UNLOCK_MUTEX(type_mutex); assert(t->base_type == GLSL_TYPE_STRUCT); assert(t->length == num_fields); diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 915d1a2..ce1ee92 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -489,10 +489,10 @@ private: /** Constructor for record types */ glsl_type(const glsl_struct_field *fields, unsigned num_fields, - const char *name); + const char *name, bool already_locked); /** Constructor for array types */ - glsl_type(const glsl_type *array, unsigned length); + glsl_type(const glsl_type *array, unsigned length, bool already_locked); /** Hash table containing the known array types. */ static struct hash_table *array_types; -- 1.7.11.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev