Merge branch 'gallium-format-cleanup'
[mesa.git] / src / gallium / auxiliary / cso_cache / cso_cache.c
index 63464e070581b17dd4b3367c0ccad608846a61d0..a6a07e72c2f985bdad571aa95bb0a64f07e09747 100644 (file)
@@ -28,8 +28,9 @@
 /* Authors:  Zack Rusin <zack@tungstengraphics.com>
  */
 
-#include "pipe/p_util.h"
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
+
+#include "util/u_memory.h"
 
 #include "cso_cache.h"
 #include "cso_hash.h"
@@ -43,6 +44,9 @@ struct cso_cache {
    struct cso_hash *rasterizer_hash;
    struct cso_hash *sampler_hash;
    int    max_size;
+
+   cso_sanitize_callback sanitize_cb;
+   void                 *sanitize_data;
 };
 
 #if 1
@@ -109,26 +113,6 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
    return hash;
 }
 
-static int _cso_size_for_type(enum cso_cache_type type)
-{
-   switch(type) {
-   case CSO_BLEND:
-      return sizeof(struct pipe_blend_state);
-   case CSO_SAMPLER:
-      return sizeof(struct pipe_sampler_state);
-   case CSO_DEPTH_STENCIL_ALPHA:
-      return sizeof(struct pipe_depth_stencil_alpha_state);
-   case CSO_RASTERIZER:
-      return sizeof(struct pipe_rasterizer_state);
-   case CSO_FRAGMENT_SHADER:
-      return sizeof(struct pipe_shader_state);
-   case CSO_VERTEX_SHADER:
-      return sizeof(struct pipe_shader_state);
-   }
-   return 0;
-}
-
-
 static void delete_blend_state(void *state, void *data)
 {
    struct cso_blend *cso = (struct cso_blend *)state;
@@ -205,8 +189,19 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type)
    }
 }
 
-static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
+
+static INLINE void sanitize_hash(struct cso_cache *sc,
+                                 struct cso_hash *hash,
+                                 enum cso_cache_type type,
                                  int max_size)
+{
+   if (sc->sanitize_cb)
+      sc->sanitize_cb(hash, type, max_size, sc->sanitize_data);
+}
+
+
+static INLINE void sanitize_cb(struct cso_hash *hash, enum cso_cache_type type,
+                               int max_size, void *user_data)
 {
    /* if we're approach the maximum size, remove fourth of the entries
     * otherwise every subsequent call will go through the same */
@@ -231,7 +226,7 @@ cso_insert_state(struct cso_cache *sc,
                  void *state)
 {
    struct cso_hash *hash = _cso_hash_for_type(sc, type);
-   sanitize_hash(hash, type, sc->max_size);
+   sanitize_hash(sc, hash, type, sc->max_size);
 
    return cso_hash_insert(hash, hash_key, state);
 }
@@ -255,9 +250,9 @@ void *cso_hash_find_data_from_template( struct cso_hash *hash,
    while (!cso_hash_iter_is_null(iter)) {
       void *iter_data = cso_hash_iter_data(iter);
       if (!memcmp(iter_data, templ, size)) {
-        /* Return the payload: 
+        /* We found a match
          */
-         return (unsigned char *)iter_data + size;
+         return iter_data;
       }
       iter = cso_hash_iter_next(iter);
    }
@@ -267,10 +262,9 @@ void *cso_hash_find_data_from_template( struct cso_hash *hash,
 
 struct cso_hash_iter cso_find_state_template(struct cso_cache *sc,
                                              unsigned hash_key, enum cso_cache_type type,
-                                             void *templ)
+                                             void *templ, unsigned size)
 {
    struct cso_hash_iter iter = cso_find_state(sc, hash_key, type);
-   int size = _cso_size_for_type(type);
    while (!cso_hash_iter_is_null(iter)) {
       void *iter_data = cso_hash_iter_data(iter);
       if (!memcmp(iter_data, templ, size))
@@ -300,6 +294,8 @@ struct cso_cache *cso_cache_create(void)
    sc->rasterizer_hash    = cso_hash_create();
    sc->fs_hash            = cso_hash_create();
    sc->vs_hash            = cso_hash_create();
+   sc->sanitize_cb        = sanitize_cb;
+   sc->sanitize_data      = 0;
 
    return sc;
 }
@@ -344,6 +340,10 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
 void cso_cache_delete(struct cso_cache *sc)
 {
    assert(sc);
+
+   if (!sc)
+      return;
+
    /* 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);
@@ -365,13 +365,13 @@ 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,
+   sanitize_hash(sc, sc->blend_hash, CSO_BLEND, sc->max_size);
+   sanitize_hash(sc, 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);
+   sanitize_hash(sc, sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size);
+   sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
+   sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
+   sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size);
 }
 
 int cso_maximum_cache_size(const struct cso_cache *sc)
@@ -379,3 +379,11 @@ int cso_maximum_cache_size(const struct cso_cache *sc)
    return sc->max_size;
 }
 
+void cso_cache_set_sanitize_callback(struct cso_cache *sc,
+                                     cso_sanitize_callback cb,
+                                     void *user_data)
+{
+   sc->sanitize_cb   = cb;
+   sc->sanitize_data = user_data;
+}
+