summaryrefslogtreecommitdiffstats
path: root/src/mesa/program/prog_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/program/prog_cache.c')
-rw-r--r--src/mesa/program/prog_cache.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/src/mesa/program/prog_cache.c b/src/mesa/program/prog_cache.c
index 56ca59890de..2ccedb5d7d0 100644
--- a/src/mesa/program/prog_cache.c
+++ b/src/mesa/program/prog_cache.c
@@ -29,6 +29,7 @@
#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/imports.h"
+#include "main/shaderobj.h"
#include "program/prog_cache.h"
#include "program/program.h"
@@ -104,7 +105,8 @@ rehash(struct gl_program_cache *cache)
static void
-clear_cache(struct gl_context *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 +117,13 @@ clear_cache(struct gl_context *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;
@@ -147,7 +155,16 @@ _mesa_new_program_cache(void)
void
_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);
}
@@ -197,7 +214,35 @@ _mesa_program_cache_insert(struct gl_context *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->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++;