aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/shaderapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/shaderapi.c')
-rw-r--r--mesalib/src/mesa/main/shaderapi.c95
1 files changed, 32 insertions, 63 deletions
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index 9372d6dec..0e655a0d8 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -45,6 +45,7 @@
#include "main/mtypes.h"
#include "main/shaderapi.h"
#include "main/shaderobj.h"
+#include "main/uniforms.h"
#include "program/program.h"
#include "program/prog_parameter.h"
#include "ralloc.h"
@@ -124,6 +125,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 +879,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;
}
@@ -900,61 +930,6 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
/**
- * Validate a program's samplers.
- * Specifically, check that there aren't two samplers of different types
- * pointing to the same texture unit.
- * \return GL_TRUE if valid, GL_FALSE if invalid
- */
-static GLboolean
-validate_samplers(const struct gl_program *prog, char *errMsg)
-{
- static const char *targetName[] = {
- "TEXTURE_BUFFER",
- "TEXTURE_2D_ARRAY",
- "TEXTURE_1D_ARRAY",
- "TEXTURE_EXTERNAL",
- "TEXTURE_CUBE",
- "TEXTURE_3D",
- "TEXTURE_RECT",
- "TEXTURE_2D",
- "TEXTURE_1D",
- };
- GLint targetUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
- GLbitfield samplersUsed = prog->SamplersUsed;
- GLuint i;
-
- STATIC_ASSERT(Elements(targetName) == NUM_TEXTURE_TARGETS);
-
- if (samplersUsed == 0x0)
- return GL_TRUE;
-
- for (i = 0; i < Elements(targetUsed); i++)
- targetUsed[i] = -1;
-
- /* walk over bits which are set in 'samplers' */
- while (samplersUsed) {
- GLuint unit;
- gl_texture_index target;
- GLint sampler = _mesa_ffs(samplersUsed) - 1;
- assert(sampler >= 0);
- assert(sampler < Elements(prog->SamplerUnits));
- unit = prog->SamplerUnits[sampler];
- target = prog->SamplerTargets[sampler];
- if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) {
- _mesa_snprintf(errMsg, 100,
- "Texture unit %d is accessed both as %s and %s",
- unit, targetName[targetUsed[unit]], targetName[target]);
- return GL_FALSE;
- }
- targetUsed[unit] = target;
- samplersUsed ^= (1 << sampler);
- }
-
- return GL_TRUE;
-}
-
-
-/**
* Do validation of the given shader program.
* \param errMsg returns error message if validation fails.
* \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
@@ -963,8 +938,6 @@ static GLboolean
validate_shader_program(const struct gl_shader_program *shProg,
char *errMsg)
{
- unsigned i;
-
if (!shProg->LinkStatus) {
return GL_FALSE;
}
@@ -989,12 +962,8 @@ validate_shader_program(const struct gl_shader_program *shProg,
* Check: any two active samplers in the current program object are of
* different types, but refer to the same texture image unit,
*/
- for (i = 0; i < Elements(shProg->_LinkedShaders); i++) {
- if (shProg->_LinkedShaders[i]
- && !validate_samplers(shProg->_LinkedShaders[i]->Program, errMsg)) {
- return GL_FALSE;
- }
- }
+ if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
+ return GL_FALSE;
return GL_TRUE;
}