mesa: Track maximum CurrentTexUnit to reduce glDeleteTextures() overhead.
authorEric Anholt <eric@anholt.net>
Fri, 25 Apr 2014 22:57:21 +0000 (15:57 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 30 Apr 2014 21:33:21 +0000 (14:33 -0700)
No more walking 96*6 pointers looking to see if they're the current
texture, when we only use the first 2 out of 96 units.  -6.26002% +/-
1.87817% effect on cairo runtime on no-fbo-cache glamor (n=36).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/main/mtypes.h
src/mesa/main/texobj.c
src/mesa/main/texstate.c

index 4c2ad908794b9abc3d5c1a117c596739c86ba176..5fbfffe98e0fe6abc7efab925970d4fa4a89b09a 100644 (file)
@@ -1401,6 +1401,9 @@ struct gl_texture_attrib
 
    /** Largest index of a texture unit with _Current != NULL. */
    GLint _MaxEnabledTexImageUnit;
+
+   /** Largest index + 1 of texture units that have had any CurrentTex set. */
+   GLint NumCurrentTexUsed;
 };
 
 
index 918dd59edaa8ff6593f4762e668b46d0b3f86e11..85246c8ab005f7e413f85afb59d3ac5cfa06b163 100644 (file)
@@ -1094,7 +1094,7 @@ unbind_texobj_from_texunits(struct gl_context *ctx,
 {
    GLuint u, tex;
 
-   for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
+   for (u = 0; u < ctx->Texture.NumCurrentTexUsed; u++) {
       struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
       for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
          if (texObj == unit->CurrentTex[tex]) {
@@ -1353,6 +1353,8 @@ _mesa_BindTexture( GLenum target, GLuint texName )
     * count hits zero.
     */
    _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
+   ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed,
+                                         ctx->Texture.CurrentUnit + 1);
    ASSERT(texUnit->CurrentTex[targetIndex]);
 
    /* Pass BindTexture call to device driver */
index 3a7e2273f90d70a3dab256cf7862140458b61285..000af94c6ed57f511478c4de8538aca11d210714 100644 (file)
@@ -108,6 +108,10 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
             _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
                                    src->Texture.Unit[u].CurrentTex[tex]);
+            if (src->Texture.Unit[u].CurrentTex[tex]) {
+               dst->Texture.NumCurrentTexUsed =
+                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
+            }
          }
          _mesa_unlock_context_textures(dst);
       }
@@ -912,6 +916,8 @@ _mesa_init_texture(struct gl_context *ctx)
    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
                                  ctx->Shared->NullBufferObj);
 
+   ctx->Texture.NumCurrentTexUsed = 0;
+
    return GL_TRUE;
 }