llvm->draw = draw;
+ llvm->context = LLVMContextCreate();
+ if (!llvm->context)
+ goto fail;
+
llvm->nr_variants = 0;
make_empty_list(&llvm->vs_variants_list);
make_empty_list(&llvm->gs_variants_list);
return llvm;
+
+fail:
+ draw_llvm_destroy(llvm);
+ return NULL;
}
void
draw_llvm_destroy(struct draw_llvm *llvm)
{
+ LLVMContextDispose(llvm->context);
+ llvm->context = NULL;
+
/* XXX free other draw_llvm data? */
FREE(llvm);
}
util_snprintf(module_name, sizeof(module_name), "draw_llvm_vs_variant%u",
variant->shader->variants_cached);
- variant->gallivm = gallivm_create(module_name);
+ variant->gallivm = gallivm_create(module_name, llvm->context);
create_jit_types(variant);
util_snprintf(module_name, sizeof(module_name), "draw_llvm_gs_variant%u",
variant->shader->variants_cached);
- variant->gallivm = gallivm_create(module_name);
+ variant->gallivm = gallivm_create(module_name, llvm->context);
create_gs_jit_types(variant);
struct draw_llvm {
struct draw_context *draw;
+ LLVMContextRef context;
+
struct draw_jit_context jit_context;
struct draw_gs_jit_context gs_jit_context;
void LLVMLinkInMCJIT();
#endif
-/*
- * LLVM has several global caches which pointing/derived from objects
- * owned by the context, so if we freeing contexts causes
- * memory leaks and false cache hits when these objects are destroyed.
- *
- * TODO: For thread safety on multi-threaded OpenGL we should use one LLVM
- * context per thread, and put them in a pool when threads are destroyed.
- */
-#define USE_GLOBAL_CONTEXT 1
-
-
#ifdef DEBUG
unsigned gallivm_debug = 0;
if (gallivm->builder)
LLVMDisposeBuilder(gallivm->builder);
- if (!USE_GLOBAL_CONTEXT && gallivm->context)
- LLVMContextDispose(gallivm->context);
+ /* The LLVMContext should be owned by the parent of gallivm. */
gallivm->engine = NULL;
gallivm->target = NULL;
* \return TRUE for success, FALSE for failure
*/
static boolean
-init_gallivm_state(struct gallivm_state *gallivm, const char *name)
+init_gallivm_state(struct gallivm_state *gallivm, const char *name,
+ LLVMContextRef context)
{
assert(!gallivm->context);
assert(!gallivm->module);
if (!lp_build_init())
return FALSE;
- if (USE_GLOBAL_CONTEXT) {
- gallivm->context = LLVMGetGlobalContext();
- } else {
- gallivm->context = LLVMContextCreate();
- }
+ gallivm->context = context;
+
if (!gallivm->context)
goto fail;
* Create a new gallivm_state object.
*/
struct gallivm_state *
-gallivm_create(const char *name)
+gallivm_create(const char *name, LLVMContextRef context)
{
struct gallivm_state *gallivm;
gallivm = CALLOC_STRUCT(gallivm_state);
if (gallivm) {
- if (!init_gallivm_state(gallivm, name)) {
+ if (!init_gallivm_state(gallivm, name, context)) {
FREE(gallivm);
gallivm = NULL;
}
struct gallivm_state *
-gallivm_create(const char *name);
+gallivm_create(const char *name, LLVMContextRef context);
void
gallivm_destroy(struct gallivm_state *gallivm);
lp_delete_setup_variants(llvmpipe);
+ LLVMContextDispose(llvmpipe->context);
+ llvmpipe->context = NULL;
+
align_free( llvmpipe );
}
llvmpipe_init_context_resource_funcs( &llvmpipe->pipe );
llvmpipe_init_surface_functions(llvmpipe);
+ llvmpipe->context = LLVMContextCreate();
+ if (!llvmpipe->context)
+ goto fail;
+
/*
* Create drawing context and plug our rendering stage into it.
*/
struct pipe_query *render_cond_query;
uint render_cond_mode;
boolean render_cond_cond;
+
+ /** The LLVMContext to use for LLVM related work */
+ LLVMContextRef context;
};
util_snprintf(module_name, sizeof(module_name), "fs%u_variant%u",
shader->no, shader->variants_created);
- variant->gallivm = gallivm_create(module_name);
+ variant->gallivm = gallivm_create(module_name, lp->context);
if (!variant->gallivm) {
FREE(variant);
return NULL;
util_snprintf(func_name, sizeof(func_name), "setup_variant_%u",
variant->no);
- variant->gallivm = gallivm = gallivm_create(func_name);
+ variant->gallivm = gallivm = gallivm_create(func_name, lp->context);
if (!variant->gallivm) {
goto fail;
}
in[i] = 1.0;
}
- gallivm = gallivm_create("test_module");
+ gallivm = gallivm_create("test_module", LLVMGetGlobalContext());
test_func = build_unary_test_func(gallivm, test);
if(verbose >= 1)
dump_blend_type(stdout, blend, type);
- gallivm = gallivm_create("test_module");
+ gallivm = gallivm_create("test_module", LLVMGetGlobalContext());
func = add_blend_test(gallivm, blend, type);
eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type));
- gallivm = gallivm_create("test_module");
+ gallivm = gallivm_create("test_module", LLVMGetGlobalContext());
func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts);
boolean success = TRUE;
unsigned i, j, k, l;
- gallivm = gallivm_create("test_module_float");
+ gallivm = gallivm_create("test_module_float", LLVMGetGlobalContext());
fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_float32_vec4_type());
test_printf_t test_printf_func;
boolean success = TRUE;
- gallivm = gallivm_create("test_module");
+ gallivm = gallivm_create("test_module", LLVMGetGlobalContext());
test = add_printf_test(gallivm);