summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.c88
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.h14
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_hash.h1
-rw-r--r--src/mesa/state_tracker/st_cache.c13
4 files changed, 114 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c
index 9c32e94124..9aa1a64272 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.c
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.c
@@ -190,9 +190,96 @@ struct cso_cache *cso_cache_create(void)
return sc;
}
+void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
+ void (*func)(void *state, void *user_data), void *user_data)
+{
+ struct cso_hash *hash = 0;
+ struct cso_hash_iter iter;
+
+ switch (type) {
+ case CSO_BLEND:
+ hash = sc->blend_hash;
+ break;
+ case CSO_SAMPLER:
+ hash = sc->sampler_hash;
+ break;
+ case CSO_DEPTH_STENCIL_ALPHA:
+ hash = sc->depth_stencil_hash;
+ break;
+ case CSO_RASTERIZER:
+ hash = sc->rasterizer_hash;
+ break;
+ case CSO_FRAGMENT_SHADER:
+ hash = sc->fs_hash;
+ break;
+ case CSO_VERTEX_SHADER:
+ hash = sc->vs_hash;
+ break;
+ }
+
+ iter = cso_hash_first_node(hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ void *state = cso_hash_iter_data(iter);
+ if (state) {
+ func(state, user_data);
+ }
+ iter = cso_hash_iter_next(iter);
+ }
+}
+
+static void delete_blend_state(void *state, void *user_data)
+{
+ struct cso_blend *cso = (struct cso_blend *)state;
+ if (cso->delete_state && cso->data != &cso->state)
+ cso->delete_state(cso->context, cso->data);
+}
+
+static void delete_depth_stencil_state(void *state, void *pipe)
+{
+ struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state;
+ if (cso->delete_state && cso->data != &cso->state)
+ cso->delete_state(cso->context, cso->data);
+}
+
+static void delete_sampler_state(void *state, void *pipe)
+{
+ struct cso_sampler *cso = (struct cso_sampler *)state;
+ if (cso->delete_state && cso->data != &cso->state)
+ cso->delete_state(cso->context, cso->data);
+}
+
+static void delete_rasterizer_state(void *state, void *pipe)
+{
+ struct cso_rasterizer *cso = (struct cso_rasterizer *)state;
+ if (cso->delete_state && cso->data != &cso->state)
+ cso->delete_state(cso->context, cso->data);
+}
+
+static void delete_fs_state(void *state, void *pipe)
+{
+ struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state;
+ if (cso->delete_state && cso->data != &cso->state)
+ cso->delete_state(cso->context, cso->data);
+}
+
+static void delete_vs_state(void *state, void *pipe)
+{
+ struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state;
+ if (cso->delete_state && cso->data != &cso->state)
+ cso->delete_state(cso->context, cso->data);
+}
+
void cso_cache_delete(struct cso_cache *sc)
{
assert(sc);
+ /* delete driver data */
+ cso_for_each_state(sc, CSO_BLEND, delete_blend_state, 0);
+ cso_for_each_state(sc, CSO_DEPTH_STENCIL_ALPHA, delete_depth_stencil_state, 0);
+ cso_for_each_state(sc, CSO_FRAGMENT_SHADER, delete_fs_state, 0);
+ cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0);
+ cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0);
+ cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0);
+
cso_hash_delete(sc->blend_hash);
cso_hash_delete(sc->sampler_hash);
cso_hash_delete(sc->depth_stencil_hash);
@@ -201,3 +288,4 @@ void cso_cache_delete(struct cso_cache *sc)
cso_hash_delete(sc->vs_hash);
FREE(sc);
}
+
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h
index 3a005a376e..f3bd4623c9 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.h
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.h
@@ -97,31 +97,43 @@ struct cso_cache {
struct cso_blend {
struct pipe_blend_state state;
void *data;
+ void (*delete_state)(void *, void *);
+ void *context;
};
struct cso_depth_stencil_alpha {
struct pipe_depth_stencil_alpha_state state;
void *data;
+ void (*delete_state)(void *, void *);
+ void *context;
};
struct cso_rasterizer {
struct pipe_rasterizer_state state;
void *data;
+ void (*delete_state)(void *, void *);
+ void *context;
};
struct cso_fragment_shader {
struct pipe_shader_state state;
void *data;
+ void (*delete_state)(void *, void *);
+ void *context;
};
struct cso_vertex_shader {
struct pipe_shader_state state;
void *data;
+ void (*delete_state)(void *, void *);
+ void *context;
};
struct cso_sampler {
struct pipe_sampler_state state;
void *data;
+ void (*delete_state)(void *, void *);
+ void *context;
};
@@ -147,6 +159,8 @@ struct cso_hash_iter cso_find_state(struct cso_cache *sc,
struct cso_hash_iter cso_find_state_template(struct cso_cache *sc,
unsigned hash_key, enum cso_cache_type type,
void *templ);
+void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
+ void (*func)(void *state, void *user_data), void *user_data);
void * cso_take_state(struct cso_cache *sc, unsigned hash_key,
enum cso_cache_type type);
diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h
index 2e8b69675c..86c62c027a 100644
--- a/src/gallium/auxiliary/cso_cache/cso_hash.h
+++ b/src/gallium/auxiliary/cso_cache/cso_hash.h
@@ -38,7 +38,6 @@
extern "C" {
#endif
-
struct cso_hash;
struct cso_node;
diff --git a/src/mesa/state_tracker/st_cache.c b/src/mesa/state_tracker/st_cache.c
index 2979e7fae5..78f282302e 100644
--- a/src/mesa/state_tracker/st_cache.c
+++ b/src/mesa/state_tracker/st_cache.c
@@ -63,6 +63,8 @@ const struct cso_blend * st_cached_blend_state(struct st_context *st,
cso->data = st->pipe->create_blend_state(st->pipe, &cso->state);
if (!cso->data)
cso->data = &cso->state;
+ cso->delete_state = st->pipe->delete_blend_state;
+ cso->context = st->pipe;
iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, cso);
}
return ((struct cso_blend *)cso_hash_iter_data(iter));
@@ -82,6 +84,8 @@ st_cached_sampler_state(struct st_context *st,
cso->data = st->pipe->create_sampler_state(st->pipe, &cso->state);
if (!cso->data)
cso->data = &cso->state;
+ cso->delete_state = st->pipe->delete_sampler_state;
+ cso->context = st->pipe;
iter = cso_insert_state(st->cache, hash_key, CSO_SAMPLER, cso);
}
return (struct cso_sampler*)(cso_hash_iter_data(iter));
@@ -103,6 +107,8 @@ st_cached_depth_stencil_alpha_state(struct st_context *st,
cso->data = st->pipe->create_depth_stencil_alpha_state(st->pipe, &cso->state);
if (!cso->data)
cso->data = &cso->state;
+ cso->delete_state = st->pipe->delete_depth_stencil_alpha_state;
+ cso->context = st->pipe;
iter = cso_insert_state(st->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso);
}
return (struct cso_depth_stencil_alpha*)(cso_hash_iter_data(iter));
@@ -123,6 +129,8 @@ const struct cso_rasterizer* st_cached_rasterizer_state(
cso->data = st->pipe->create_rasterizer_state(st->pipe, &cso->state);
if (!cso->data)
cso->data = &cso->state;
+ cso->delete_state = st->pipe->delete_rasterizer_state;
+ cso->context = st->pipe;
iter = cso_insert_state(st->cache, hash_key, CSO_RASTERIZER, cso);
}
return (struct cso_rasterizer*)(cso_hash_iter_data(iter));
@@ -143,6 +151,8 @@ st_cached_fs_state(struct st_context *st,
cso->data = st->pipe->create_fs_state(st->pipe, &cso->state);
if (!cso->data)
cso->data = &cso->state;
+ cso->delete_state = st->pipe->delete_fs_state;
+ cso->context = st->pipe;
iter = cso_insert_state(st->cache, hash_key, CSO_FRAGMENT_SHADER, cso);
}
return (struct cso_fragment_shader*)(cso_hash_iter_data(iter));
@@ -163,8 +173,9 @@ st_cached_vs_state(struct st_context *st,
cso->data = st->pipe->create_vs_state(st->pipe, &cso->state);
if (!cso->data)
cso->data = &cso->state;
+ cso->delete_state = st->pipe->delete_vs_state;
+ cso->context = st->pipe;
iter = cso_insert_state(st->cache, hash_key, CSO_VERTEX_SHADER, cso);
}
return (struct cso_vertex_shader*)(cso_hash_iter_data(iter));
}
-