Files
VulkanDriver/src/vulkan/VulkanAllocator.zig

76 lines
2.6 KiB
Zig

//! A Zig allocator from VkAllocationCallbacks.
//! Falls back on c_allocator if callbacks passed are null
const std = @import("std");
const vk = @import("vulkan");
const builtin = @import("builtin");
const DRIVER_DEBUG_ALLOCATOR_ENV_NAME = @import("lib.zig").DRIVER_DEBUG_ALLOCATOR_ENV_NAME;
const Allocator = std.mem.Allocator;
const Alignment = std.mem.Alignment;
const Self = @This();
pub var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
callbacks: ?vk.AllocationCallbacks,
scope: vk.SystemAllocationScope,
pub fn init(callbacks: ?*const vk.AllocationCallbacks, scope: vk.SystemAllocationScope) Self {
const deref_callbacks = if (callbacks) |c| c.* else null;
return .{
.callbacks = deref_callbacks,
.scope = scope,
};
}
pub fn allocator(self: *const Self) Allocator {
if (self.callbacks != null) {
return .{
.ptr = @constCast(self),
.vtable = &.{
.alloc = alloc,
.resize = resize,
.remap = remap,
.free = free,
},
};
}
return if (std.process.hasEnvVarConstant(DRIVER_DEBUG_ALLOCATOR_ENV_NAME) or builtin.mode == std.builtin.OptimizeMode.Debug)
debug_allocator.allocator()
else
std.heap.c_allocator;
}
fn alloc(context: *anyopaque, len: usize, alignment: Alignment, _: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context));
if (self.callbacks.?.pfn_allocation) |pfn_allocation| {
return @ptrCast(pfn_allocation(self.callbacks.?.p_user_data, len, alignment.toByteUnits(), self.scope));
}
@panic("Null PFN_vkAllocationFunction passed to VkAllocationCallbacks");
}
fn resize(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, _: usize) bool {
_ = alignment;
_ = context;
return new_len <= ptr.len;
}
fn remap(context: *anyopaque, ptr: []u8, alignment: Alignment, new_len: usize, _: usize) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(context));
if (self.callbacks.?.pfn_reallocation) |pfn_reallocation| {
return @ptrCast(pfn_reallocation(self.callbacks.?.p_user_data, ptr.ptr, new_len, alignment.toByteUnits(), self.scope));
}
@panic("Null PFN_vkReallocationFunction passed to VkAllocationCallbacks");
}
fn free(context: *anyopaque, ptr: []u8, alignment: Alignment, _: usize) void {
_ = alignment;
const self: *Self = @ptrCast(@alignCast(context));
if (self.callbacks.?.pfn_free) |pfn_free| {
return pfn_free(self.callbacks.?.p_user_data, ptr.ptr);
}
@panic("Null PFN_vkFreeFunction passed to VkAllocationCallbacks");
}