mesa: retain gl_shader_programs after glDeleteProgram if they are in use
Fixes regressions from c505d6d852
.
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@whitecape.org>
This commit is contained in:
parent
300900516d
commit
e6506b3cd2
|
@ -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. :)
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue