diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 2d1b14b0b88..b668fb762df 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -47,6 +47,7 @@ #include "context.h" #include "bufferobj.h" #include "arrayobj.h" +#include "draw_validate.h" #include "macros.h" #include "mtypes.h" #include "state.h" @@ -1010,6 +1011,13 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, bool no_error) _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0); _mesa_reference_vao(ctx, &ctx->Array.VAO, newObj); + + /* Update the valid-to-render state if binding on unbinding default VAO + * if drawing with the default VAO is invalid. + */ + if (ctx->API == API_OPENGL_CORE && + (oldObj == ctx->Array.DefaultVAO) != (newObj == ctx->Array.DefaultVAO)) + _mesa_update_valid_to_render_state(ctx); } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index c90a9d07561..29653bd19a6 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -93,6 +93,7 @@ #include "debug_output.h" #include "depth.h" #include "dlist.h" +#include "draw_validate.h" #include "eval.h" #include "extensions.h" #include "fbobject.h" @@ -1745,6 +1746,7 @@ _mesa_make_current( struct gl_context *newCtx, */ _mesa_update_draw_buffers(newCtx); _mesa_update_allow_draw_out_of_order(newCtx); + _mesa_update_valid_to_render_state(newCtx); } if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); diff --git a/src/mesa/main/draw_validate.c b/src/mesa/main/draw_validate.c index 7a72508eefa..022385a8f97 100644 --- a/src/mesa/main/draw_validate.c +++ b/src/mesa/main/draw_validate.c @@ -266,89 +266,6 @@ check_valid_to_render(struct gl_context *ctx, bool uses_vao, return false; } - /* Section 11.2 (Tessellation) of the ES 3.2 spec says: - * - * "An INVALID_OPERATION error is generated by any command that - * transfers vertices to the GL if the current program state has - * one but not both of a tessellation control shader and tessellation - * evaluation shader." - * - * The OpenGL spec argues that this is allowed because a tess ctrl shader - * without a tess eval shader can be used with transform feedback. - * However, glBeginTransformFeedback doesn't allow GL_PATCHES and - * therefore doesn't allow tessellation. - * - * Further investigation showed that this is indeed a spec bug and - * a tess ctrl shader without a tess eval shader shouldn't have been - * allowed, because there is no API in GL 4.0 that can make use this - * to produce something useful. - * - * Also, all vendors except one don't support a tess ctrl shader without - * a tess eval shader anyway. - */ - if (ctx->TessCtrlProgram._Current && !ctx->TessEvalProgram._Current) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(tess eval shader is missing)", function); - return false; - } - - switch (ctx->API) { - case API_OPENGLES2: - /* Section 11.2 (Tessellation) of the ES 3.2 spec says: - * - * "An INVALID_OPERATION error is generated by any command that - * transfers vertices to the GL if the current program state has - * one but not both of a tessellation control shader and tessellation - * evaluation shader." - */ - if (_mesa_is_gles3(ctx) && - ctx->TessEvalProgram._Current && !ctx->TessCtrlProgram._Current) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(tess ctrl shader is missing)", function); - return false; - } - - /* From GL_EXT_color_buffer_float: - * - * "Blending applies only if the color buffer has a fixed-point or - * or floating-point format. If the color buffer has an integer - * format, proceed to the next operation. Furthermore, an - * INVALID_OPERATION error is generated by DrawArrays and the other - * drawing commands defined in section 2.8.3 (10.5 in ES 3.1) if - * blending is enabled (see below) and any draw buffer has 32-bit - * floating-point format components." - * - * However GL_EXT_float_blend removes this text. - */ - if (!ctx->Extensions.EXT_float_blend && - (ctx->DrawBuffer->_FP32Buffers & ctx->Color.BlendEnabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(32-bit float output + blending)", function); - return false; - } - break; - - case API_OPENGL_CORE: - /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5 - * Core Profile spec says: - * - * "An INVALID_OPERATION error is generated if no vertex array - * object is bound (see section 10.3.1)." - */ - if (ctx->Array.VAO == ctx->Array.DefaultVAO) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function); - return false; - } - break; - - case API_OPENGLES: - case API_OPENGL_COMPAT: - break; - - default: - unreachable("Invalid API value in check_valid_to_render()"); - } - return true; } @@ -375,6 +292,80 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx) /* Start with an empty mask and set this to the trimmed mask at the end. */ ctx->ValidPrimMask = 0; + /* Section 11.2 (Tessellation) of the ES 3.2 spec says: + * + * "An INVALID_OPERATION error is generated by any command that + * transfers vertices to the GL if the current program state has + * one but not both of a tessellation control shader and tessellation + * evaluation shader." + * + * The OpenGL spec argues that this is allowed because a tess ctrl shader + * without a tess eval shader can be used with transform feedback. + * However, glBeginTransformFeedback doesn't allow GL_PATCHES and + * therefore doesn't allow tessellation. + * + * Further investigation showed that this is indeed a spec bug and + * a tess ctrl shader without a tess eval shader shouldn't have been + * allowed, because there is no API in GL 4.0 that can make use this + * to produce something useful. + * + * Also, all vendors except one don't support a tess ctrl shader without + * a tess eval shader anyway. + */ + if (shader->CurrentProgram[MESA_SHADER_TESS_CTRL] && + !shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) + return; + + switch (ctx->API) { + case API_OPENGLES2: + /* Section 11.2 (Tessellation) of the ES 3.2 spec says: + * + * "An INVALID_OPERATION error is generated by any command that + * transfers vertices to the GL if the current program state has + * one but not both of a tessellation control shader and tessellation + * evaluation shader." + */ + if (_mesa_is_gles3(ctx) && + shader->CurrentProgram[MESA_SHADER_TESS_EVAL] && + !shader->CurrentProgram[MESA_SHADER_TESS_CTRL]) + return; + + /* From GL_EXT_color_buffer_float: + * + * "Blending applies only if the color buffer has a fixed-point or + * or floating-point format. If the color buffer has an integer + * format, proceed to the next operation. Furthermore, an + * INVALID_OPERATION error is generated by DrawArrays and the other + * drawing commands defined in section 2.8.3 (10.5 in ES 3.1) if + * blending is enabled (see below) and any draw buffer has 32-bit + * floating-point format components." + * + * However GL_EXT_float_blend removes this text. + */ + if (!ctx->Extensions.EXT_float_blend && + (ctx->DrawBuffer->_FP32Buffers & ctx->Color.BlendEnabled)) + return; + break; + + case API_OPENGL_CORE: + /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5 + * Core Profile spec says: + * + * "An INVALID_OPERATION error is generated if no vertex array + * object is bound (see section 10.3.1)." + */ + if (ctx->Array.VAO == ctx->Array.DefaultVAO) + return; + break; + + case API_OPENGLES: + case API_OPENGL_COMPAT: + break; + + default: + unreachable("Invalid API value in _mesa_update_valid_to_render_state"); + } + /* From GL_INTEL_conservative_rasterization spec: * * The conservative rasterization option applies only to polygons with diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index fa0c86acd2c..04831dd5125 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -440,6 +440,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) ctx->PopAttribState |= GL_ENABLE_BIT; ctx->Color.BlendEnabled = newEnabled; _mesa_update_allow_draw_out_of_order(ctx); + _mesa_update_valid_to_render_state(ctx); } } break; @@ -1403,6 +1404,7 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap, ctx->PopAttribState |= GL_ENABLE_BIT; ctx->Color.BlendEnabled = enabled; _mesa_update_allow_draw_out_of_order(ctx); + _mesa_update_valid_to_render_state(ctx); } break; case GL_SCISSOR_TEST: diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index a1a084d1f77..1fb76e52f22 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -36,6 +36,7 @@ #include "buffers.h" #include "context.h" #include "debug_output.h" +#include "draw_validate.h" #include "enums.h" #include "fbobject.h" #include "formats.h" @@ -3137,6 +3138,7 @@ _mesa_bind_framebuffers(struct gl_context *ctx, _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb); _mesa_update_allow_draw_out_of_order(ctx); + _mesa_update_valid_to_render_state(ctx); } if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) { diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 5311d117673..a50d0febe7e 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -35,6 +35,7 @@ #include "blend.h" #include "buffers.h" #include "context.h" +#include "draw_validate.h" #include "enums.h" #include "formats.h" #include "macros.h" @@ -504,6 +505,7 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, compute_depth_max(fb); _mesa_update_allow_draw_out_of_order(ctx); + _mesa_update_valid_to_render_state(ctx); }