#include "r600_formats.h"
#include "compute_memory_pool.h"
#include "evergreen_compute_internal.h"
+#include <inttypes.h>
-static struct r600_resource_texture * create_pool_texture(struct r600_screen * screen,
+static struct r600_texture * create_pool_texture(struct r600_screen * screen,
unsigned size_in_dw)
{
struct pipe_resource templ;
- struct r600_resource_texture * tex;
+ struct r600_texture * tex;
if (size_in_dw == 0) {
return NULL;
templ.depth0 = 1;
templ.array_size = 1;
- tex = (struct r600_resource_texture *)r600_texture_create(
+ tex = (struct r600_texture *)r600_texture_create(
&screen->screen, &templ);
/* XXX: Propagate this error */
assert(tex && "Out of memory");
COMPUTE_DBG(" Aligned size = %d\n", new_size_in_dw);
compute_memory_shadow(pool, pipe, 1);
- pool->shadow = (uint32_t*)realloc(pool->shadow, new_size_in_dw*4);
+ pool->shadow = realloc(pool->shadow, new_size_in_dw*4);
pool->size_in_dw = new_size_in_dw;
pool->screen->screen.resource_destroy(
(struct pipe_screen *)pool->screen,
COMPUTE_DBG("* compute_memory_finalize_pending()\n");
for (item = pool->item_list; item; item = item->next) {
- COMPUTE_DBG("list: %i %p\n", item->start_in_dw, item->next);
+ COMPUTE_DBG(" + list: offset = %i id = %i size = %i "
+ "(%i bytes)\n",item->start_in_dw, item->id,
+ item->size_in_dw, item->size_in_dw * 4);
}
+ /* Search through the list of memory items in the pool */
for (item = pool->item_list; item; item = next) {
next = item->next;
-
+ /* Check if the item is pending. */
if (item->start_in_dw == -1) {
+ /* It is pending, so add it to the pending_list... */
if (end_p) {
end_p->next = item;
}
pending_list = item;
}
+ /* ... and then remove it from the item list. */
if (item->prev) {
item->prev->next = next;
}
next->prev = item->prev;
}
+ /* This sequence makes the item be at the end of the list */
item->prev = end_p;
item->next = NULL;
end_p = item;
+ /* Update the amount of space we will need to allocate. */
unallocated += item->size_in_dw+1024;
}
else {
+ /* The item is not pendng, so update the amount of space
+ * that has already been allocated. */
allocated += item->size_in_dw;
}
}
+ /* 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->size_in_dw < allocated+unallocated) {
compute_memory_grow_pool(pool, pipe, allocated+unallocated);
}
+ /* Loop through all the pending items, allocate space for them and
+ * add them back to the item_list. */
for (item = pending_list; item; item = next) {
next = item->next;
int64_t start_in_dw;
+ /* Search for free space in the pool for this item. */
while ((start_in_dw=compute_memory_prealloc_chunk(pool,
item->size_in_dw)) == -1) {
int64_t need = item->size_in_dw+2048 -
pool->size_in_dw + need);
}
}
+ COMPUTE_DBG(" + Found space for Item %p id = %u "
+ "start_in_dw = %u (%u bytes) size_in_dw = %u (%u bytes)\n",
+ item, item->id, start_in_dw, start_in_dw * 4,
+ item->size_in_dw, item->size_in_dw * 4);
item->start_in_dw = start_in_dw;
item->next = NULL;
}
}
- fprintf(stderr, "Internal error, invalid id %ld "
+ fprintf(stderr, "Internal error, invalid id %"PRIi64" "
"for compute_memory_free\n", id);
assert(0 && "error");
{
struct compute_memory_item *new_item;
- COMPUTE_DBG("* compute_memory_alloc() size_in_dw = %ld\n", size_in_dw);
+ COMPUTE_DBG("* compute_memory_alloc() size_in_dw = %ld (%ld bytes)\n",
+ size_in_dw, 4 * size_in_dw);
new_item = (struct compute_memory_item *)
CALLOC(sizeof(struct compute_memory_item), 1);
pool->item_list = new_item;
}
+ COMPUTE_DBG(" + Adding item %p id = %u size = %u (%u bytes)\n",
+ new_item, new_item->id, new_item->size_in_dw,
+ new_item->size_in_dw * 4);
return new_item;
}