[Mesa-dev] [PATCH v2 1/5] anv: Add a helper for doing mass allocations

Jason Ekstrand jason at jlekstrand.net
Fri Apr 7 05:53:06 UTC 2017


We tend to try to reduce the number of allocation calls the Vulkan
driver uses by doing a single allocation whenever possible for a data
structure.  While this has certain downsides (usually code complexity),
it does mean error handling and cleanup is much easier.  This commit
adds a nice little helper struct for getting rid of some of that
complexity.
---
 src/intel/vulkan/anv_private.h | 65 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 53057a5..1c5c044 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -269,6 +269,71 @@ void anv_loge_v(const char *format, va_list va);
 #define anv_assert(x)
 #endif
 
+struct anv_multialloc {
+    const VkAllocationCallbacks *alloc;
+    VkSystemAllocationScope scope;
+
+    size_t size;
+    size_t align;
+
+    uint32_t ptr_count;
+    void **ptrs[10];
+};
+
+static inline void
+anv_multialloc_init(struct anv_multialloc *ma,
+                    const VkAllocationCallbacks *alloc,
+                    VkSystemAllocationScope scope)
+{
+   ma->alloc = alloc;
+   ma->scope = scope;
+   ma->size = 0;
+   ma->align = 0;
+   ma->ptr_count = 0;
+}
+
+static inline void
+anv_multialloc_init2(struct anv_multialloc *ma,
+                     const VkAllocationCallbacks *parent_alloc,
+                     const VkAllocationCallbacks *alloc,
+                     VkSystemAllocationScope scope)
+{
+   anv_multialloc_init(ma, alloc ? alloc : parent_alloc, scope);
+}
+
+static inline void
+_anv_multialloc_add(struct anv_multialloc *ma,
+                    void **ptr, size_t size, size_t align)
+{
+   size_t offset = align_u64(ma->size, align);
+   ma->size = offset + size;
+   ma->align = MAX2(ma->align, align);
+
+   /* Store the offset in the pointer. */
+   *ptr = (void *)(uintptr_t)offset;
+
+   assert(ma->ptr_count < ARRAY_SIZE(ma->ptrs));
+   ma->ptrs[ma->ptr_count++] = ptr;
+}
+
+#define anv_multialloc_add(_ma, _ptr, _count) \
+   _anv_multialloc_add((_ma), (void **)(_ptr), \
+                       (_count) * sizeof(**(_ptr)), __alignof__(**(_ptr)))
+
+static inline void *
+anv_multialloc_finish(struct anv_multialloc *ma)
+{
+   void *ptr = vk_alloc(ma->alloc, ma->size, ma->align, ma->scope);
+   if (!ptr)
+      return NULL;
+
+   /* Fill out each of the pointers with their final value */
+   for (uint32_t i = 0; i < ma->ptr_count; i++)
+      *ma->ptrs[i] = ptr + (uintptr_t)*ma->ptrs[i];
+
+   return ptr;
+}
+
 /**
  * A dynamically growable, circular buffer.  Elements are added at head and
  * removed from tail. head and tail are free-running uint32_t indices and we
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list