[Mesa-dev] [PATCH v2] swr: fix memory leaks from vs/fs compilation

Tim Rowley timothy.o.rowley at intel.com
Thu Apr 21 00:42:16 UTC 2016


v2: varient -> variant
---
 src/gallium/drivers/swr/swr_shader.cpp | 41 ++++++++++++++++++++--------------
 src/gallium/drivers/swr/swr_state.cpp  |  6 ++---
 src/gallium/drivers/swr/swr_state.h    | 17 ++++++++++++--
 3 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp
index 83e3216..f693f51 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<JitManager *>(swr_screen(ctx->pipe.screen)->hJitMgr));
-   return builder.CompileVS(ctx, key);
+      reinterpret_cast<JitManager *>(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<VariantVS>(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<JitManager *>(swr_screen(ctx->pipe.screen)->hJitMgr));
-   return builder.CompileFS(ctx, key);
+      reinterpret_cast<JitManager *>(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<VariantFS>(builder.gallivm, func)));
+   return func;
 }
diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp
index 4ce2d12..18c4fb2 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 32a5441..fb0319c 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 <unordered_map>
 
+template <typename T>
+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<PFN_VERTEX_FUNC> VariantVS;
+typedef ShaderVariant<PFN_PIXEL_KERNEL> VariantFS;
+
 /* skeleton */
 struct swr_vertex_shader {
    struct pipe_shader_state pipe;
    struct lp_tgsi_info info;
    unsigned linkageMask;
-   std::unordered_map<swr_jit_vs_key, PFN_VERTEX_FUNC> map;
+   std::unordered_map<swr_jit_vs_key, std::unique_ptr<VariantVS>> 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<swr_jit_fs_key, PFN_PIXEL_KERNEL> map;
+   std::unordered_map<swr_jit_fs_key, std::unique_ptr<VariantFS>> map;
 };
 
 /* Vertex element state */
-- 
1.9.1



More information about the mesa-dev mailing list