diff options
-rw-r--r-- | src/mesa/main/mtypes.h | 11 | ||||
-rw-r--r-- | src/mesa/main/texenvprogram.c | 75 | ||||
-rw-r--r-- | src/mesa/main/texenvprogram.h | 1 | ||||
-rw-r--r-- | src/mesa/main/texstate.c | 2 |
4 files changed, 71 insertions, 18 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index e52e0bae5e5..1bafaf3485f 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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; }; diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 520ea02b61c..63c93c96fcd 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -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); } diff --git a/src/mesa/main/texenvprogram.h b/src/mesa/main/texenvprogram.h index 30c8cca3889..6f017767c82 100644 --- a/src/mesa/main/texenvprogram.h +++ b/src/mesa/main/texenvprogram.h @@ -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 diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 7e762edd256..ea3873c3804 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -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; |