diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/mtypes.h | 2 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.c | 29 | ||||
-rw-r--r-- | src/mesa/main/state.c | 10 |
3 files changed, 41 insertions, 0 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bb46ba0c035..aca47379ca1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2350,6 +2350,8 @@ struct gl_shader_state struct gl_shader_program *CurrentGeometryProgram; struct gl_shader_program *CurrentFragmentProgram; + struct gl_shader_program *_CurrentFragmentProgram; + /** * Program used by glUniform calls. * diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 9372d6decf6..f3f13a02645 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -124,6 +124,8 @@ _mesa_free_shader_state(struct gl_context *ctx) NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram, NULL); + _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram, + NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); } @@ -876,6 +878,33 @@ use_shader_program(struct gl_context *ctx, GLenum type, if (*target != shProg) { FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + + /* If the shader is also bound as the current rendering shader, unbind + * it from that binding point as well. This ensures that the correct + * semantics of glDeleteProgram are maintained. + */ + switch (type) { +#if FEATURE_ARB_vertex_shader + case GL_VERTEX_SHADER: + /* Empty for now. */ + break; +#endif +#if FEATURE_ARB_geometry_shader4 + case GL_GEOMETRY_SHADER_ARB: + /* Empty for now. */ + break; +#endif +#if FEATURE_ARB_fragment_shader + case GL_FRAGMENT_SHADER: + if (*target == ctx->Shader._CurrentFragmentProgram) { + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + NULL); + } + break; +#endif + } + _mesa_reference_shader_program(ctx, target, shProg); return true; } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 7e43563bd01..56bb797e625 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -43,6 +43,7 @@ #include "pixel.h" #include "program/program.h" #include "program/prog_parameter.h" +#include "shaderobj.h" #include "state.h" #include "stencil.h" #include "texenvprogram.h" @@ -252,12 +253,18 @@ update_program(struct gl_context *ctx) if (fsProg && fsProg->LinkStatus && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { /* Use GLSL fragment shader */ + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + fsProg); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, (struct gl_fragment_program *) fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); } else if (ctx->FragmentProgram._Enabled) { /* Use user-defined fragment program */ + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + NULL); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, ctx->FragmentProgram.Current); } @@ -265,6 +272,9 @@ update_program(struct gl_context *ctx) /* Use fragment program generated from fixed-function state */ struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + f); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, (struct gl_fragment_program *) f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); |