diff options
author | Kenneth Graunke <[email protected]> | 2010-11-17 11:03:57 -0800 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2010-11-30 13:48:28 -0800 |
commit | 2da02e75b17dcfb2efc3ce053c48339109bc0f26 (patch) | |
tree | e0827a8daf9d433b00839e4e7da07563654b96bd /src/glsl/linker.cpp | |
parent | ff994eeff8fa9f8f889878d6b48015ca7683e22b (diff) |
glsl/linker: Free any IR discarded by optimization passes.
Previously, IR for a linked shader was allocated directly out of the
gl_shader object - meaning all of it lived as long as the shader.
Now, IR is allocated out of a temporary context, and any -live- IR is
reparented/stolen to (effectively) the gl_shader. Any remaining IR can
be freed.
NOTE: This is a candidate for the 7.9 branch.
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r-- | src/glsl/linker.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 8d14c5afdff..cde70adff56 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -726,7 +726,8 @@ get_main_function_signature(gl_shader *sh) * shader is returned. */ static struct gl_shader * -link_intrastage_shaders(struct gl_context *ctx, +link_intrastage_shaders(void *mem_ctx, + struct gl_context *ctx, struct gl_shader_program *prog, struct gl_shader **shader_list, unsigned num_shaders) @@ -802,7 +803,7 @@ link_intrastage_shaders(struct gl_context *ctx, gl_shader *linked = ctx->Driver.NewShader(NULL, 0, main->Type); linked->ir = new(linked) exec_list; - clone_ir_list(linked, linked->ir, main->ir); + clone_ir_list(mem_ctx, linked->ir, main->ir); populate_symbol_table(linked); @@ -1407,6 +1408,8 @@ assign_varying_locations(struct gl_shader_program *prog, void link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) { + void *mem_ctx = talloc_init("temporary linker context"); + prog->LinkStatus = false; prog->Validated = false; prog->_Used = false; @@ -1475,7 +1478,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) */ if (num_vert_shaders > 0) { gl_shader *const sh = - link_intrastage_shaders(ctx, prog, vert_shader_list, num_vert_shaders); + link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list, + num_vert_shaders); if (sh == NULL) goto done; @@ -1489,7 +1493,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (num_frag_shaders > 0) { gl_shader *const sh = - link_intrastage_shaders(ctx, prog, frag_shader_list, num_frag_shaders); + link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list, + num_frag_shaders); if (sh == NULL) goto done; @@ -1598,4 +1603,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) done: free(vert_shader_list); + + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + + /* Retain any live IR, but trash the rest. */ + reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir); + } + + talloc_free(mem_ctx); } |