On Fri, Mar 27, 2015 at 10:05:06AM +0900, Michel Dänzer wrote: > From: Michel Dänzer <michel.daen...@amd.com> > > 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-sta...@lists.freedesktop.org> > Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
Reviewed-by: Tom Stellard <thomas.stell...@amd.com> Thanks for looking into this. > --- > src/gallium/drivers/radeonsi/si_compute.c | 3 +- > src/gallium/drivers/radeonsi/si_pipe.c | 43 > +++++++++++++------------ > src/gallium/drivers/radeonsi/si_pipe.h | 3 +- > src/gallium/drivers/radeonsi/si_shader.c | 13 +++++--- > src/gallium/drivers/radeonsi/si_shader.h | 5 +-- > src/gallium/drivers/radeonsi/si_state_shaders.c | 4 ++- > 6 files changed, 41 insertions(+), 30 deletions(-) > > diff --git a/src/gallium/drivers/radeonsi/si_compute.c > b/src/gallium/drivers/radeonsi/si_compute.c > index 8609b89..89bef2e 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 d335bda..0eada72 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) > @@ -170,6 +181,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); > @@ -445,12 +467,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); > } > > @@ -508,12 +524,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; > } > @@ -541,13 +552,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 422b873..f98c7a8 100644 > --- a/src/gallium/drivers/radeonsi/si_pipe.h > +++ b/src/gallium/drivers/radeonsi/si_pipe.h > @@ -85,7 +85,6 @@ struct si_compute; > > struct si_screen { > struct r600_common_screen b; > - LLVMTargetMachineRef tm; > }; > > struct si_sampler_view { > @@ -203,6 +202,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 4dcf756..b4709ac 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; > @@ -2697,13 +2698,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; > @@ -2791,7 +2792,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); > > @@ -2836,7 +2837,8 @@ static void si_dump_key(unsigned shader, union > si_shader_key *key) > } > } > > -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) > { > struct si_shader_selector *sel = shader->selector; > struct tgsi_token *tokens = sel->tokens; > @@ -2909,6 +2911,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: > @@ -2964,7 +2967,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 5b602ac..51055af 100644 > --- a/src/gallium/drivers/radeonsi/si_shader.h > +++ b/src/gallium/drivers/radeonsi/si_shader.h > @@ -183,9 +183,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 382738a..b0a6fb9 100644 > --- a/src/gallium/drivers/radeonsi/si_state_shaders.c > +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c > @@ -405,6 +405,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; > @@ -444,7 +445,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); > -- > 2.1.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev