implement cache limits for cso
authorZack Rusin <zack@tungstengraphics.com>
Tue, 26 Feb 2008 06:48:01 +0000 (01:48 -0500)
committerZack Rusin <zack@tungstengraphics.com>
Tue, 26 Feb 2008 06:51:46 +0000 (01:51 -0500)
by default set to 4096, which might be on the large side

src/gallium/auxiliary/cso_cache/cso_cache.c
src/gallium/auxiliary/cso_cache/cso_hash.c
src/gallium/auxiliary/cso_cache/cso_hash.h

index f31042bce1197b5fcf544a19e7851adcf0dd976c..a6e8469b44199d39e02813c99d71a7a6f8cef8f0 100644 (file)
@@ -127,12 +127,106 @@ static int _cso_size_for_type(enum cso_cache_type type)
    return 0;
 }
 
+
+static void delete_blend_state(void *state, void *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 *data)
+{
+   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 *data)
+{
+   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 *data)
+{
+   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 *data)
+{
+   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 *data)
+{
+   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);
+}
+
+
+static INLINE void delete_cso(void *state, enum cso_cache_type type)
+{
+   switch (type) {
+   case CSO_BLEND: {
+      delete_blend_state(state, 0);
+   }
+      break;
+   case CSO_SAMPLER: {
+      delete_sampler_state(state, 0);
+   }
+      break;
+   case CSO_DEPTH_STENCIL_ALPHA: {
+      delete_depth_stencil_state(state, 0);
+   }
+      break;
+   case CSO_RASTERIZER: {
+      delete_rasterizer_state(state, 0);
+   }
+      break;
+   case CSO_FRAGMENT_SHADER: {
+      delete_fs_state(state, 0);
+   }
+      break;
+   case CSO_VERTEX_SHADER: {
+      delete_vs_state(state, 0);
+   }
+      break;
+   }
+   free(state);
+}
+
+static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
+                                 int max_size)
+{
+   /* if we're approach the maximum size, remove fourth of the entries
+    * otherwise every subsequent call will go through the same */
+   int max_entries = (max_size > cso_hash_size(hash)) ? max_size : cso_hash_size(hash);
+   int to_remove =  (max_size < max_entries) * max_entries/4;
+   while (to_remove) {
+      /*remove elements until we're good */
+      /*fixme: currently we pick the nodes to remove at random*/
+      struct cso_hash_iter iter = cso_hash_first_node(hash);
+      void  *cso = cso_hash_take(hash, cso_hash_iter_key(iter));
+      delete_cso(cso, type);
+      --to_remove;
+   }
+}
+
 struct cso_hash_iter
 cso_insert_state(struct cso_cache *sc,
                  unsigned hash_key, enum cso_cache_type type,
                  void *state)
 {
    struct cso_hash *hash = _cso_hash_for_type(sc, type);
+   sanitize_hash(hash, type, sc->max_size);
+
    return cso_hash_insert(hash, hash_key, state);
 }
 
@@ -239,48 +333,6 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
    }
 }
 
-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);
@@ -304,6 +356,14 @@ void cso_cache_delete(struct cso_cache *sc)
 void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
 {
    sc->max_size = number;
+
+   sanitize_hash(sc->blend_hash, CSO_BLEND, sc->max_size);
+   sanitize_hash(sc->depth_stencil_hash, CSO_DEPTH_STENCIL_ALPHA,
+                 sc->max_size);
+   sanitize_hash(sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size);
+   sanitize_hash(sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
+   sanitize_hash(sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
+   sanitize_hash(sc->sampler_hash, CSO_SAMPLER, sc->max_size);
 }
 
 int cso_maximum_cache_size(const struct cso_cache *sc)
index 208fc58502b00e6ef73d712997c880c19efb4d4c..b3b4d667d2cfa8a3ce920115ad5efabf624cdfbf 100644 (file)
@@ -395,3 +395,8 @@ struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash)
    struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)};
    return iter;
 }
+
+int cso_hash_size(struct cso_hash *hash)
+{
+   return hash->data.d->size;
+}
index 86c62c027a0d275cc12ef984d995bbdd81dc2d90..d5bca9d591114b658db514ff2418b6783e56e41f 100644 (file)
@@ -47,7 +47,9 @@ struct cso_hash_iter {
 };
 
 struct cso_hash *cso_hash_create(void);
-void              cso_hash_delete(struct cso_hash *hash);
+void             cso_hash_delete(struct cso_hash *hash);
+
+int              cso_hash_size(struct cso_hash *hash);
 
 struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key,
                                      void *data);