Mesa (master): mesa: retain gl_shader_programs after glDeleteProgram if they are in use
Timothy Arceri
tarceri at kemper.freedesktop.org
Thu Feb 16 04:05:36 UTC 2017
Module: Mesa
Branch: master
Commit: e6506b3cd2382a9a7e0a3494a964d2bafb3bebc3
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e6506b3cd2382a9a7e0a3494a964d2bafb3bebc3
Author: Timothy Arceri <t_arceri at yahoo.com.au>
Date: Thu Jan 26 19:29:20 2017 +1100
mesa: retain gl_shader_programs after glDeleteProgram if they are in use
Fixes regressions from c505d6d852220f4aaaee161465dd2c579647e672.
Switching from using gl_shader_program to gl_program for the pipline
objects CurrentProgram array meant we were freeing gl_shader_programs
immediately after glDeleteProgram was called, but the spec states
the program should only get deleted once it is no longer in use.
To work around this we add a new ReferencedPrograms array to track
gl_shader_programs in use.
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
---
src/mesa/drivers/common/meta.c | 2 +-
src/mesa/main/mtypes.h | 2 ++
src/mesa/main/pipelineobj.c | 6 ++++--
src/mesa/main/shaderapi.c | 14 +++++++++-----
src/mesa/main/shaderapi.h | 2 +-
5 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 5b99c6b..2db4668 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -962,7 +962,7 @@ _mesa_meta_end(struct gl_context *ctx)
* program object must be NULL. _mesa_use_program is a no-op
* in that case.
*/
- _mesa_use_program(ctx, i, save->Program[i], &ctx->Shader);
+ _mesa_use_program(ctx, i, NULL, save->Program[i], &ctx->Shader);
/* Do this *before* killing the reference. :)
*/
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 08bd929..efe0cbc 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2875,6 +2875,8 @@ struct gl_pipeline_object
*/
struct gl_program *CurrentProgram[MESA_SHADER_STAGES];
+ struct gl_shader_program *ReferencedPrograms[MESA_SHADER_STAGES];
+
struct gl_program *_CurrentFragmentProgram;
/**
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index ec5df89..c1dd8d7 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -60,8 +60,10 @@ _mesa_delete_pipeline_object(struct gl_context *ctx,
_mesa_reference_program(ctx, &obj->_CurrentFragmentProgram, NULL);
- for (i = 0; i < MESA_SHADER_STAGES; i++)
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
_mesa_reference_program(ctx, &obj->CurrentProgram[i], NULL);
+ _mesa_reference_shader_program(ctx, &obj->ReferencedPrograms[i], NULL);
+ }
_mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
mtx_destroy(&obj->Mutex);
@@ -227,7 +229,7 @@ use_program_stage(struct gl_context *ctx, GLenum type,
if (shProg && shProg->_LinkedShaders[stage])
prog = shProg->_LinkedShaders[stage]->Program;
- _mesa_use_program(ctx, stage, prog, pipe);
+ _mesa_use_program(ctx, stage, shProg, prog, pipe);
}
/**
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 3de0a7e..86ce0bc 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1128,7 +1128,7 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
if (shProg->_LinkedShaders[stage])
prog = shProg->_LinkedShaders[stage]->Program;
- _mesa_use_program(ctx, stage, prog, ctx->_Shader);
+ _mesa_use_program(ctx, stage, shProg, prog, ctx->_Shader);
}
}
@@ -1243,7 +1243,8 @@ _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
static void
use_program(struct gl_context *ctx, gl_shader_stage stage,
- struct gl_program *new_prog, struct gl_pipeline_object *shTarget)
+ struct gl_shader_program *shProg, struct gl_program *new_prog,
+ struct gl_pipeline_object *shTarget)
{
struct gl_program **target;
@@ -1279,6 +1280,9 @@ use_program(struct gl_context *ctx, gl_shader_stage stage,
break;
}
+ _mesa_reference_shader_program(ctx,
+ &shTarget->ReferencedPrograms[stage],
+ shProg);
_mesa_reference_program(ctx, target, new_prog);
return;
}
@@ -1296,7 +1300,7 @@ _mesa_use_shader_program(struct gl_context *ctx,
struct gl_program *new_prog = NULL;
if (shProg && shProg->_LinkedShaders[i])
new_prog = shProg->_LinkedShaders[i]->Program;
- use_program(ctx, i, new_prog, &ctx->Shader);
+ use_program(ctx, i, shProg, new_prog, &ctx->Shader);
}
_mesa_active_program(ctx, shProg, "glUseProgram");
}
@@ -2180,10 +2184,10 @@ invalid_value:
void
_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
- struct gl_program *prog,
+ struct gl_shader_program *shProg, struct gl_program *prog,
struct gl_pipeline_object *shTarget)
{
- use_program(ctx, stage, prog, shTarget);
+ use_program(ctx, stage, shProg, prog, shTarget);
}
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index a89dbfb..99b4fe8 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -215,7 +215,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value);
void
_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
- struct gl_program *prog,
+ struct gl_shader_program *shProg, struct gl_program *prog,
struct gl_pipeline_object *shTarget);
extern void
More information about the mesa-commit
mailing list