st/mesa/i965: simplify gl_program references and stop leaking
authorTimothy Arceri <timothy.arceri@collabora.com>
Thu, 17 Nov 2016 01:26:08 +0000 (12:26 +1100)
committerTimothy Arceri <timothy.arceri@collabora.com>
Fri, 18 Nov 2016 20:42:33 +0000 (07:42 +1100)
In i965 we were calling _mesa_reference_program() after creating
gl_program and then later calling it again with NULL as a param
to get the refcount back down to 1. This changes things to not
use _mesa_reference_program() at all and just have gl_linked_shader
take ownership of gl_program since refcount starts at 1.

The st and ir_to_mesa linkers were worse as they were both getting
in a state were the refcount would never get to 0 and we would leak
the program.

Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
src/mesa/drivers/dri/i965/brw_link.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_nir.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index fbb834be1a03f66f34ce557afca8c6fdaa38f5dd..a0c9e20807c684788cd5c186a95f116b3bdc4140 100644 (file)
@@ -227,7 +227,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
       if (!prog)
         return false;
 
-      _mesa_reference_program(ctx, &shader->Program, prog);
+      /* Don't use _mesa_reference_program() just take ownership */
+      shader->Program = prog;
 
       prog->Parameters = _mesa_new_parameter_list();
 
@@ -276,8 +277,6 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
 
       prog->nir = brw_create_nir(brw, shProg, prog, (gl_shader_stage) stage,
                                  compiler->scalar_stage[stage]);
-
-      _mesa_reference_program(ctx, &prog, NULL);
    }
 
    if ((ctx->_Shader->Flags & GLSL_DUMP) && shProg->Name != 0) {
index b042c86f9390c7b77201d219eab7b8c30318370a..7f4212333f11b219601b4e92582f8c65547203b5 100644 (file)
@@ -2929,7 +2929,8 @@ get_mesa_program(struct gl_context *ctx,
       prog->info.fs.depth_layout = shader_program->FragDepthLayout;
    }
 
-   _mesa_reference_program(ctx, &shader->Program, prog);
+   /* Don't use _mesa_reference_program() just take ownership */
+   shader->Program = prog;
 
    if ((ctx->_Shader->Flags & GLSL_NO_OPT) == 0) {
       _mesa_optimize_program(ctx, prog, prog);
@@ -3033,11 +3034,11 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
          if (!ctx->Driver.ProgramStringNotify(ctx,
                                               _mesa_shader_stage_to_program(i),
                                               linked_prog)) {
+            _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
+                                    NULL);
             return GL_FALSE;
          }
       }
-
-      _mesa_reference_program(ctx, &linked_prog, NULL);
    }
 
    build_program_resource_list(ctx, prog);
index 36531ad3047766a36e10703d413266d4937113f1..2d8cf81dcce9c0f63ab528594429ef8c065b3eff 100644 (file)
@@ -375,7 +375,8 @@ st_nir_get_mesa_program(struct gl_context *ctx,
    if (!prog)
       return NULL;
 
-   _mesa_reference_program(ctx, &shader->Program, prog);
+   /* Don't use _mesa_reference_program() just take ownership */
+   shader->Program = prog;
 
    prog->Parameters = _mesa_new_parameter_list();
 
index 7d67a598f0a3c45ceea26167270ba4c3026f79b7..b47e1470e3f13dc656e0212a6c5b1663c2242cab 100644 (file)
@@ -6419,7 +6419,8 @@ get_mesa_program_tgsi(struct gl_context *ctx,
    if (!prog)
       return NULL;
 
-   _mesa_reference_program(ctx, &shader->Program, prog);
+   /* Don't use _mesa_reference_program() just take ownership */
+   shader->Program = prog;
 
    prog->Parameters = _mesa_new_parameter_list();
    v = new glsl_to_tgsi_visitor();
@@ -6541,6 +6542,7 @@ get_mesa_program_tgsi(struct gl_context *ctx,
    _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters);
    if (!shader_program->LinkStatus) {
       free_glsl_to_tgsi_visitor(v);
+      _mesa_reference_program(ctx, &shader->Program, NULL);
       return NULL;
    }
 
@@ -6883,19 +6885,14 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
 
       if (linked_prog) {
-         _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
-                                 linked_prog);
          if (!ctx->Driver.ProgramStringNotify(ctx,
                                               _mesa_shader_stage_to_program(i),
                                               linked_prog)) {
             _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
                                     NULL);
-            _mesa_reference_program(ctx, &linked_prog, NULL);
             return GL_FALSE;
          }
       }
-
-      _mesa_reference_program(ctx, &linked_prog, NULL);
    }
 
    return GL_TRUE;