X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fprogram%2Fprog_cache.c;h=33f74cd7ab2d6424e2dba345ce6371567eed73d9;hb=e5339fe4a47c242693962c9f90bbab8b74935cba;hp=8af689754bbd85730b5e3cd7cf0ce00c3925a0fa;hpb=1218430e1200a08cd64b6555d3fd1fd0274ad9e5;p=mesa.git diff --git a/src/mesa/program/prog_cache.c b/src/mesa/program/prog_cache.c index 8af689754bb..33f74cd7ab2 100644 --- a/src/mesa/program/prog_cache.c +++ b/src/mesa/program/prog_cache.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2003 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,7 +28,8 @@ #include "main/glheader.h" #include "main/mtypes.h" -#include "main/imports.h" +#include "util/imports.h" +#include "main/shaderobj.h" #include "program/prog_cache.h" #include "program/program.h" @@ -36,6 +37,7 @@ struct cache_item { GLuint hash; + unsigned keysize; void *key; struct gl_program *program; struct cache_item *next; @@ -75,7 +77,7 @@ hash_key(const void *key, GLuint key_size) /** - * Rebuild/expand the hash table to accomodate more entries + * Rebuild/expand the hash table to accommodate more entries */ static void rehash(struct gl_program_cache *cache) @@ -87,7 +89,7 @@ rehash(struct gl_program_cache *cache) cache->last = NULL; size = cache->size * 3; - items = (struct cache_item**) malloc(size * sizeof(*items)); + items = malloc(size * sizeof(*items)); memset(items, 0, size * sizeof(*items)); for (i = 0; i < cache->size; i++) @@ -104,7 +106,8 @@ rehash(struct gl_program_cache *cache) static void -clear_cache(GLcontext *ctx, struct gl_program_cache *cache) +clear_cache(struct gl_context *ctx, struct gl_program_cache *cache, + GLboolean shader) { struct cache_item *c, *next; GLuint i; @@ -115,7 +118,13 @@ clear_cache(GLcontext *ctx, struct gl_program_cache *cache) for (c = cache->items[i]; c; c = next) { next = c->next; free(c->key); - _mesa_reference_program(ctx, &c->program, NULL); + if (shader) { + _mesa_reference_shader_program(ctx, + (struct gl_shader_program **)&c->program, + NULL); + } else { + _mesa_reference_program(ctx, &c->program, NULL); + } free(c); } cache->items[i] = NULL; @@ -133,8 +142,8 @@ _mesa_new_program_cache(void) struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache); if (cache) { cache->size = 17; - cache->items = (struct cache_item **) - calloc(1, cache->size * sizeof(struct cache_item)); + cache->items = + calloc(cache->size, sizeof(struct cache_item *)); if (!cache->items) { free(cache); return NULL; @@ -145,9 +154,18 @@ _mesa_new_program_cache(void) void -_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache) +_mesa_delete_program_cache(struct gl_context *ctx, struct gl_program_cache *cache) { - clear_cache(ctx, cache); + clear_cache(ctx, cache, GL_FALSE); + free(cache->items); + free(cache); +} + +void +_mesa_delete_shader_cache(struct gl_context *ctx, + struct gl_program_cache *cache) +{ + clear_cache(ctx, cache, GL_TRUE); free(cache->items); free(cache); } @@ -157,7 +175,8 @@ struct gl_program * _mesa_search_program_cache(struct gl_program_cache *cache, const void *key, GLuint keysize) { - if (cache->last && + if (cache->last && + cache->last->keysize == keysize && memcmp(cache->last->key, key, keysize) == 0) { return cache->last->program; } @@ -166,7 +185,10 @@ _mesa_search_program_cache(struct gl_program_cache *cache, struct cache_item *c; for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->hash == hash && memcmp(c->key, key, keysize) == 0) { + if (c->hash == hash && + c->keysize == keysize && + memcmp(c->key, key, keysize) == 0) { + cache->last = c; return c->program; } @@ -178,7 +200,7 @@ _mesa_search_program_cache(struct gl_program_cache *cache, void -_mesa_program_cache_insert(GLcontext *ctx, +_mesa_program_cache_insert(struct gl_context *ctx, struct gl_program_cache *cache, const void *key, GLuint keysize, struct gl_program *program) @@ -190,6 +212,7 @@ _mesa_program_cache_insert(GLcontext *ctx, c->key = malloc(keysize); memcpy(c->key, key, keysize); + c->keysize = keysize; c->program = program; /* no refcount change */ @@ -197,7 +220,36 @@ _mesa_program_cache_insert(GLcontext *ctx, if (cache->size < 1000) rehash(cache); else - clear_cache(ctx, cache); + clear_cache(ctx, cache, GL_FALSE); + } + + cache->n_items++; + c->next = cache->items[hash % cache->size]; + cache->items[hash % cache->size] = c; +} + +void +_mesa_shader_cache_insert(struct gl_context *ctx, + struct gl_program_cache *cache, + const void *key, GLuint keysize, + struct gl_shader_program *program) +{ + const GLuint hash = hash_key(key, keysize); + struct cache_item *c = CALLOC_STRUCT(cache_item); + + c->hash = hash; + + c->key = malloc(keysize); + memcpy(c->key, key, keysize); + c->keysize = keysize; + + c->program = (struct gl_program *)program; /* no refcount change */ + + if (cache->n_items > cache->size * 1.5) { + if (cache->size < 1000) + rehash(cache); + else + clear_cache(ctx, cache, GL_TRUE); } cache->n_items++;