From f6913fb366ae52523a1236025575c3d6ccecba1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 16 Jan 2021 07:58:17 -0500 Subject: [PATCH] mesa: precompute all valid primitive types at context creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New variable gl_context::MaxValidPrimMask is set at context creation and determines the valid primitive types for that context. The Max prefix indicates that the mask doesn't mask out primitives disallowed by current states and shaders. Reviewed-by: Zoltán Böszörményi Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mesa/main/draw_validate.c | 31 ------------------------------- src/mesa/main/draw_validate.h | 19 ++++++++++++++----- src/mesa/main/mtypes.h | 7 +++++++ src/mesa/main/version.c | 26 ++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/mesa/main/draw_validate.c b/src/mesa/main/draw_validate.c index 84897bd5dbc..1e6df888f31 100644 --- a/src/mesa/main/draw_validate.c +++ b/src/mesa/main/draw_validate.c @@ -350,37 +350,6 @@ check_valid_to_render(struct gl_context *ctx, const char *function) return true; } - -/** - * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), - * etc? The set of legal values depends on whether geometry shaders/programs - * are supported. - * Note: This may be called during display list compilation. - */ -bool -_mesa_is_valid_prim_mode(const struct gl_context *ctx, GLenum mode) -{ - /* The overwhelmingly common case is (mode <= GL_TRIANGLE_FAN). Test that - * first and exit. You would think that a switch-statement would be the - * right approach, but at least GCC 4.7.2 generates some pretty dire code - * for the common case. - */ - if (likely(mode <= GL_TRIANGLE_FAN)) - return true; - - if (mode <= GL_POLYGON) - return (ctx->API == API_OPENGL_COMPAT); - - if (mode <= GL_TRIANGLE_STRIP_ADJACENCY) - return _mesa_has_geometry_shaders(ctx); - - if (mode == GL_PATCHES) - return _mesa_has_tessellation(ctx); - - return false; -} - - /** * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), * etc? Also, do additional checking related to transformation feedback. diff --git a/src/mesa/main/draw_validate.h b/src/mesa/main/draw_validate.h index d015c7e830e..1fcf0a40089 100644 --- a/src/mesa/main/draw_validate.h +++ b/src/mesa/main/draw_validate.h @@ -27,8 +27,7 @@ #ifndef API_VALIDATE_H #define API_VALIDATE_H -#include -#include "glheader.h" +#include "mtypes.h" struct gl_buffer_object; struct gl_context; @@ -38,9 +37,6 @@ struct gl_transform_feedback_object; extern GLboolean _mesa_valid_to_render(struct gl_context *ctx, const char *where); -extern bool -_mesa_is_valid_prim_mode(const struct gl_context *ctx, GLenum mode); - extern GLboolean _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name); @@ -131,4 +127,17 @@ _mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx, GLsizei maxdrawcount, GLsizei stride); +/** + * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), + * etc? The set of legal values depends on whether geometry shaders/programs + * are supported. + * Note: This may be called during display list compilation. + */ +static inline bool +_mesa_is_valid_prim_mode(const struct gl_context *ctx, GLenum mode) +{ + /* All primitive types are less than 32, which allows us to use a mask. */ + return mode < 32 && (1u << mode) & ctx->SupportedPrimMask; +} + #endif diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index e862649fcdf..1301bfb2c83 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -5220,6 +5220,13 @@ struct gl_context /** Core/Driver constants */ struct gl_constants Const; + /** + * Bitmask of valid primitive types supported by this context type, + * GL version, and extensions, not taking current states into account. + * Current states can further reduce the final bitmask at draw time. + */ + GLbitfield SupportedPrimMask; + /** \name The various 4x4 matrix stacks */ /*@{*/ struct gl_matrix_stack ModelviewMatrixStack; diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c index 45eaa3552c3..95113c76924 100644 --- a/src/mesa/main/version.c +++ b/src/mesa/main/version.c @@ -676,6 +676,32 @@ _mesa_compute_version(struct gl_context *ctx) done: if (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 31) ctx->Extensions.ARB_compatibility = GL_TRUE; + + /* Precompute valid primitive types for faster draw time validation. */ + /* All primitive type enums are less than 32, so we can use the shift. */ + ctx->SupportedPrimMask = (1 << GL_POINTS) | + (1 << GL_LINES) | + (1 << GL_LINE_LOOP) | + (1 << GL_LINE_STRIP) | + (1 << GL_TRIANGLES) | + (1 << GL_TRIANGLE_STRIP) | + (1 << GL_TRIANGLE_FAN); + + if (ctx->API == API_OPENGL_COMPAT) { + ctx->SupportedPrimMask |= (1 << GL_QUADS) | + (1 << GL_QUAD_STRIP) | + (1 << GL_POLYGON); + } + + if (_mesa_has_geometry_shaders(ctx)) { + ctx->SupportedPrimMask |= (1 << GL_LINES_ADJACENCY) | + (1 << GL_LINE_STRIP_ADJACENCY) | + (1 << GL_TRIANGLES_ADJACENCY) | + (1 << GL_TRIANGLE_STRIP_ADJACENCY); + } + + if (_mesa_has_tessellation(ctx)) + ctx->SupportedPrimMask |= 1 << GL_PATCHES; }