#endif
#include "glsl_parser_extras.h"
-
+#include <stdbool.h>
#ifndef MESA_VERBOSE
GLboolean
_mesa_valid_to_render(GLcontext *ctx, const char *where)
{
+ bool vert_from_glsl_shader = false;
+ bool geom_from_glsl_shader = false;
+ bool frag_from_glsl_shader = false;
+
/* This depends on having up to date derived state (shaders) */
if (ctx->NewState)
_mesa_update_state(ctx);
if (ctx->Shader.CurrentProgram) {
+ unsigned i;
+
/* using shaders */
if (!ctx->Shader.CurrentProgram->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION,
}
}
#endif
- }
- else {
- if (ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(vertex program not valid)", where);
- return GL_FALSE;
- }
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(fragment program not valid)", where);
- return GL_FALSE;
+
+ /* Figure out which shader stages are provided by the GLSL program. For
+ * any stages that are not provided, the corresponding assembly shader
+ * target will be validated below.
+ */
+ for (i = 0; i < ctx->Shader.CurrentProgram->_NumLinkedShaders; i++) {
+ switch (ctx->Shader.CurrentProgram->_LinkedShaders[i]->Type) {
+ case GL_VERTEX_SHADER: vert_from_glsl_shader = true; break;
+ case GL_GEOMETRY_SHADER_ARB: geom_from_glsl_shader = true; break;
+ case GL_FRAGMENT_SHADER: frag_from_glsl_shader = true; break;
+ }
}
}
+
+ /* Any shader stages that are not supplied by the GLSL shader and have
+ * assembly shaders enabled must now be validated.
+ */
+ if (!vert_from_glsl_shader
+ && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(vertex program not valid)", where);
+ return GL_FALSE;
+ }
+
+ /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
+ * FINISHME: geometry program should validated here.
+ */
+
+ if (!frag_from_glsl_shader
+ && ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(fragment program not valid)", where);
+ return GL_FALSE;
+ }
+
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"%s(incomplete framebuffer)", where);