summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2009-10-01 13:35:42 -0600
committerBrian Paul <[email protected]>2009-10-01 13:35:42 -0600
commit5d2413fca4c252ec5c7880fa7f983b5df3d762ba (patch)
tree28d9fb9fc5724b65579f06fc9258461f9c7fc47f /src/mesa/drivers/dri/i965
parent15c57648cd87d344777e3aafa79a9be970b83979 (diff)
parent18883cdf2334511005973155fc517eb678dc0043 (diff)
Merge branch 'mesa_7_6_branch'
Diffstat (limited to 'src/mesa/drivers/dri/i965')
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c49
2 files changed, 50 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 5335eac8951..d639656b9d4 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -151,6 +151,7 @@ void brw_state_cache_check_size( struct brw_context *brw );
void brw_init_caches( struct brw_context *brw );
void brw_destroy_caches( struct brw_context *brw );
+void brw_state_cache_bo_delete(struct brw_cache *cache, dri_bo *bo);
/***********************************************************************
* brw_state_batch.c
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index e40d7a04164..f8e46aacf71 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -517,6 +517,55 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
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;
+ int j;
+
+ for (j = 0; j < c->nr_reloc_bufs; j++) {
+ if (c->reloc_bufs[j] == bo)
+ break;
+ }
+
+ if (j != c->nr_reloc_bufs) {
+
+ *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--;
+
+ /* Delete up the tree. Notably we're trying to get from
+ * a request to delete the surface, to deleting the surface state
+ * object, to deleting the binding table. We're slack and restart
+ * the deletion process when we do this because the other delete
+ * may kill our *prev.
+ */
+ brw_state_cache_bo_delete(cache, c->bo);
+ prev = &cache->items[i];
+ } else {
+ prev = &(*prev)->next;
+ }
+ }
+ }
+}
void
brw_state_cache_check_size(struct brw_context *brw)