diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2015-03-26 11:32:59 +0900 |
---|---|---|
committer | Emil Velikov <emil.l.velikov@gmail.com> | 2015-04-08 18:45:32 +0100 |
commit | 64d0f0e3b24c7d3ffd7bde921aadfccf3f12df0c (patch) | |
tree | 4c8b596c6b816d90069500a5d1d2a73cb3bbfa4d | |
parent | 9a3a2479d49ac2e22e4c4b253a20e75aca38a77a (diff) |
radeonsi: Cache LLVMTargetMachineRef in context instead of in screen
Fixes a crash in genymotion with several threads compiling shaders
concurrently.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89746
Cc: 10.5 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
(cherry picked from commit d64adc3a79e419062432cfa8d1cbc437676a3fbd)
Conflicts:
src/gallium/drivers/radeonsi/si_shader.c
-rw-r--r-- | src/gallium/drivers/radeonsi/si_compute.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.c | 43 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 50 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_shaders.c | 4 |
6 files changed, 78 insertions, 30 deletions
diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c index 5009f699443..8ebcb8dc7d1 100644 --- a/src/gallium/drivers/radeonsi/si_compute.c +++ b/src/gallium/drivers/radeonsi/si_compute.c @@ -130,7 +130,8 @@ static void *si_create_compute_state( for (i = 0; i < program->num_kernels; i++) { LLVMModuleRef mod = radeon_llvm_get_kernel_module(program->llvm_ctx, i, code, header->num_bytes); - si_compile_llvm(sctx->screen, &program->kernels[i], mod); + si_compile_llvm(sctx->screen, &program->kernels[i], sctx->tm, + mod); LLVMDisposeModule(mod); } } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 26182c25a41..e761d20e92c 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -69,6 +69,11 @@ static void si_destroy_context(struct pipe_context *context) si_pm4_cleanup(sctx); r600_common_context_cleanup(&sctx->b); + +#if HAVE_LLVM >= 0x0306 + LLVMDisposeTargetMachine(sctx->tm); +#endif + FREE(sctx); } @@ -77,6 +82,12 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, void * struct si_context *sctx = CALLOC_STRUCT(si_context); struct si_screen* sscreen = (struct si_screen *)screen; struct radeon_winsys *ws = sscreen->b.ws; + LLVMTargetRef r600_target; +#if HAVE_LLVM >= 0x0306 + const char *triple = "amdgcn--"; +#else + const char *triple = "r600--"; +#endif int shader, i; if (sctx == NULL) @@ -167,6 +178,17 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, void * */ sctx->scratch_waves = 32 * sscreen->b.info.max_compute_units; +#if HAVE_LLVM >= 0x0306 + /* Initialize LLVM TargetMachine */ + r600_target = radeon_llvm_get_r600_target(triple); + sctx->tm = LLVMCreateTargetMachine(r600_target, triple, + r600_get_llvm_processor_name(sscreen->b.family), + "+DumpCode,+vgpr-spilling", + LLVMCodeGenLevelDefault, + LLVMRelocDefault, + LLVMCodeModelDefault); +#endif + return &sctx->b.b; fail: si_destroy_context(&sctx->b.b); @@ -435,12 +457,6 @@ static void si_destroy_screen(struct pipe_screen* pscreen) if (!sscreen->b.ws->unref(sscreen->b.ws)) return; -#if HAVE_LLVM >= 0x0306 - // r600_destroy_common_screen() frees sscreen, so we need to make - // sure to dispose the TargetMachine before we call it. - LLVMDisposeTargetMachine(sscreen->tm); -#endif - r600_destroy_common_screen(&sscreen->b); } @@ -498,12 +514,7 @@ static bool si_initialize_pipe_config(struct si_screen *sscreen) struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws) { struct si_screen *sscreen = CALLOC_STRUCT(si_screen); - LLVMTargetRef r600_target; -#if HAVE_LLVM >= 0x0306 - const char *triple = "amdgcn--"; -#else - const char *triple = "r600--"; -#endif + if (sscreen == NULL) { return NULL; } @@ -531,13 +542,5 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws) /* Create the auxiliary context. This must be done last. */ sscreen->b.aux_context = sscreen->b.b.context_create(&sscreen->b.b, NULL); -#if HAVE_LLVM >= 0x0306 - /* Initialize LLVM TargetMachine */ - r600_target = radeon_llvm_get_r600_target(triple); - sscreen->tm = LLVMCreateTargetMachine(r600_target, triple, - r600_get_llvm_processor_name(sscreen->b.family), - "+DumpCode,+vgpr-spilling", LLVMCodeGenLevelDefault, LLVMRelocDefault, - LLVMCodeModelDefault); -#endif return &sscreen->b.b; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 059fe0dc99b..63fe54faa8e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -83,7 +83,6 @@ struct si_compute; struct si_screen { struct r600_common_screen b; - LLVMTargetMachineRef tm; }; struct si_sampler_view { @@ -200,6 +199,8 @@ struct si_context { struct pipe_resource *esgs_ring; struct pipe_resource *gsvs_ring; + LLVMTargetMachineRef tm; + /* SI state handling */ union si_state queued; union si_state emitted; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 81ce3f67f44..a86d4b18bed 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -72,6 +72,7 @@ struct si_shader_context int param_streamout_offset[4]; int param_vertex_id; int param_instance_id; + LLVMTargetMachineRef tm; LLVMValueRef const_md; LLVMValueRef const_resource[SI_NUM_CONST_BUFFERS]; LLVMValueRef ddxy_lds; @@ -2638,13 +2639,13 @@ int si_shader_binary_read(struct si_screen *sscreen, } int si_compile_llvm(struct si_screen *sscreen, struct si_shader *shader, - LLVMModuleRef mod) + LLVMTargetMachineRef tm, LLVMModuleRef mod) { int r = 0; bool dump = r600_can_dump_shader(&sscreen->b, shader->selector ? shader->selector->tokens : NULL); r = radeon_llvm_compile(mod, &shader->binary, - r600_get_llvm_processor_name(sscreen->b.family), dump, sscreen->tm); + r600_get_llvm_processor_name(sscreen->b.family), dump, tm); if (r) { return r; @@ -2732,7 +2733,7 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen, fprintf(stderr, "Copy Vertex Shader for Geometry Shader:\n\n"); r = si_compile_llvm(sscreen, si_shader_ctx->shader, - bld_base->base.gallivm->module); + si_shader_ctx->tm, bld_base->base.gallivm->module); radeon_llvm_dispose(&si_shader_ctx->radeon_bld); @@ -2740,7 +2741,45 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen, return r; } -int si_shader_create(struct si_screen *sscreen, struct si_shader *shader) +static void si_dump_key(unsigned shader, union si_shader_key *key) +{ + int i; + + fprintf(stderr, "SHADER KEY\n"); + + switch (shader) { + case PIPE_SHADER_VERTEX: + fprintf(stderr, " instance_divisors = {"); + for (i = 0; i < Elements(key->vs.instance_divisors); i++) + fprintf(stderr, !i ? "%u" : ", %u", + key->vs.instance_divisors[i]); + fprintf(stderr, "}\n"); + + if (key->vs.as_es) + fprintf(stderr, " gs_used_inputs = 0x%"PRIx64"\n", + key->vs.gs_used_inputs); + fprintf(stderr, " as_es = %u\n", key->vs.as_es); + break; + + case PIPE_SHADER_GEOMETRY: + break; + + case PIPE_SHADER_FRAGMENT: + fprintf(stderr, " export_16bpc = 0x%X\n", key->ps.export_16bpc); + fprintf(stderr, " last_cbuf = %u\n", key->ps.last_cbuf); + fprintf(stderr, " color_two_side = %u\n", key->ps.color_two_side); + fprintf(stderr, " alpha_func = %u\n", key->ps.alpha_func); + fprintf(stderr, " alpha_to_one = %u\n", key->ps.alpha_to_one); + fprintf(stderr, " poly_stipple = %u\n", key->ps.poly_stipple); + break; + + default: + assert(0); + } +} + +int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm, + struct si_shader *shader) { struct si_shader_selector *sel = shader->selector; struct tgsi_token *tokens = sel->tokens; @@ -2812,6 +2851,7 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader) si_shader_ctx.shader = shader; si_shader_ctx.type = tgsi_get_processor_type(tokens); si_shader_ctx.screen = sscreen; + si_shader_ctx.tm = tm; switch (si_shader_ctx.type) { case TGSI_PROCESSOR_VERTEX: @@ -2867,7 +2907,7 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader) radeon_llvm_finalize_module(&si_shader_ctx.radeon_bld); mod = bld_base->base.gallivm->module; - r = si_compile_llvm(sscreen, shader, mod); + r = si_compile_llvm(sscreen, shader, tm, mod); if (r) { fprintf(stderr, "LLVM failed to compile shader\n"); goto out; diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 551c7dc9f23..0727b534f24 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -181,9 +181,10 @@ static inline struct si_shader* si_get_vs_state(struct si_context *sctx) } /* radeonsi_shader.c */ -int si_shader_create(struct si_screen *sscreen, struct si_shader *shader); +int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm, + struct si_shader *shader); int si_compile_llvm(struct si_screen *sscreen, struct si_shader *shader, - LLVMModuleRef mod); + LLVMTargetMachineRef tm, LLVMModuleRef mod); void si_shader_destroy(struct pipe_context *ctx, struct si_shader *shader); unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index); int si_shader_binary_read(struct si_screen *sscreen, struct si_shader *shader, diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 5b463365c96..ba3b31eb2a6 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -398,6 +398,7 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx, static int si_shader_select(struct pipe_context *ctx, struct si_shader_selector *sel) { + struct si_context *sctx = (struct si_context *)ctx; union si_shader_key key; struct si_shader * shader = NULL; int r; @@ -437,7 +438,8 @@ static int si_shader_select(struct pipe_context *ctx, shader->next_variant = sel->current; sel->current = shader; - r = si_shader_create((struct si_screen*)ctx->screen, shader); + r = si_shader_create((struct si_screen*)ctx->screen, sctx->tm, + shader); if (unlikely(r)) { R600_ERR("Failed to build shader variant (type=%u) %d\n", sel->type, r); |