i965: Mostly fix glsl-max-varyings.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_state_cache.c
index 502ad0bd6cc24ceec0e7ded1ab306127ad834860..b31d84953a1a9639e85b956d0dd360e29768f62c 100644 (file)
 #include "main/imports.h"
 #include "brw_state.h"
 #include "intel_batchbuffer.h"
-
-/* XXX: Fixme - have to include these to get the sizes of the prog_key
- * structs:
- */
 #include "brw_wm.h"
-#include "brw_vs.h"
-#include "brw_clip.h"
-#include "brw_sf.h"
-#include "brw_gs.h"
 
 
 static GLuint
-hash_key(const void *key, GLuint key_size,
-         dri_bo **reloc_bufs, GLuint nr_reloc_bufs)
+hash_key(struct brw_cache_item *item)
 {
-   GLuint *ikey = (GLuint *)key;
-   GLuint hash = 0, i;
+   GLuint *ikey = (GLuint *)item->key;
+   GLuint hash = item->cache_id, i;
 
-   assert(key_size % 4 == 0);
+   assert(item->key_size % 4 == 0);
 
    /* I'm sure this can be improved on:
     */
-   for (i = 0; i < key_size/4; i++) {
+   for (i = 0; i < item->key_size/4; i++) {
       hash ^= ikey[i];
       hash = (hash << 5) | (hash >> 27);
    }
 
    /* Include the BO pointers as key data as well */
-   ikey = (GLuint *)reloc_bufs;
-   key_size = nr_reloc_bufs * sizeof(dri_bo *);
-   for (i = 0; i < key_size/4; i++) {
+   ikey = (GLuint *)item->reloc_bufs;
+   for (i = 0; i < item->nr_reloc_bufs * sizeof(drm_intel_bo *) / 4; i++) {
       hash ^= ikey[i];
       hash = (hash << 5) | (hash >> 27);
    }
@@ -103,22 +93,33 @@ hash_key(const void *key, GLuint key_size,
  */
 static void
 update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,
-                 dri_bo *bo)
+                 drm_intel_bo *bo)
 {
    if (bo == cache->last_bo[cache_id])
       return; /* no change */
 
-   dri_bo_unreference(cache->last_bo[cache_id]);
+   drm_intel_bo_unreference(cache->last_bo[cache_id]);
    cache->last_bo[cache_id] = bo;
-   dri_bo_reference(cache->last_bo[cache_id]);
+   drm_intel_bo_reference(cache->last_bo[cache_id]);
    cache->brw->state.dirty.cache |= 1 << cache_id;
 }
 
+static int
+brw_cache_item_equals(const struct brw_cache_item *a,
+                     const struct brw_cache_item *b)
+{
+   return a->cache_id == b->cache_id &&
+      a->hash == b->hash &&
+      a->key_size == b->key_size &&
+      (memcmp(a->key, b->key, a->key_size) == 0) &&
+      a->nr_reloc_bufs == b->nr_reloc_bufs &&
+      (memcmp(a->reloc_bufs, b->reloc_bufs,
+             a->nr_reloc_bufs * sizeof(drm_intel_bo *)) == 0);
+}
 
 static struct brw_cache_item *
-search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
-            GLuint hash, const void *key, GLuint key_size,
-            dri_bo **reloc_bufs, GLuint nr_reloc_bufs)
+search_cache(struct brw_cache *cache, GLuint hash,
+            struct brw_cache_item *lookup)
 {
    struct brw_cache_item *c;
 
@@ -133,13 +134,7 @@ search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
 #endif
 
    for (c = cache->items[hash % cache->size]; c; c = c->next) {
-      if (c->cache_id == cache_id &&
-         c->hash == hash &&
-         c->key_size == key_size &&
-         memcmp(c->key, key, key_size) == 0 &&
-         c->nr_reloc_bufs == nr_reloc_bufs &&
-         memcmp(c->reloc_bufs, reloc_bufs,
-                nr_reloc_bufs * sizeof(dri_bo *)) == 0)
+      if (brw_cache_item_equals(lookup, c))
         return c;
    }
 
@@ -155,7 +150,7 @@ rehash(struct brw_cache *cache)
    GLuint size, i;
 
    size = cache->size * 3;
-   items = (struct brw_cache_item**) _mesa_calloc(size * sizeof(*items));
+   items = (struct brw_cache_item**) calloc(1, size * sizeof(*items));
 
    for (i = 0; i < cache->size; i++)
       for (c = cache->items[i]; c; c = next) {
@@ -173,19 +168,27 @@ rehash(struct brw_cache *cache)
 /**
  * Returns the buffer object matching cache_id and key, or NULL.
  */
-dri_bo *
+drm_intel_bo *
 brw_search_cache(struct brw_cache *cache,
                  enum brw_cache_id cache_id,
                  const void *key,
                  GLuint key_size,
-                 dri_bo **reloc_bufs, GLuint nr_reloc_bufs,
+                 drm_intel_bo **reloc_bufs, GLuint nr_reloc_bufs,
                  void *aux_return)
 {
    struct brw_cache_item *item;
-   GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs);
+   struct brw_cache_item lookup;
+   GLuint hash;
+
+   lookup.cache_id = cache_id;
+   lookup.key = key;
+   lookup.key_size = key_size;
+   lookup.reloc_bufs = reloc_bufs;
+   lookup.nr_reloc_bufs = nr_reloc_bufs;
+   hash = hash_key(&lookup);
+   lookup.hash = hash;
 
-   item = search_cache(cache, cache_id, hash, key, key_size,
-                      reloc_bufs, nr_reloc_bufs);
+   item = search_cache(cache, hash, &lookup);
 
    if (item == NULL)
       return NULL;
@@ -195,7 +198,7 @@ brw_search_cache(struct brw_cache *cache,
 
    update_cache_last(cache, cache_id, item->bo);
 
-   dri_bo_reference(item->bo);
+   drm_intel_bo_reference(item->bo);
    return item->bo;
 }
 
@@ -205,7 +208,7 @@ brw_upload_cache_with_auxdata(struct brw_cache *cache,
                              enum brw_cache_id cache_id,
                              const void *key,
                              GLuint key_size,
-                             dri_bo **reloc_bufs,
+                             drm_intel_bo **reloc_bufs,
                              GLuint nr_reloc_bufs,
                              const void *data,
                              GLuint data_size,
@@ -214,37 +217,41 @@ brw_upload_cache_with_auxdata(struct brw_cache *cache,
                              void *aux_return)
 {
    struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
-   GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs);
-   GLuint relocs_size = nr_reloc_bufs * sizeof(dri_bo *);
+   GLuint hash;
+   GLuint relocs_size = nr_reloc_bufs * sizeof(drm_intel_bo *);
    void *tmp;
-   dri_bo *bo;
+   drm_intel_bo *bo;
    int i;
 
+   item->cache_id = cache_id;
+   item->key = key;
+   item->key_size = key_size;
+   item->reloc_bufs = reloc_bufs;
+   item->nr_reloc_bufs = nr_reloc_bufs;
+   hash = hash_key(item);
+   item->hash = hash;
+
    /* Create the buffer object to contain the data */
-   bo = dri_bo_alloc(cache->brw->intel.bufmgr,
-                    cache->name[cache_id], data_size, 1 << 6);
+   bo = drm_intel_bo_alloc(cache->brw->intel.bufmgr,
+                          cache->name[cache_id], data_size, 1 << 6);
 
 
    /* Set up the memory containing the key, aux_data, and reloc_bufs */
-   tmp = _mesa_malloc(key_size + aux_size + relocs_size);
+   tmp = malloc(key_size + aux_size + relocs_size);
 
    memcpy(tmp, key, key_size);
    memcpy(tmp + key_size, aux, aux_size);
    memcpy(tmp + key_size + aux_size, reloc_bufs, relocs_size);
    for (i = 0; i < nr_reloc_bufs; i++) {
       if (reloc_bufs[i] != NULL)
-        dri_bo_reference(reloc_bufs[i]);
+        drm_intel_bo_reference(reloc_bufs[i]);
    }
 
-   item->cache_id = cache_id;
    item->key = tmp;
-   item->hash = hash;
-   item->key_size = key_size;
    item->reloc_bufs = tmp + key_size + aux_size;
-   item->nr_reloc_bufs = nr_reloc_bufs;
 
    item->bo = bo;
-   dri_bo_reference(bo);
+   drm_intel_bo_reference(bo);
 
    if (cache->n_items > cache->size * 1.5)
       rehash(cache);
@@ -259,12 +266,12 @@ brw_upload_cache_with_auxdata(struct brw_cache *cache,
    }
 
    if (INTEL_DEBUG & DEBUG_STATE)
-      _mesa_printf("upload %s: %d bytes to cache id %d\n",
+      printf("upload %s: %d bytes to cache id %d\n",
                   cache->name[cache_id],
                   data_size, cache_id);
 
    /* Copy data to the buffer */
-   dri_bo_subdata(bo, 0, data_size, data);
+   drm_intel_bo_subdata(bo, 0, data_size, data);
 
    update_cache_last(cache, cache_id, bo);
 
@@ -276,7 +283,7 @@ brw_upload_cache(struct brw_cache *cache,
                 enum brw_cache_id cache_id,
                 const void *key,
                 GLuint key_size,
-                dri_bo **reloc_bufs,
+                drm_intel_bo **reloc_bufs,
                 GLuint nr_reloc_bufs,
                 const void *data,
                 GLuint data_size)
@@ -299,29 +306,34 @@ brw_upload_cache(struct brw_cache *cache,
  * If aux data is involved, use search/upload instead.
 
  */
-dri_bo *
+drm_intel_bo *
 brw_cache_data(struct brw_cache *cache,
               enum brw_cache_id cache_id,
               const void *data,
-              GLuint data_size,
-              dri_bo **reloc_bufs,
-              GLuint nr_reloc_bufs)
+              GLuint data_size)
 {
-   dri_bo *bo;
-   struct brw_cache_item *item;
-   GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs);
-
-   item = search_cache(cache, cache_id, hash, data, data_size,
-                      reloc_bufs, nr_reloc_bufs);
+   drm_intel_bo *bo;
+   struct brw_cache_item *item, lookup;
+   GLuint hash;
+
+   lookup.cache_id = cache_id;
+   lookup.key = data;
+   lookup.key_size = data_size;
+   lookup.reloc_bufs = NULL;
+   lookup.nr_reloc_bufs = 0;
+   hash = hash_key(&lookup);
+   lookup.hash = hash;
+
+   item = search_cache(cache, hash, &lookup);
    if (item) {
       update_cache_last(cache, cache_id, item->bo);
-      dri_bo_reference(item->bo);
+      drm_intel_bo_reference(item->bo);
       return item->bo;
    }
 
    bo = brw_upload_cache(cache, cache_id,
                         data, data_size,
-                        reloc_bufs, nr_reloc_bufs,
+                        NULL, 0,
                         data, data_size);
 
    return bo;
@@ -352,7 +364,7 @@ brw_init_non_surface_cache(struct brw_context *brw)
    cache->size = 7;
    cache->n_items = 0;
    cache->items = (struct brw_cache_item **)
-      _mesa_calloc(cache->size * sizeof(struct brw_cache_item));
+      calloc(1, cache->size * sizeof(struct brw_cache_item));
 
    brw_init_cache_id(cache, "CC_VP", BRW_CC_VP);
    brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT);
@@ -372,35 +384,20 @@ brw_init_non_surface_cache(struct brw_context *brw)
    brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT);
 
    brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG);
+   brw_init_cache_id(cache, "CLIP_VP", BRW_CLIP_VP);
 
    brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT);
 
    brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG);
