use core;
use libc::c_void;
use std::mem;
use std::sync::Arc;
use vks;
unsafe extern "system" fn alloc(user_data: *mut c_void, size: usize, alignment: usize, allocation_scope: vks::VkSystemAllocationScope) -> *mut c_void {
let allocator = user_data as *const Box<core::Allocator>;
(*allocator).alloc(size, alignment, allocation_scope.into())
}
unsafe extern "system" fn realloc(user_data: *mut c_void, original: *mut c_void, size: usize, alignment: usize, allocation_scope: vks::VkSystemAllocationScope) -> *mut c_void {
let allocator = user_data as *const Box<core::Allocator>;
(*allocator).realloc(original, size, alignment, allocation_scope.into())
}
unsafe extern "system" fn free(user_data: *mut c_void, memory: *mut c_void) {
let allocator = user_data as *const Box<core::Allocator>;
(*allocator).free(memory);
}
unsafe extern "system" fn internal_alloc(user_data: *mut c_void, size: usize, allocation_type: vks::VkInternalAllocationType, allocation_scope: vks::VkSystemAllocationScope) {
let allocator = user_data as *const Box<core::Allocator>;
(*allocator).internal_alloc(size, allocation_type.into(), allocation_scope.into())
}
unsafe extern "system" fn internal_free(user_data: *mut c_void, size: usize, allocation_type: vks::VkInternalAllocationType, allocation_scope: vks::VkSystemAllocationScope) {
let allocator = user_data as *const Box<core::Allocator>;
(*allocator).internal_free(size, allocation_type.into(), allocation_scope.into())
}
#[derive(Debug, Clone)]
pub struct AllocatorHelper {
callbacks: vks::VkAllocationCallbacks,
allocator: Arc<Box<core::Allocator>>,
}
impl AllocatorHelper {
pub fn new(allocator: Box<core::Allocator>) -> Self {
let has_internal_alloc = allocator.has_internal_alloc();
let allocator = Arc::new(allocator);
let allocator_ptr = Arc::into_raw(allocator);
let allocator = unsafe { Arc::from_raw(allocator_ptr) };
let mut allocation_callbacks = vks::VkAllocationCallbacks {
pUserData: allocator_ptr as *mut c_void,
pfnAllocation: alloc,
pfnReallocation: realloc,
pfnFree: free,
pfnInternalAllocation: unsafe { mem::transmute(0usize) },
pfnInternalFree: unsafe { mem::transmute(0usize) },
};
if has_internal_alloc {
allocation_callbacks.pfnInternalAllocation = internal_alloc;
allocation_callbacks.pfnInternalFree = internal_free;
}
AllocatorHelper {
callbacks: allocation_callbacks,
allocator: allocator,
}
}
#[inline]
pub fn callbacks(&self) -> *const vks::VkAllocationCallbacks {
&self.callbacks
}
}