summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/shaderapi.c
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2017-01-26 19:29:20 +1100
committerTimothy Arceri <[email protected]>2017-02-16 15:01:41 +1100
commite6506b3cd2382a9a7e0a3494a964d2bafb3bebc3 (patch)
tree2b4a50bf5da75da19f94c72dac3fb2f1e7ae0a65 /src/mesa/main/shaderapi.c
parent300900516d1e15edd86ea0512f9b5ccda85d150e (diff)
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 <[email protected]>
Diffstat (limited to 'src/mesa/main/shaderapi.c')
-rw-r--r--src/mesa/main/shaderapi.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 3de0a7eeabf..86ce0bc5fdf 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);
}