+   brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE);
+   brw_init_cache_id(cache, "COLOR_CALC_STATE", BRW_COLOR_CALC_STATE);
+   brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE);
 }
 
-
-static void
-brw_init_surface_cache(struct brw_context *brw)
-{
-   struct brw_cache *cache = &brw->surface_cache;
-
-   cache->brw = brw;
-
-   cache->size = 7;
-   cache->n_items = 0;
-   cache->items = (struct brw_cache_item **)
-      _mesa_calloc(cache->size * sizeof(struct brw_cache_item));
-
-   brw_init_cache_id(cache, "SS_SURFACE", BRW_SS_SURFACE);
-   brw_init_cache_id(cache, "SS_SURF_BIND", BRW_SS_SURF_BIND);
-}
-
-
 void
 brw_init_caches(struct brw_context *brw)
 {
    brw_init_non_surface_cache(brw);
-   brw_init_surface_cache(brw);
 }
 
 
@@ -411,7 +408,7 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
    GLuint i;
 
    if (INTEL_DEBUG & DEBUG_STATE)
-      _mesa_printf("%s\n", __FUNCTION__);
+      printf("%s\n", __FUNCTION__);
 
    for (i = 0; i < cache->size; i++) {
       for (c = cache->items[i]; c; c = next) {
@@ -419,8 +416,8 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
 
         next = c->next;
         for (j = 0; j < c->nr_reloc_bufs; j++)
-           dri_bo_unreference(c->reloc_bufs[j]);
-        dri_bo_unreference(c->bo);
+           drm_intel_bo_unreference(c->reloc_bufs[j]);
+        drm_intel_bo_unreference(c->bo);
         free((void *)c->key);
         free(c);
       }
@@ -429,66 +426,22 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
 
    cache->n_items = 0;
 
-   if (brw->curbe.last_buf) {
-      _mesa_free(brw->curbe.last_buf);
-      brw->curbe.last_buf = NULL;
-   }
-
    brw->state.dirty.mesa |= ~0;
    brw->state.dirty.brw |= ~0;
    brw->state.dirty.cache |= ~0;
 }
 
