mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
llvmpipe: Use a second LLVMContext for compiling sample functions
LLVMContextr is not thread safe. There are many code paths that use llvmpipe_context::context and adding locking to all of them is difficult and adds unnecessary overhead. This approach restricts locking to lp_sampler_matrix, which makes covering all uses of the LLVMContext easy and only adds overhead when running lavapipe. Fixes:7ebf7f4("llvmpipe: Compile sample functioins on demand") Reviewed-by: Roland Scheidegger <roland.scheidegger@broadcom.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29397> (cherry picked from commitc31038ef98)
This commit is contained in:
parent
7981b12585
commit
b3d9f853cd
3 changed files with 38 additions and 5 deletions
|
|
@ -2064,7 +2064,7 @@
|
|||
"description": "llvmpipe: Use a second LLVMContext for compiling sample functions",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "7ebf7f49a052c75f49496e31f7b3ccca716d30e5",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -200,6 +200,20 @@ llvmpipe_sampler_matrix_destroy(struct llvmpipe_context *ctx)
|
|||
gallivm_destroy(*gallivm);
|
||||
|
||||
util_dynarray_fini(&ctx->sampler_matrix.gallivms);
|
||||
|
||||
if (ctx->sampler_matrix.context)
|
||||
LLVMContextDispose(ctx->sampler_matrix.context);
|
||||
}
|
||||
|
||||
static LLVMContextRef
|
||||
get_llvm_context(struct llvmpipe_context *ctx)
|
||||
{
|
||||
struct lp_sampler_matrix *matrix = &ctx->sampler_matrix;
|
||||
|
||||
if (!matrix->context)
|
||||
matrix->context = LLVMContextCreate();
|
||||
|
||||
return matrix->context;
|
||||
}
|
||||
|
||||
static void *
|
||||
|
|
@ -261,7 +275,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||
lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
|
||||
bool needs_caching = !cached.data_size;
|
||||
|
||||
struct gallivm_state *gallivm = gallivm_create("sample_function", ctx->context, &cached);
|
||||
struct gallivm_state *gallivm = gallivm_create("sample_function", get_llvm_context(ctx), &cached);
|
||||
|
||||
struct lp_image_static_state state = {
|
||||
.image_state = *texture,
|
||||
|
|
@ -414,7 +428,7 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s
|
|||
lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
|
||||
bool needs_caching = !cached.data_size;
|
||||
|
||||
struct gallivm_state *gallivm = gallivm_create("sample_function", ctx->context, &cached);
|
||||
struct gallivm_state *gallivm = gallivm_create("sample_function", get_llvm_context(ctx), &cached);
|
||||
|
||||
struct lp_sampler_static_state state = {
|
||||
.texture_state = *texture,
|
||||
|
|
@ -543,7 +557,7 @@ compile_jit_sample_function(struct llvmpipe_context *ctx, uint32_t sample_key)
|
|||
lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
|
||||
bool needs_caching = !cached.data_size;
|
||||
|
||||
struct gallivm_state *gallivm = gallivm_create("jit_sample_function", ctx->context, &cached);
|
||||
struct gallivm_state *gallivm = gallivm_create("jit_sample_function", get_llvm_context(ctx), &cached);
|
||||
|
||||
struct lp_type type;
|
||||
memset(&type, 0, sizeof type);
|
||||
|
|
@ -650,7 +664,7 @@ compile_size_function(struct llvmpipe_context *ctx, struct lp_static_texture_sta
|
|||
lp_disk_cache_find_shader(llvmpipe_screen(ctx->pipe.screen), &cached, cache_key);
|
||||
bool needs_caching = !cached.data_size;
|
||||
|
||||
struct gallivm_state *gallivm = gallivm_create("sample_function", ctx->context, &cached);
|
||||
struct gallivm_state *gallivm = gallivm_create("sample_function", get_llvm_context(ctx), &cached);
|
||||
|
||||
struct lp_sampler_static_state state = {
|
||||
.texture_state = *texture,
|
||||
|
|
@ -793,6 +807,8 @@ llvmpipe_register_texture(struct llvmpipe_context *ctx, struct lp_static_texture
|
|||
else
|
||||
entry->storage = true;
|
||||
|
||||
simple_mtx_lock(&matrix->lock);
|
||||
|
||||
if (entry->sampled) {
|
||||
if (entry->sample_functions) {
|
||||
entry->sample_functions = realloc(entry->sample_functions, matrix->sampler_count * sizeof(void **));
|
||||
|
|
@ -827,6 +843,8 @@ llvmpipe_register_texture(struct llvmpipe_context *ctx, struct lp_static_texture
|
|||
if (!entry->image_functions[image_op])
|
||||
entry->image_functions[image_op] = compile_image_function(ctx, state, image_op);
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&matrix->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -842,6 +860,8 @@ llvmpipe_register_sampler(struct llvmpipe_context *ctx, struct lp_static_sampler
|
|||
|
||||
matrix->samplers[matrix->sampler_count - 1] = *state;
|
||||
|
||||
simple_mtx_lock(&matrix->lock);
|
||||
|
||||
for (uint32_t i = 0; i < matrix->texture_count; i++) {
|
||||
struct lp_texture_functions *texture = matrix->textures[i];
|
||||
if (!texture->sampled)
|
||||
|
|
@ -866,6 +886,8 @@ llvmpipe_register_sampler(struct llvmpipe_context *ctx, struct lp_static_sampler
|
|||
*dst = NULL;
|
||||
compile_sample_functions(ctx, &texture->state, state, dst);
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&matrix->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -877,6 +899,8 @@ register_sample_key(struct llvmpipe_context *ctx, uint32_t sample_key)
|
|||
|
||||
BITSET_SET(matrix->sample_keys, sample_key);
|
||||
|
||||
simple_mtx_lock(&matrix->lock);
|
||||
|
||||
matrix->jit_sample_functions[sample_key] = compile_jit_sample_function(ctx, sample_key);
|
||||
|
||||
for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
|
||||
|
|
@ -902,6 +926,8 @@ register_sample_key(struct llvmpipe_context *ctx, uint32_t sample_key)
|
|||
for (uint32_t sampler_index = 0; sampler_index < matrix->sampler_count; sampler_index++)
|
||||
texture->sample_functions[sampler_index][sample_key] = matrix->jit_sample_functions[sample_key];
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&matrix->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -913,11 +939,15 @@ register_image_op(struct llvmpipe_context *ctx, uint32_t op)
|
|||
|
||||
BITSET_SET(matrix->image_ops, op);
|
||||
|
||||
simple_mtx_lock(&matrix->lock);
|
||||
|
||||
for (uint32_t texture_index = 0; texture_index < matrix->texture_count; texture_index++) {
|
||||
struct lp_texture_functions *texture = matrix->textures[texture_index];
|
||||
if (texture->storage)
|
||||
texture->image_functions[op] = compile_image_function(ctx, &texture->state, op);
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&matrix->lock);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ struct lp_sampler_matrix {
|
|||
|
||||
struct llvmpipe_context *ctx;
|
||||
|
||||
/* Use a separate LLVMContext since it is not thread safe but can be accessed by shaders. */
|
||||
LLVMContextRef context;
|
||||
|
||||
struct util_dynarray gallivms;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue