Better caching for texenv programs.
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 22 May 2006 14:17:32 +0000 (14:17 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Mon, 22 May 2006 14:17:32 +0000 (14:17 +0000)
Initialize some values correctly.

src/mesa/main/mtypes.h
src/mesa/main/texenvprogram.c
src/mesa/main/texenvprogram.h
src/mesa/main/texstate.c

index e52e0ba..1bafaf3 100644 (file)
@@ -1514,11 +1514,16 @@ struct gl_texture_unit
    GLboolean ColorTableEnabled;
 };
 
-struct texenvprog_cache {
+struct texenvprog_cache_item {
    GLuint hash;
    void *key;
    void *data;
-   struct texenvprog_cache *next;
+   struct texenvprog_cache_item *next;
+};
+
+struct texenvprog_cache {
+   struct texenvprog_cache_item **items;
+   GLuint size, n_items;
 };
 
 /**
@@ -1551,7 +1556,7 @@ struct gl_texture_attrib
    struct gl_color_table Palette;
    
    /** Cached texenv fragment programs */
-   struct texenvprog_cache *env_fp_cache;
+   struct texenvprog_cache env_fp_cache;
 };
 
 
index 520ea02..63c93c9 100644 (file)
@@ -1023,6 +1023,10 @@ create_new_program(struct state_key *key, GLcontext *ctx,
       p.src_texture[unit] = undef;
 
    p.src_previous = undef;
+   p.half = undef;
+   p.zero = undef;
+   p.one = undef;
+
    p.last_tex_stage = 0;
    release_temps(&p);
 
@@ -1106,27 +1110,53 @@ static void *search_cache( struct texenvprog_cache *cache,
                           const void *key,
                           GLuint keysize)
 {
-   struct texenvprog_cache *c;
+   struct texenvprog_cache_item *c;
 
-   for (c = cache; c; c = c->next) {
-      if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0)
+   for (c = cache->items[hash % cache->size]; c; c = c->next) {
+      if (c->hash == hash && memcmp(c->key, key, keysize) == 0)
         return c->data;
    }
 
    return NULL;
 }
 
-static void cache_item( struct texenvprog_cache **cache,
+static void rehash( struct texenvprog_cache *cache )
+{
+   struct texenvprog_cache_item **items;
+   struct texenvprog_cache_item *c, *next;
+   GLuint size, i;
+
+   size = cache->size * 3;
+   items = (struct texenvprog_cache_item**) _mesa_malloc(size * sizeof(*items));
+   _mesa_memset(items, 0, size * sizeof(*items));
+
+   for (i = 0; i < cache->size; i++)
+      for (c = cache->items[i]; c; c = next) {
+        next = c->next;
+        c->next = items[c->hash % size];
+        items[c->hash % size] = c;
+      }
+
+   _mesa_free(cache->items);
+   cache->items = items;
+   cache->size = size;
+}
+
+static void cache_item( struct texenvprog_cache *cache,
                        GLuint hash,
                        void *key,
                        void *data )
 {
-   struct texenvprog_cache *c = CALLOC_STRUCT(texenvprog_cache);
+   struct texenvprog_cache_item *c = MALLOC(sizeof(*c));
    c->hash = hash;
    c->key = key;
    c->data = data;
-   c->next = *cache;
-   *cache = c;
+
+   if (++cache->n_items > cache->size * 1.5)
+      rehash(cache);
+
+   c->next = cache->items[hash % cache->size];
+   cache->items[hash % cache->size] = c;
 }
 
 static GLuint hash_key( struct state_key *key )
@@ -1154,7 +1184,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
       
       ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
         (struct fragment_program *)
-        search_cache(ctx->Texture.env_fp_cache, hash, key, sizeof(*key));
+        search_cache(&ctx->Texture.env_fp_cache, hash, key, sizeof(*key));
        
       if (!ctx->_TexEnvProgram) {
         if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
@@ -1184,14 +1214,29 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
    }
 }
 
+
+void _mesa_TexEnvProgramCacheInit( GLcontext *ctx )
+{
+   ctx->Texture.env_fp_cache.size = 17;
+   ctx->Texture.env_fp_cache.n_items = 0;
+   ctx->Texture.env_fp_cache.items = (struct texenvprog_cache_item **)
+      _mesa_calloc(ctx->Texture.env_fp_cache.size * 
+                  sizeof(struct texenvprog_cache_item));
+}
+
+
 void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
 {
-   struct texenvprog_cache *a, *tmp;
+   struct texenvprog_cache_item *c, *next;
+   GLuint i;
 
-   for (a = ctx->Texture.env_fp_cache; a; a = tmp) {
-      tmp = a->next;
-      _mesa_free(a->key);
-      ctx->Driver.DeleteProgram(ctx, (struct program *) a->data);
-      _mesa_free(a);
-   }
+   for (i = 0; i < ctx->Texture.env_fp_cache.size; i++)
+      for (c = ctx->Texture.env_fp_cache.items[i]; c; c = next) {
+        next = c->next;
+        _mesa_free(c->key);
+        _mesa_free(c->data);
+        _mesa_free(c);
+      }
+
+   _mesa_free(ctx->Texture.env_fp_cache.items);
 }
index 30c8cca..6f01776 100644 (file)
@@ -35,6 +35,7 @@
 #include "mtypes.h"
 
 extern void _mesa_UpdateTexEnvProgram( GLcontext *ctx );
+extern void _mesa_TexEnvProgramCacheInit( GLcontext *ctx );
 extern void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx );
 
 #endif
index 7e762ed..ea3873c 100644 (file)
@@ -3198,6 +3198,8 @@ _mesa_init_texture(GLcontext *ctx)
    ctx->Texture.SharedPalette = GL_FALSE;
    _mesa_init_colortable(&ctx->Texture.Palette);
 
+   _mesa_TexEnvProgramCacheInit( ctx );
+
    /* Allocate proxy textures */
    if (!alloc_proxy_textures( ctx ))
       return GL_FALSE;