-/* Clear all entries from the cache that point to the given bo.
- *
- * This lets us release memory for reuse earlier for known-dead buffers,
- * at the cost of walking the entire hash table.
- */
-void
-brw_state_cache_bo_delete(struct brw_cache *cache, dri_bo *bo)
-{
-   struct brw_cache_item **prev;
-   GLuint i;
-
-   if (INTEL_DEBUG & DEBUG_STATE)
-      _mesa_printf("%s\n", __FUNCTION__);
-
-   for (i = 0; i < cache->size; i++) {
-      for (prev = &cache->items[i]; *prev;) {
-        struct brw_cache_item *c = *prev;
-
-        if (drm_intel_bo_references(c->bo, bo)) {
-           int j;
-
-           *prev = c->next;
-
-           for (j = 0; j < c->nr_reloc_bufs; j++)
-              dri_bo_unreference(c->reloc_bufs[j]);
-           dri_bo_unreference(c->bo);
-           free((void *)c->key);
-           free(c);
-           cache->n_items--;
-        } else {
-           prev = &c->next;
-        }
-      }
-   }
-}
-
 void
 brw_state_cache_check_size(struct brw_context *brw)
 {
    if (INTEL_DEBUG & DEBUG_STATE)
-      _mesa_printf("%s (n_items=%d)\n", __FUNCTION__, brw->cache.n_items);
+      printf("%s (n_items=%d)\n", __FUNCTION__, brw->cache.n_items);
 
-   /* un-tuned guess.  We've got around 20 state objects for a total of around
-    * 32k, so 1000 of them is around 1.5MB.
+   /* un-tuned guess.  Each object is generally a page, so 1000 of them is 4 MB of
+    * state cache.
     */
    if (brw->cache.n_items > 1000)
       brw_clear_cache(brw, &brw->cache);
-
-   if (brw->surface_cache.n_items > 1000)
-      brw_clear_cache(brw, &brw->surface_cache);
 }
 
 
@@ -498,11 +451,11 @@ brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache)
    GLuint i;
 
    if (INTEL_DEBUG & DEBUG_STATE)
-      _mesa_printf("%s\n", __FUNCTION__);
+      printf("%s\n", __FUNCTION__);
 
    brw_clear_cache(brw, cache);
    for (i = 0; i < BRW_MAX_CACHE; i++) {
-      dri_bo_unreference(cache->last_bo[i]);
+      drm_intel_bo_unreference(cache->last_bo[i]);
       free(cache->name[i]);
    }
    free(cache->items);
@@ -515,5 +468,4 @@ void
 brw_destroy_caches(struct brw_context *brw)
 {
    brw_destroy_cache(brw, &brw->cache);
-   brw_destroy_cache(brw, &brw->surface_cache);
 }