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