diff options
-rw-r--r-- | src/gallium/drivers/r600/compute_memory_pool.c | 32 | ||||
-rw-r--r-- | src/gallium/drivers/r600/compute_memory_pool.h | 4 |
2 files changed, 19 insertions, 17 deletions
diff --git a/src/gallium/drivers/r600/compute_memory_pool.c b/src/gallium/drivers/r600/compute_memory_pool.c index 00b28bc3249..b158f5e36be 100644 --- a/src/gallium/drivers/r600/compute_memory_pool.c +++ b/src/gallium/drivers/r600/compute_memory_pool.c @@ -262,23 +262,10 @@ int compute_memory_finalize_pending(struct compute_memory_pool* pool, unallocated += align(item->size_in_dw, ITEM_ALIGNMENT); } - /* If we require more space than the size of the pool, then grow the - * pool. - * - * XXX: I'm pretty sure this won't work. Imagine this scenario: - * - * Offset Item Size - * 0 A 50 - * 200 B 50 - * 400 C 50 - * - * Total size = 450 - * Allocated size = 150 - * Pending Item D Size = 200 - * - * In this case, there are 300 units of free space in the pool, but - * they aren't contiguous, so it will be impossible to allocate Item D. - */ + if (pool->status & POOL_FRAGMENTED) { + compute_memory_defrag(pool, pipe); + } + if (pool->size_in_dw < allocated + unallocated) { err = compute_memory_grow_pool(pool, pipe, allocated + unallocated); if (err == -1) @@ -324,6 +311,8 @@ void compute_memory_defrag(struct compute_memory_pool *pool, last_pos += align(item->size_in_dw, ITEM_ALIGNMENT); } + + pool->status &= ~POOL_FRAGMENTED; } int compute_memory_promote_item(struct compute_memory_pool *pool, @@ -430,6 +419,10 @@ void compute_memory_demote_item(struct compute_memory_pool *pool, /* Remember to mark the buffer as 'pending' by setting start_in_dw to -1 */ item->start_in_dw = -1; + + if (item->link.next != pool->item_list) { + pool->status |= POOL_FRAGMENTED; + } } /** @@ -533,6 +526,11 @@ void compute_memory_free(struct compute_memory_pool* pool, int64_t id) LIST_FOR_EACH_ENTRY_SAFE(item, next, pool->item_list, link) { if (item->id == id) { + + if (item->link.next != pool->item_list) { + pool->status |= POOL_FRAGMENTED; + } + list_del(&item->link); if (item->real_buffer) { diff --git a/src/gallium/drivers/r600/compute_memory_pool.h b/src/gallium/drivers/r600/compute_memory_pool.h index 5d187778d63..acc68ea172f 100644 --- a/src/gallium/drivers/r600/compute_memory_pool.h +++ b/src/gallium/drivers/r600/compute_memory_pool.h @@ -32,6 +32,8 @@ #define ITEM_FOR_PROMOTING (1<<2) #define ITEM_FOR_DEMOTING (1<<3) +#define POOL_FRAGMENTED (1<<0) + struct compute_memory_pool; struct compute_memory_item @@ -60,6 +62,8 @@ struct compute_memory_pool uint32_t *shadow; ///host copy of the pool, used for defragmentation + uint32_t status; /**< Status of the pool */ + struct list_head *item_list; ///Allocated memory chunks in the buffer,they must be ordered by "start_in_dw" struct list_head *unallocated_list; ///Unallocated memory chunks }; |