gallium: fix a few more shader-related mem leaks
authorBrian <brian.paul@tungstengraphics.com>
Sat, 22 Mar 2008 16:29:30 +0000 (10:29 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Sat, 22 Mar 2008 16:29:30 +0000 (10:29 -0600)
src/mesa/state_tracker/st_atom_shader.c
src/mesa/state_tracker/st_atom_shader.h
src/mesa/state_tracker/st_cb_program.c
src/mesa/state_tracker/st_program.c

index 072668849304ab2f5cfd810213547bf35ea5645d..ec39026eb3203534e1b449cbec19e9ba0ae307ec 100644 (file)
@@ -77,34 +77,6 @@ struct translated_vertex_program
 
 
 
-/**
- * Free data hanging off the st vert prog.
- */
-void
-st_remove_vertex_program(struct st_context *st, struct st_vertex_program *stvp)
-{
-   /* no-op, for now? */
-}
-
-
-/**
- * Free data hanging off the st frag prog.
- */
-void
-st_remove_fragment_program(struct st_context *st,
-                          struct st_fragment_program *stfp)
-{
-   struct translated_vertex_program *xvp, *next;
-
-   for (xvp = stfp->vertex_programs; xvp; xvp = next) {
-      next = xvp->next;
-      /* XXX free xvp->vs */
-      free(xvp);
-   }
-}
-
-
-
 /**
  * Given a vertex program output attribute, return the corresponding
  * fragment program input attribute.
@@ -265,6 +237,21 @@ find_translated_vp(struct st_context *st,
 }
 
 
+void
+st_free_translated_vertex_programs(struct st_context *st,
+                                   struct translated_vertex_program *xvp)
+{
+   struct translated_vertex_program *next;
+
+   while (xvp) {
+      next = xvp->next;
+      free(xvp);
+      xvp = next;
+   }
+}
+
+
+
 static void
 update_linkage( struct st_context *st )
 {
index f3124d87c013f3f549c27bf22d89975663c586ab..8403bc66c928535cbe927b70e1f7db6e8ecb10b2 100644 (file)
 
 
 extern void
-st_remove_vertex_program(struct st_context *, struct st_vertex_program *);
-
-extern void
-st_remove_fragment_program(struct st_context *, struct st_fragment_program *);
+st_free_translated_vertex_programs(struct st_context *st,
+                                   struct translated_vertex_program *xvp);
 
 
 #endif /* ST_ATOM_SHADER_H */
index 7cf352d710b68d371a249eab1ebe8eea1ad96351..a739fcd3362e9d6ffad15c805850c467df20f61c 100644 (file)
@@ -132,25 +132,33 @@ static void st_delete_program( GLcontext *ctx,
    case GL_VERTEX_PROGRAM_ARB:
       {
          struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
-         st_remove_vertex_program(st, stvp);
+
          if (stvp->driver_shader) {
             pipe->delete_vs_state(pipe, stvp->driver_shader);
             stvp->driver_shader = NULL;
          }
+
+         if (stvp->state.tokens) {
+            FREE((void *) stvp->state.tokens);
+            stvp->state.tokens = NULL;
+         }
       }
       break;
    case GL_FRAGMENT_PROGRAM_ARB:
       {
-         struct st_fragment_program *stfp
-            = (struct st_fragment_program *) prog;
-         st_remove_fragment_program(st, stfp);
+         struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
+
          if (stfp->driver_shader) {
             pipe->delete_fs_state(pipe, stfp->driver_shader);
             stfp->driver_shader = NULL;
          }
+         
+         if (stfp->state.tokens) {
+            FREE((void *) stfp->state.tokens);
+            stfp->state.tokens = NULL;
+         }
 
-         assert(!stfp->vertex_programs);
-
+         st_free_translated_vertex_programs(st, stfp->vertex_programs);
       }
       break;
    default:
@@ -186,13 +194,13 @@ static void st_program_string_notify( GLcontext *ctx,
          stfp->driver_shader = NULL;
       }
 
-      stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
-
       if (stfp->state.tokens) {
          FREE((void *) stfp->state.tokens);
          stfp->state.tokens = NULL;
       }
 
+      stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
+
       if (st->fp == stfp)
         st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    }
@@ -211,13 +219,13 @@ static void st_program_string_notify( GLcontext *ctx,
          stvp->draw_shader = NULL;
       }
 
-      stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
-
       if (stvp->state.tokens) {
          FREE((void *) stvp->state.tokens);
          stvp->state.tokens = NULL;
       }
 
+      stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
+
       if (st->vp == stvp)
         st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
    }
index d9d11ee0e8420c61db607c4c26e0b267a5bb4361..101a6a48afdd9a570051c7a9be73dd3480dad18c 100644 (file)
@@ -260,6 +260,16 @@ st_translate_vertex_program(struct st_context *st,
       outputMapping = defaultOutputMapping;
    }
 
+   /* free old shader state, if any */
+   if (stvp->state.tokens) {
+      FREE((void *) stvp->state.tokens);
+      stvp->state.tokens = NULL;
+   }
+   if (stvp->driver_shader) {
+      pipe->delete_vs_state(pipe, stvp->driver_shader);
+      stvp->driver_shader = NULL;
+   }
+
    /* XXX: fix static allocation of tokens:
     */
    num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,