summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/mtypes.h2
-rw-r--r--src/mesa/main/shaderapi.c29
-rw-r--r--src/mesa/main/state.c10
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);