vk/allocator: Add a concept of a slave block pool
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 19 May 2015 02:55:34 +0000 (19:55 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 19 May 2015 03:57:43 +0000 (20:57 -0700)
We probably need a better name but this will do for now.

src/vulkan/allocator.c
src/vulkan/private.h

index aeffe76140737389efa04f9a9d64d7dd8bf3ff59..11cdf39819896d83ff51dbf4becd5f9184b14475 100644 (file)
@@ -221,6 +221,39 @@ anv_block_pool_init(struct anv_block_pool *pool,
    anv_block_pool_grow(pool);
 }
 
+/** Initializes a block pool that is a slave of another
+ *
+ * The newly initialized pool is not a block pool on its own but it rather
+ * takes a fixed number of blocks from the master pool and hands them out.
+ * In some sense, it's nothing more than a glorified free list.  However,
+ * since it is a block pool, it can be used to back a pool or stream.
+ */
+void
+anv_block_pool_init_slave(struct anv_block_pool *pool,
+                          struct anv_block_pool *master_pool,
+                          uint32_t num_blocks)
+{
+   pool->device = NULL;
+
+   /* We don't have backing storage */
+   pool->bo.gem_handle = 0;
+   pool->bo.offset = 0;
+   pool->size = 0;
+   pool->next_block = 0;
+
+   pool->block_size = master_pool->block_size;
+   pool->free_list = ANV_FREE_LIST_EMPTY;
+   anv_vector_init(&pool->mmap_cleanups,
+                   round_to_power_of_two(sizeof(struct anv_mmap_cleanup)), 128);
+
+   /* Pull N blocks off the master pool and put them on this pool */
+   for (uint32_t i = 0; i < num_blocks; i++) {
+      uint32_t block = anv_block_pool_alloc(master_pool);
+      pool->map = master_pool->map;
+      anv_block_pool_free(pool, block);
+   }
+}
+
 /* The memfd path lets us create a map for an fd and lets us grow and remap
  * without copying.  It breaks valgrind however, so we have a MAP_ANONYMOUS
  * path we can take for valgrind debugging. */
@@ -258,6 +291,12 @@ anv_block_pool_grow(struct anv_block_pool *pool)
    int gem_handle;
    struct anv_mmap_cleanup *cleanup;
 
+   /* If we don't have a device then we can't resize the pool.  This can be
+    * the case if the pool is a slave pool.
+    */
+   if (pool->device == NULL)
+      return -1;
+
    if (pool->size == 0) {
       size = 32 * pool->block_size;
    } else {
index b79dea3ddc480295b34929b299dcf02d6b6d87b9..fb28b61aff184264b2d23fa1250a41e50b9f921f 100644 (file)
@@ -233,6 +233,9 @@ struct anv_state_stream {
 
 void anv_block_pool_init(struct anv_block_pool *pool,
                          struct anv_device *device, uint32_t block_size);
+void anv_block_pool_init_slave(struct anv_block_pool *pool,
+                               struct anv_block_pool *master_pool,
+                               uint32_t num_blocks);
 void anv_block_pool_finish(struct anv_block_pool *pool);
 uint32_t anv_block_pool_alloc(struct anv_block_pool *pool);
 void anv_block_pool_free(struct anv_block_pool *pool, uint32_t offset);