mesa: precompute all valid primitive types at context creation

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 <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 07:58:17 -05:00 committed by Marge Bot
parent fc78429523
commit f6913fb366
4 changed files with 47 additions and 36 deletions

View File

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

View File

@ -27,8 +27,7 @@
#ifndef API_VALIDATE_H
#define API_VALIDATE_H
#include <stdbool.h>
#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

View File

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

View File

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