}
/* Local shader has no exact candidates; check the built-ins. */
- _mesa_glsl_initialize_builtin_functions();
sig = _mesa_glsl_find_builtin_function(state, name, actual_parameters);
/* if _mesa_glsl_find_builtin_function failed, fall back to the result
*/
if (state->es_shader) {
/* Local shader has no exact candidates; check the built-ins. */
- _mesa_glsl_initialize_builtin_functions();
if (state->language_version >= 300 &&
_mesa_glsl_has_builtin_function(state, name)) {
YYLTYPE loc = this->get_location();
if (mem_ctx != NULL)
return;
+ glsl_type_singleton_init_or_ref();
+
mem_ctx = ralloc_context(NULL);
create_shader();
create_intrinsics();
ralloc_free(shader);
shader = NULL;
+
+ glsl_type_singleton_decref();
}
void
/* The singleton instance of builtin_builder. */
static builtin_builder builtins;
static mtx_t builtins_lock = _MTX_INITIALIZER_NP;
+static uint32_t builtin_users = 0;
/**
* External API (exposing the built-in module to the rest of the compiler):
* @{
*/
-void
-_mesa_glsl_initialize_builtin_functions()
+extern "C" void
+_mesa_glsl_builtin_functions_init_or_ref()
{
mtx_lock(&builtins_lock);
- builtins.initialize();
+ if (builtin_users++ == 0)
+ builtins.initialize();
mtx_unlock(&builtins_lock);
}
-void
-_mesa_glsl_release_builtin_functions()
+extern "C" void
+_mesa_glsl_builtin_functions_decref()
{
mtx_lock(&builtins_lock);
- builtins.release();
+ assert(builtin_users != 0);
+ if (--builtin_users == 0)
+ builtins.release();
mtx_unlock(&builtins_lock);
}
struct gl_shader;
-extern void
-_mesa_glsl_initialize_builtin_functions();
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+_mesa_glsl_builtin_functions_init_or_ref();
+
+void
+_mesa_glsl_builtin_functions_decref(void);
+
+#ifdef __cplusplus
+
+} /* extern "C" */
extern ir_function_signature *
_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
extern ir_function_signature *
_mesa_get_main_function_signature(glsl_symbol_table *symbols);
-extern void
-_mesa_glsl_release_builtin_functions(void);
-
namespace generate_ir {
ir_function_signature *
}
+#endif /* __cplusplus */
+
#endif /* BULITIN_FUNCTIONS_H */
return progress;
}
-
-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
- * programs would be invalid. So this should happen at approximately
- * program exit.
- */
-void
-_mesa_destroy_shader_compiler(void)
-{
- _mesa_destroy_shader_compiler_caches();
-}
-
-/**
- * Releases compiler caches to trade off performance for memory.
- *
- * Intended to be used with glReleaseShaderCompiler().
- */
-void
-_mesa_destroy_shader_compiler_caches(void)
-{
- _mesa_glsl_release_builtin_functions();
-}
-
-}
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);
-
extern void
_mesa_glsl_copy_symbols_from_table(struct exec_list *shader_ir,
struct glsl_symbol_table *src,
initialize_context(struct gl_context *ctx, gl_api api)
{
initialize_context_to_defaults(ctx, api);
- glsl_type_singleton_init_or_ref();
+ _mesa_glsl_builtin_functions_init_or_ref();
/* The standalone compiler needs to claim support for almost
* everything in order to compile the built-in functions.
delete whole_program->FragDataIndexBindings;
ralloc_free(whole_program);
- glsl_type_singleton_decref();
- _mesa_glsl_release_builtin_functions();
+ _mesa_glsl_builtin_functions_decref();
}
#endif
#include "compiler/glsl_types.h"
+#include "compiler/glsl/builtin_functions.h"
#include "compiler/glsl/glsl_parser_extras.h"
#include <stdbool.h>
static void
one_time_fini(void)
{
- _mesa_destroy_shader_compiler();
+ glsl_type_singleton_decref();
_mesa_locale_fini();
}
_mesa_debug(ctx, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n");
}
#endif
+
+ /* Take a glsl type reference for the duration of libGL's life to avoid
+ * unecessary creation/destruction of glsl types.
+ */
+ glsl_type_singleton_init_or_ref();
}
/* per-API one-time init */
/* misc one-time initializations */
one_time_init(ctx);
- _mesa_init_shader_compiler_types();
-
/* Plug in driver functions and context pointer here.
* This is important because when we call alloc_shared_state() below
* we'll call ctx->Driver.NewTextureObject() to create the default
free(ctx->VersionString);
- if (destroy_compiler_types)
- _mesa_destroy_shader_compiler_types();
-
ralloc_free(ctx->SoftFP64);
/* unbind the context if it's currently bound */
_mesa_make_current(NULL, NULL, NULL);
}
+ /* Do this after unbinding context to ensure any thread is finished. */
+ if (ctx->shader_builtin_ref) {
+ _mesa_glsl_builtin_functions_decref();
+ ctx->shader_builtin_ref = false;
+ }
+
free(ctx->Const.SpirVExtensions);
}
struct hash_table_u64 *ResidentTextureHandles;
struct hash_table_u64 *ResidentImageHandles;
/*@}*/
+
+ bool shader_builtin_ref;
};
/**
#include "main/state.h"
#include "main/transformfeedback.h"
#include "main/uniforms.h"
+#include "compiler/glsl/builtin_functions.h"
#include "compiler/glsl/glsl_parser_extras.h"
#include "compiler/glsl/ir.h"
#include "compiler/glsl/ir_uniform.h"
#endif
}
+static void
+ensure_builtin_types(struct gl_context *ctx)
+{
+ if (!ctx->shader_builtin_ref) {
+ _mesa_glsl_builtin_functions_init_or_ref();
+ ctx->shader_builtin_ref = true;
+ }
+}
/**
* Compile a shader.
_mesa_log("%s\n", sh->Source);
}
+ ensure_builtin_types(ctx);
+
/* this call will set the shader->CompileStatus field to indicate if
* compilation was successful.
*/
}
}
+ ensure_builtin_types(ctx);
+
FLUSH_VERTICES(ctx, 0);
_mesa_glsl_link_shader(ctx, shProg);
void GLAPIENTRY
_mesa_ReleaseShaderCompiler(void)
{
- _mesa_destroy_shader_compiler_caches();
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (ctx->shader_builtin_ref) {
+ _mesa_glsl_builtin_functions_decref();
+ ctx->shader_builtin_ref = false;
+ }
}
st_destroy_context_priv(st, true);
st = NULL;
- /* This must be called after st_destroy_context_priv() to avoid a race
- * condition between any shader compiler threads and context destruction.
- */
- _mesa_destroy_shader_compiler_types();
-
free(ctx);
if (save_ctx == ctx) {