From: Tim Rowley Date: Thu, 21 Apr 2016 00:42:16 +0000 (-0500) Subject: swr: fix memory leaks from vs/fs compilation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ee9621e2f5653cf2dfa8589bd3a57bafb122c6bd;p=mesa.git swr: fix memory leaks from vs/fs compilation v2: varient -> variant Reviewed by: George Kyriazis --- diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index 83e32163ecc..f693f51bb49 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -124,12 +124,19 @@ swr_generate_vs_key(struct swr_jit_vs_key &key, } struct BuilderSWR : public Builder { - BuilderSWR(JitManager *pJitMgr) + BuilderSWR(JitManager *pJitMgr, const char *pName) : Builder(pJitMgr) { pJitMgr->SetupNewModule(); + gallivm = gallivm_create(pName, wrap(&JM()->mContext)); + pJitMgr->mpCurrentModule = unwrap(gallivm->module); } + ~BuilderSWR() { + gallivm_free_ir(gallivm); + } + + struct gallivm_state *gallivm; PFN_VERTEX_FUNC CompileVS(struct swr_context *ctx, swr_jit_vs_key &key); PFN_PIXEL_KERNEL CompileFS(struct swr_context *ctx, swr_jit_fs_key &key); }; @@ -151,12 +158,6 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key) } } - // tgsi_dump(swr_vs->pipe.tokens, 0); - - struct gallivm_state *gallivm = - gallivm_create("VS", wrap(&JM()->mContext)); - gallivm->module = wrap(JM()->mpCurrentModule); - LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS]; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; @@ -231,6 +232,8 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key) &swr_vs->info.base, NULL); // geometry shader face + sampler->destroy(sampler); + IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); Value *vtxOutput = LOAD(pVsCtx, {0, SWR_VS_CONTEXT_pVout}); @@ -273,8 +276,12 @@ PFN_VERTEX_FUNC swr_compile_vs(struct swr_context *ctx, swr_jit_vs_key &key) { BuilderSWR builder( - reinterpret_cast(swr_screen(ctx->pipe.screen)->hJitMgr)); - return builder.CompileVS(ctx, key); + reinterpret_cast(swr_screen(ctx->pipe.screen)->hJitMgr), + "VS"); + PFN_VERTEX_FUNC func = builder.CompileVS(ctx, key); + + ctx->vs->map.insert(std::make_pair(key, make_unique(builder.gallivm, func))); + return func; } static unsigned @@ -304,12 +311,6 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key) { struct swr_fragment_shader *swr_fs = ctx->fs; - // tgsi_dump(swr_fs->pipe.tokens, 0); - - struct gallivm_state *gallivm = - gallivm_create("FS", wrap(&JM()->mContext)); - gallivm->module = wrap(JM()->mpCurrentModule); - LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS]; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; @@ -540,6 +541,8 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key) &swr_fs->info.base, NULL); // geometry shader face + sampler->destroy(sampler); + IRB()->SetInsertPoint(unwrap(LLVMGetInsertBlock(gallivm->builder))); for (uint32_t attrib = 0; attrib < swr_fs->info.base.num_outputs; @@ -620,6 +623,10 @@ PFN_PIXEL_KERNEL swr_compile_fs(struct swr_context *ctx, swr_jit_fs_key &key) { BuilderSWR builder( - reinterpret_cast(swr_screen(ctx->pipe.screen)->hJitMgr)); - return builder.CompileFS(ctx, key); + reinterpret_cast(swr_screen(ctx->pipe.screen)->hJitMgr), + "FS"); + PFN_PIXEL_KERNEL func = builder.CompileFS(ctx, key); + + ctx->fs->map.insert(std::make_pair(key, make_unique(builder.gallivm, func))); + return func; } diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index 4ce2d12a48d..18c4fb23c9b 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -1030,10 +1030,9 @@ swr_update_derived(struct pipe_context *pipe, auto search = ctx->vs->map.find(key); PFN_VERTEX_FUNC func; if (search != ctx->vs->map.end()) { - func = search->second; + func = search->second->shader; } else { func = swr_compile_vs(ctx, key); - ctx->vs->map.insert(std::make_pair(key, func)); } SwrSetVertexFunc(ctx->swrContext, func); @@ -1062,10 +1061,9 @@ swr_update_derived(struct pipe_context *pipe, auto search = ctx->fs->map.find(key); PFN_PIXEL_KERNEL func; if (search != ctx->fs->map.end()) { - func = search->second; + func = search->second->shader; } else { func = swr_compile_fs(ctx, key); - ctx->fs->map.insert(std::make_pair(key, func)); } SWR_PS_STATE psState = {0}; psState.pfnPixelShader = func; diff --git a/src/gallium/drivers/swr/swr_state.h b/src/gallium/drivers/swr/swr_state.h index 32a5441295b..fb0319cc699 100644 --- a/src/gallium/drivers/swr/swr_state.h +++ b/src/gallium/drivers/swr/swr_state.h @@ -28,6 +28,7 @@ #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_dump.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_tgsi.h" #include "util/u_hash.h" #include "api.h" @@ -35,12 +36,24 @@ #include "swr_shader.h" #include +template +struct ShaderVariant { + struct gallivm_state *gallivm; + T shader; + + ShaderVariant(struct gallivm_state *gs, T code) : gallivm(gs), shader(code) {} + ~ShaderVariant() { gallivm_destroy(gallivm); } +}; + +typedef ShaderVariant VariantVS; +typedef ShaderVariant VariantFS; + /* skeleton */ struct swr_vertex_shader { struct pipe_shader_state pipe; struct lp_tgsi_info info; unsigned linkageMask; - std::unordered_map map; + std::unordered_map> map; SWR_STREAMOUT_STATE soState; PFN_SO_FUNC soFunc[PIPE_PRIM_MAX] {0}; }; @@ -50,7 +63,7 @@ struct swr_fragment_shader { struct lp_tgsi_info info; uint32_t constantMask; uint32_t pointSpriteMask; - std::unordered_map map; + std::unordered_map> map; }; /* Vertex element state */