Merge "BQ: Replace items from back of queue" into nyc-dev
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 6f57238..f29cb68 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -19,6 +19,7 @@
#include <algorithm>
#include <array>
#include <inttypes.h>
+#include <stdlib.h>
#include <string.h>
#include <log/log.h>
@@ -186,6 +187,58 @@
AllocHandle(type, &device->next_handle[type]));
}
+VKAPI_ATTR void* DefaultAllocate(void*,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope) {
+ void* ptr = nullptr;
+ // Vulkan requires 'alignment' to be a power of two, but posix_memalign
+ // additionally requires that it be at least sizeof(void*).
+ int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
+ return ret == 0 ? ptr : nullptr;
+}
+
+VKAPI_ATTR void* DefaultReallocate(void*,
+ void* ptr,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope) {
+ if (size == 0) {
+ free(ptr);
+ return nullptr;
+ }
+
+ // TODO(jessehall): Right now we never shrink allocations; if the new
+ // request is smaller than the existing chunk, we just continue using it.
+ // The null driver never reallocs, so this doesn't matter. If that changes,
+ // or if this code is copied into some other project, this should probably
+ // have a heuristic to allocate-copy-free when doing so will save "enough"
+ // space.
+ size_t old_size = ptr ? malloc_usable_size(ptr) : 0;
+ if (size <= old_size)
+ return ptr;
+
+ void* new_ptr = nullptr;
+ if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0)
+ return nullptr;
+ if (ptr) {
+ memcpy(new_ptr, ptr, std::min(old_size, size));
+ free(ptr);
+ }
+ return new_ptr;
+}
+
+VKAPI_ATTR void DefaultFree(void*, void* ptr) {
+ free(ptr);
+}
+
+const VkAllocationCallbacks kDefaultAllocCallbacks = {
+ .pUserData = nullptr,
+ .pfnAllocation = DefaultAllocate,
+ .pfnReallocation = DefaultReallocate,
+ .pfnFree = DefaultFree,
+};
+
} // namespace
namespace null_driver {
@@ -239,10 +292,8 @@
VkResult CreateInstance(const VkInstanceCreateInfo* create_info,
const VkAllocationCallbacks* allocator,
VkInstance* out_instance) {
- // Assume the loader provided alloc callbacks even if the app didn't.
- ALOG_ASSERT(
- allocator,
- "Missing alloc callbacks, loader or app should have provided them");
+ if (!allocator)
+ allocator = &kDefaultAllocCallbacks;
VkInstance_T* instance =
static_cast<VkInstance_T*>(allocator->pfnAllocation(