mesa: fold most of check_valid_to_render into _mesa_update_valid_to_render_state

Set the mask (ValidPrimMask) to 0 if draw calls should generate
GL_INVALID_OPERATION. The mask is updated when states are changed.

Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8798>
This commit is contained in:
Marek Olšák 2021-01-16 11:30:44 -05:00 committed by Marge Bot
parent 12ecbd6bf8
commit dfd1080f9d
6 changed files with 90 additions and 83 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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) {

View File

@ -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);
}