From b5c0706d470d03c3f155c515e406857fef60ff61 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 11 Dec 2022 23:47:29 -0500 Subject: [PATCH] mesa: optimize _mesa_bytes_per_vertex_attrib using a hash-based translation This reduces time spent in gl*Pointer for viewperf. Generated by find_hash_func.c. Reviewed-by: Rob Clark Part-of: --- src/mesa/main/glformats.c | 49 ----------------------------------------------- src/mesa/main/glformats.h | 3 --- src/mesa/main/varray.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/varray.h | 34 ++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 52 deletions(-) diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c index 068c018..06c68b4 100644 --- a/src/mesa/main/glformats.c +++ b/src/mesa/main/glformats.c @@ -522,55 +522,6 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) /** - * Get the number of bytes for a vertex attrib with the given number of - * components and type. - * - * \param comps number of components. - * \param type data type. - * - * \return bytes per attribute, or -1 if a bad comps/type combination was given. - */ -GLint -_mesa_bytes_per_vertex_attrib(GLint comps, GLenum type) -{ - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return comps * sizeof(GLubyte); - case GL_SHORT: - case GL_UNSIGNED_SHORT: - return comps * sizeof(GLshort); - case GL_INT: - case GL_UNSIGNED_INT: - return comps * sizeof(GLint); - case GL_FLOAT: - return comps * sizeof(GLfloat); - case GL_HALF_FLOAT_ARB: - case GL_HALF_FLOAT_OES: - return comps * sizeof(GLhalfARB); - case GL_DOUBLE: - return comps * sizeof(GLdouble); - case GL_FIXED: - return comps * sizeof(GLfixed); - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (comps == 4) - return sizeof(GLuint); - else - return -1; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - if (comps == 3) - return sizeof(GLuint); - else - return -1; - case GL_UNSIGNED_INT64_ARB: - return comps * 8; - default: - return -1; - } -} - -/** * Test if the given format is unsized. */ GLboolean diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h index cfca451..a402a83 100644 --- a/src/mesa/main/glformats.h +++ b/src/mesa/main/glformats.h @@ -57,9 +57,6 @@ _mesa_components_in_format( GLenum format ); extern GLint _mesa_bytes_per_pixel( GLenum format, GLenum type ); -extern GLint -_mesa_bytes_per_vertex_attrib(GLint comps, GLenum type); - extern GLboolean _mesa_is_astc_format(GLenum internalFormat); diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 72a71db..4bb289d 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -47,6 +47,52 @@ #include "state_tracker/st_atom.h" #include "state_tracker/st_util.h" +/* The values are multiplied by the component count to get the attrib size. + * Indexed by PERF_HASH_GL_TYPE(GLenum). + * Generated by src/util/tools/find_hash_func.c. + */ +const uint8_t _mesa_vertex_type_bytes[16] = { + /* These elements are listed out of order. */ + [/* 7*/ PERF_HASH_GL_VERTEX_TYPE(GL_BYTE)] = 1, + [/* 8*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_BYTE)] = 1, + [/* 5*/ PERF_HASH_GL_VERTEX_TYPE(GL_INT_2_10_10_10_REV)] = 1, /* count is 4 */ + [/* 0*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV)] = 1, /* count is 4 */ + [/* 9*/ PERF_HASH_GL_VERTEX_TYPE(GL_SHORT)] = 2, + [/*10*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_SHORT)] = 2, + [/* 2*/ PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_ARB)] = 2, + [/* 4*/ PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_OES)] = 2, + [/*11*/ PERF_HASH_GL_VERTEX_TYPE(GL_INT)] = 4, + [/*12*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT)] = 4, + [/*13*/ PERF_HASH_GL_VERTEX_TYPE(GL_FLOAT)] = 4, + [/* 3*/ PERF_HASH_GL_VERTEX_TYPE(GL_FIXED)] = 4, + [/* 1*/ PERF_HASH_GL_VERTEX_TYPE(GL_DOUBLE)] = 8, + [/* 6*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT64_ARB)] = 8, +}; + +static inline void +compile_check_uniqueness_of_gl_vertex_type(unsigned x) +{ + /* This switch has the same purpose as static_assert. + * It should fail compilation if any case is not unique. + */ + switch (x) { + case PERF_HASH_GL_VERTEX_TYPE(GL_BYTE): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_BYTE): + case PERF_HASH_GL_VERTEX_TYPE(GL_INT_2_10_10_10_REV): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV): + case PERF_HASH_GL_VERTEX_TYPE(GL_SHORT): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_SHORT): + case PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_ARB): + case PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_OES): + case PERF_HASH_GL_VERTEX_TYPE(GL_INT): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT): + case PERF_HASH_GL_VERTEX_TYPE(GL_FLOAT): + case PERF_HASH_GL_VERTEX_TYPE(GL_FIXED): + case PERF_HASH_GL_VERTEX_TYPE(GL_DOUBLE): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT64_ARB): + break; + } +} /** Used to do error checking for GL_EXT_vertex_array_bgra */ #define BGRA_OR_4 5 diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index 8c61070..07cfa23 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -175,4 +175,38 @@ _mesa_update_edgeflag_state_explicit(struct gl_context *ctx, void _mesa_update_edgeflag_state_vao(struct gl_context *ctx); + +/** + * Get the number of bytes for a vertex attrib with the given number of + * components and type. + * + * Note that this function will return some number between 0 and + * "8 * comps" if the type is invalid. It's assumed that error checking + * was done before this, or was skipped intentionally by mesa_no_error. + * + * \param comps number of components. + * \param type data type. + */ +static inline int +_mesa_bytes_per_vertex_attrib(int comps, GLenum type) +{ + /* This has comps = 3, but should return 4, so it's difficult to + * incorporate it into the "bytes * comps" formula below. + */ + if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) + return 4; + + /* This is a perfect hash for the specific set of GLenums that is valid + * here. It injectively maps a small set of GLenums into smaller numbers + * that can be used for indexing into small translation tables. It has + * hash collisions with enums that are invalid here. + */ + #define PERF_HASH_GL_VERTEX_TYPE(x) ((((x) * 17175) >> 14) & 0xf) + + extern const uint8_t _mesa_vertex_type_bytes[16]; + + assert(PERF_HASH_GL_VERTEX_TYPE(type) < ARRAY_SIZE(_mesa_vertex_type_bytes)); + return _mesa_vertex_type_bytes[PERF_HASH_GL_VERTEX_TYPE(type)] * comps; +} + #endif -- 2.7.4