From 4df2931a87fe082f90871564a89a09c826641f5b Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Mon, 3 Apr 2017 16:38:18 +1000 Subject: [PATCH] mesa/vbo: move some Draw checks out of validation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit These checks do not generate any errors. Move them so we can add KHR_no_error support and still make sure we do these checks. Reviewed-by: Nicolai Hähnle --- src/mesa/main/api_validate.c | 43 +------------- src/mesa/vbo/vbo_exec_array.c | 106 ++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 41 deletions(-) diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index e23be60b2b4..bddde29878a 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -290,15 +290,6 @@ check_valid_to_render(struct gl_context *ctx, const char *function) "%s(tess ctrl shader is missing)", function); return false; } - - /* For ES2, we can draw if we have a vertex program/shader). */ - return ctx->VertexProgram._Current != NULL; - - case API_OPENGLES: - /* For OpenGL ES, only draw if we have vertex positions - */ - if (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled) - return false; break; case API_OPENGL_CORE: @@ -312,32 +303,10 @@ check_valid_to_render(struct gl_context *ctx, const char *function) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function); return false; } + break; - /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec - * says: - * - * "If there is no active program for the vertex or fragment shader - * stages, the results of vertex and/or fragment processing will be - * undefined. However, this is not an error." - * - * The fragment shader is not tested here because other state (e.g., - * GL_RASTERIZER_DISCARD) affects whether or not we actually care. - */ - return ctx->VertexProgram._Current != NULL; - + case API_OPENGLES: case API_OPENGL_COMPAT: - if (ctx->VertexProgram._Current != NULL) { - /* Draw regardless of whether or not we have any vertex arrays. - * (Ex: could draw a point using a constant vertex pos) - */ - return true; - } else { - /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic - * array [0]). - */ - return (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled || - ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); - } break; default: @@ -700,14 +669,6 @@ validate_DrawElements_common(struct gl_context *ctx, if (!check_valid_to_render(ctx, caller)) return false; - /* Not using a VBO for indices, so avoid NULL pointer derefs later. - */ - if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) - return false; - - if (count == 0) - return false; - return true; } diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index e5eeae44ece..ac27b49fcb5 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -179,6 +179,60 @@ check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) } +/** + * Check if we should skip the draw call even after validation was successful. + */ +static bool +skip_validated_draw(struct gl_context *ctx) +{ + switch (ctx->API) { + case API_OPENGLES2: + /* For ES2, we can draw if we have a vertex program/shader). */ + return ctx->VertexProgram._Current == NULL; + + case API_OPENGLES: + /* For OpenGL ES, only draw if we have vertex positions + */ + if (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled) + return false; + break; + + case API_OPENGL_CORE: + /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec + * says: + * + * "If there is no active program for the vertex or fragment shader + * stages, the results of vertex and/or fragment processing will be + * undefined. However, this is not an error." + * + * The fragment shader is not tested here because other state (e.g., + * GL_RASTERIZER_DISCARD) affects whether or not we actually care. + */ + return ctx->VertexProgram._Current == NULL; + + case API_OPENGL_COMPAT: + if (ctx->VertexProgram._Current != NULL) { + /* Draw regardless of whether or not we have any vertex arrays. + * (Ex: could draw a point using a constant vertex pos) + */ + return false; + } else { + /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic + * array [0]). + */ + return (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled && + !ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); + } + break; + + default: + unreachable("Invalid API value in check_valid_to_render()"); + } + + return false; +} + + /** * Print info/data for glDrawArrays(), for debugging. */ @@ -410,6 +464,9 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, struct vbo_context *vbo = vbo_context(ctx); struct _mesa_prim prim[2]; + if (skip_validated_draw(ctx)) + return; + vbo_bind_arrays(ctx); /* OpenGL 4.5 says that primitive restart is ignored with non-indexed @@ -739,6 +796,25 @@ dump_element_buffer(struct gl_context *ctx, GLenum type) #endif +static bool +skip_draw_elements(struct gl_context *ctx, GLsizei count, + const GLvoid *indices) +{ + if (count == 0) + return true; + + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) + return true; + + if (skip_validated_draw(ctx)) + return true; + + return false; +} + + /** * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. * Do the rendering for a glDrawElements or glDrawRangeElements call after @@ -757,6 +833,9 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, struct _mesa_index_buffer ib; struct _mesa_prim prim[1]; + if (skip_draw_elements(ctx, count, indices)) + return; + vbo_bind_arrays(ctx); ib.count = count; @@ -1230,6 +1309,9 @@ vbo_exec_MultiDrawElements(GLenum mode, primcount)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, NULL); } @@ -1248,6 +1330,9 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, primcount)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, basevertex); } @@ -1275,6 +1360,9 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, return; } + if (skip_validated_draw(ctx)) + return; + vbo_bind_arrays(ctx); /* init most fields to zero */ @@ -1482,6 +1570,9 @@ vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_drawarraysindirect(ctx, mode, indirect); } @@ -1499,6 +1590,9 @@ vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_drawelementsindirect(ctx, mode, type, indirect); } @@ -1521,6 +1615,9 @@ vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, primcount, stride)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_multidrawarraysindirect(ctx, mode, indirect, primcount, stride); } @@ -1546,6 +1643,9 @@ vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type, primcount, stride)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect, primcount, stride); } @@ -1634,6 +1734,9 @@ vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect, maxdrawcount, stride)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect, drawcount, maxdrawcount, stride); } @@ -1662,6 +1765,9 @@ vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type, maxdrawcount, stride)) return; + if (skip_validated_draw(ctx)) + return; + vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect, drawcount, maxdrawcount, stride); -- 2.30.2