From 81e6f6ef0cd51187d38421b90dee868cff5de33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 19 Dec 2020 19:55:59 -0500 Subject: [PATCH] mesa: don't push/pop default texture attributes redundantly Since default texture objects are bound in almost all texture units and all texture targets, we can skip saving and restoring their attributes if we just do that for default texture objects outside the loop saving all texture units. This reduces CPU time spent in glPushAttrib from 2.1% to 1.35% in one subtest of viewperf13/catia. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mesa/main/attrib.c | 31 +++++++++++++++++++++++++++++-- src/mesa/main/mtypes.h | 3 +++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 0229bb30689..c06695c6240 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -262,6 +262,19 @@ _mesa_PushAttrib(GLbitfield mask) memcpy(&head->Texture.FixedFuncUnit, &ctx->Texture.FixedFuncUnit, sizeof(ctx->Texture.FixedFuncUnit)); + /* Copy/save contents of default texture objects. They are almost + * always bound, so this can be done unconditionally. + * + * We save them separately, so that we don't have to save them in every + * texture unit where they are bound. This decreases CPU overhead. + */ + for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { + struct gl_texture_object *dst = &head->Texture.SavedDefaultObj[tex]; + struct gl_texture_object *src = ctx->Shared->DefaultTex[tex]; + + copy_texture_attribs(dst, src, tex); + } + /* copy state/contents of the currently bound texture objects */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { head->Texture.LodBias[u] = ctx->Texture.Unit[u].LodBias; @@ -272,7 +285,9 @@ _mesa_PushAttrib(GLbitfield mask) dst->Name = src->Name; - copy_texture_attribs(dst, src, tex); + /* Default texture targets are saved separately above. */ + if (src->Name != 0) + copy_texture_attribs(dst, src, tex); } } _mesa_unlock_context_textures(ctx); @@ -626,15 +641,27 @@ pop_texture_group(struct gl_context *ctx, struct gl_texture_attrib_node *texstat texObj = _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt]; } + /* Default texture object states are restored separately below. */ + if (texObj->Name == 0) + continue; + if (!copy_texture_attribs(texObj, savedObj, tgt)) continue; /* GL_ALL_ATTRIB_BITS means all pnames. (internal) */ - if (texObj->Name != 0 && ctx->Driver.TexParameter) + if (ctx->Driver.TexParameter) ctx->Driver.TexParameter(ctx, texObj, GL_ALL_ATTRIB_BITS); } } + /* Restore default texture object states. */ + for (gl_texture_index tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { + struct gl_texture_object *dst = ctx->Shared->DefaultTex[tex]; + const struct gl_texture_object *src = &texstate->SavedDefaultObj[tex]; + + copy_texture_attribs(dst, src, tex); + } + if (!ctx->Driver.TexEnv && !ctx->Driver.TexGen) { ctx->Texture._TexGenEnabled = texstate->_TexGenEnabled; ctx->Texture._GenFlags = texstate->_GenFlags; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2f04de3e79e..c88b31508ca 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -5053,6 +5053,9 @@ struct gl_texture_attrib_node struct gl_fixedfunc_texture_unit FixedFuncUnit[MAX_TEXTURE_COORD_UNITS]; GLfloat LodBias[MAX_TEXTURE_UNITS]; + /** Saved default texture object state. */ + struct gl_texture_object SavedDefaultObj[NUM_TEXTURE_TARGETS]; + /* For saving per texture object state (wrap modes, filters, etc), * SavedObj[][].Target is unused, so the value is invalid. */