mesa: Free old linked shaders when relinking new shaders.
authorEric Anholt <eric@anholt.net>
Wed, 18 Aug 2010 19:02:35 +0000 (12:02 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 18 Aug 2010 21:16:07 +0000 (14:16 -0700)
src/glsl/linker.cpp
src/glsl/main.cpp
src/glsl/program.h
src/mesa/program/ir_to_mesa.cpp

index 4172e41..b256574 100644 (file)
@@ -674,7 +674,8 @@ get_main_function_signature(gl_shader *sh)
  * shader is returned.
  */
 static struct gl_shader *
-link_intrastage_shaders(struct gl_shader_program *prog,
+link_intrastage_shaders(GLcontext *ctx,
+                       struct gl_shader_program *prog,
                        struct gl_shader **shader_list,
                        unsigned num_shaders)
 {
@@ -747,7 +748,7 @@ link_intrastage_shaders(struct gl_shader_program *prog,
       return NULL;
    }
 
-   gl_shader *const linked = _mesa_new_shader(NULL, 0, main->Type);
+   gl_shader *const linked = ctx->Driver.NewShader(NULL, 0, main->Type);
    linked->ir = new(linked) exec_list;
    clone_ir_list(linked, linked->ir, main->ir);
 
@@ -1212,7 +1213,7 @@ assign_varying_locations(struct gl_shader_program *prog,
 
 
 void
-link_shaders(struct gl_shader_program *prog)
+link_shaders(GLcontext *ctx, struct gl_shader_program *prog)
 {
    prog->LinkStatus = false;
    prog->Validated = false;
@@ -1270,12 +1271,16 @@ link_shaders(struct gl_shader_program *prog)
 
    prog->Version = max_version;
 
+   for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) {
+      ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]);
+   }
+
    /* Link all shaders for a particular stage and validate the result.
     */
    prog->_NumLinkedShaders = 0;
    if (num_vert_shaders > 0) {
       gl_shader *const sh =
-        link_intrastage_shaders(prog, vert_shader_list, num_vert_shaders);
+        link_intrastage_shaders(ctx, prog, vert_shader_list, num_vert_shaders);
 
       if (sh == NULL)
         goto done;
@@ -1289,7 +1294,7 @@ link_shaders(struct gl_shader_program *prog)
 
    if (num_frag_shaders > 0) {
       gl_shader *const sh =
-        link_intrastage_shaders(prog, frag_shader_list, num_frag_shaders);
+        link_intrastage_shaders(ctx, prog, frag_shader_list, num_frag_shaders);
 
       if (sh == NULL)
         goto done;
index 24d6076..cb9f8a5 100644 (file)
@@ -209,6 +209,10 @@ int
 main(int argc, char **argv)
 {
    int status = EXIT_SUCCESS;
+   GLcontext local_ctx;
+   GLcontext *ctx = &local_ctx;
+
+   ctx->Driver.NewShader = _mesa_new_shader;
 
    int c;
    int idx = 0;
@@ -265,7 +269,7 @@ main(int argc, char **argv)
    }
 
    if ((status == EXIT_SUCCESS) && do_link)  {
-      link_shaders(whole_program);
+      link_shaders(ctx, whole_program);
       status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
 
       if (strlen(whole_program->InfoLog) > 0)
index 0a49203..ea2c4ab 100644 (file)
@@ -30,4 +30,4 @@ extern "C" {
 }
 
 extern void
-link_shaders(struct gl_shader_program *prog);
+link_shaders(GLcontext *ctx, struct gl_shader_program *prog);
index 4f49943..394370d 100644 (file)
@@ -2740,7 +2740,7 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
    _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
 
    if (prog->LinkStatus) {
-      link_shaders(prog);
+      link_shaders(ctx, prog);
 
       /* We don't use the linker's uniforms list, and cook up our own at
        * generate time.