diff options
Diffstat (limited to 'src/mesa/main/context.c')
-rw-r--r-- | src/mesa/main/context.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 00132514d77..284c8b1d37b 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -137,7 +137,7 @@ #endif #include "glsl_parser_extras.h" - +#include <stdbool.h> #ifndef MESA_VERBOSE @@ -1699,11 +1699,17 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx, 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, @@ -1720,20 +1726,42 @@ _mesa_valid_to_render(GLcontext *ctx, const char *where) } } #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); |