-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d63423f
commit 4d05743
Showing
14 changed files
with
4,225 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
//! This alloc provides base definitions for allocator functionality. | ||
use std::alloc::Layout; | ||
use std::ffi; | ||
use std::ptr::NonNull; | ||
|
||
use crate::c; | ||
|
||
/// Represents an allocation Scope that may be requested, so that data can appear | ||
/// on separate heaps. | ||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||
pub enum Scope { | ||
/// The allocation is for Command objects | ||
Command, | ||
/// The allocation is for Objects | ||
Object, | ||
/// The allocation is for Catch objects | ||
Cache, | ||
/// The allocation is for Device objects | ||
Device, | ||
/// The allocation is for Instance objects | ||
Instance, | ||
} | ||
|
||
impl Scope { | ||
fn from_c(scope: c::VkSystemAllocationScope) -> Scope { | ||
match scope { | ||
c::VkSystemAllocationScope_VK_SYSTEM_ALLOCATION_SCOPE_COMMAND => Scope::Command, | ||
c::VkSystemAllocationScope_VK_SYSTEM_ALLOCATION_SCOPE_OBJECT => Scope::Object, | ||
c::VkSystemAllocationScope_VK_SYSTEM_ALLOCATION_SCOPE_CACHE => Scope::Cache, | ||
c::VkSystemAllocationScope_VK_SYSTEM_ALLOCATION_SCOPE_DEVICE => Scope::Device, | ||
c::VkSystemAllocationScope_VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE => Scope::Instance, | ||
_ => unreachable!(), | ||
} | ||
} | ||
} | ||
|
||
/// The primary trait to define the allocation mechanisms in the Vulkan API. | ||
/// | ||
/// Types implementing this can be converted easily into [`VkAllocationCallbacks`] | ||
/// | ||
/// # Safety | ||
/// | ||
/// This trait requires the semantics of an allocator, in that an allocation | ||
/// must always be freeable by a call to deallocate. | ||
/// | ||
/// [`VkAllocationCallbacks`] c::VkAllocationCallbacks | ||
pub unsafe trait Allocator { | ||
/// The error type that may be returned | ||
type Error; | ||
|
||
/// Requests Layout memory from the underlying system to be used with the | ||
/// given allocation scope | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `layout` - the layout to allocate | ||
/// * `scope` - the amount requested to allocate | ||
fn allocate(&mut self, layout: Layout, scope: Scope) -> Result<NonNull<u8>, Self::Error>; | ||
|
||
/// Requests to deallocate the bytes at the given address | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `data` - the bytes to deallocate | ||
/// | ||
/// # Safety | ||
/// | ||
/// * `data` must denote a block of memory currently allocated via this allocator | ||
unsafe fn deallocate(&mut self, data: *mut u8); | ||
|
||
/// Requests that a given pointer be reallocated to align to the new layout | ||
/// and within the given scope. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `ptr` - the address to reallocate | ||
/// * `new_layout` - the new layout to allocate at this pointer | ||
/// * `scope` - the new scope this allocation should be allocated to | ||
/// | ||
/// # Safety | ||
/// | ||
/// This function is unsafe because undefined behavior can result if the | ||
/// caller does not ensure all of the following: | ||
/// | ||
/// * `ptr` must be currently allocated via this allocator, | ||
/// * `new_layout` must be greater than zero | ||
unsafe fn reallocate( | ||
&mut self, | ||
ptr: *mut u8, | ||
new_layout: Layout, | ||
new_scope: Scope, | ||
) -> Result<NonNull<u8>, Self::Error>; | ||
} | ||
|
||
/// A collection of allocation callbacks that can be used within Vulkan. | ||
#[derive(Clone)] | ||
pub struct AllocationCallbacks(c::VkAllocationCallbacks); | ||
|
||
impl AllocationCallbacks { | ||
/// Constructs a new set of [`AllocationCallbacks`] from an underlying | ||
/// `allocator` object. | ||
pub fn new<T: Allocator>(allocator: &mut T) -> Self { | ||
Self(c::VkAllocationCallbacks { | ||
pUserData: allocator as *mut _ as *mut ffi::c_void, | ||
pfnAllocation: Some(vulkan_alloc_fn::<T>), | ||
pfnReallocation: Some(vulkan_realloc_fn::<T>), | ||
pfnFree: Some(vulkan_dealloc_fn::<T>), | ||
pfnInternalAllocation: None, | ||
pfnInternalFree: None, | ||
}) | ||
} | ||
|
||
/// Constructs the [`AllocationCallbacks`] object from the raw underlying C | ||
/// API. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `callbacks` - the callbacks to user internally. | ||
pub const fn from_raw(callbacks: c::VkAllocationCallbacks) -> Self { | ||
Self(callbacks) | ||
} | ||
|
||
/// Returns a pointer to the internal [`VkAllocationCallbacks`] | ||
/// | ||
/// [`VkAllocationCallbacks`]: c::VkAllocationCallbacks | ||
pub fn as_ptr(&self) -> *const c::VkAllocationCallbacks { | ||
&self.0 as *const c::VkAllocationCallbacks | ||
} | ||
|
||
/// Returns a mutable pointer to the internal [`VkAllocationCallbacks`] | ||
/// | ||
/// [`VkAllocationCallbacks`]: c::VkAllocationCallbacks | ||
pub fn as_ptr_mut(&self) -> *const c::VkAllocationCallbacks { | ||
&self.0 as *const c::VkAllocationCallbacks | ||
} | ||
} | ||
|
||
unsafe extern "C" fn vulkan_alloc_fn<T: Allocator>( | ||
data: *mut ffi::c_void, | ||
size: usize, | ||
alignment: usize, | ||
scope: c::VkSystemAllocationScope, | ||
) -> *mut ffi::c_void { | ||
let allocator: &mut T = unsafe { &mut *(data as *mut T) }; | ||
let maybe_layout = Layout::from_size_align(size, alignment); | ||
|
||
let layout = match maybe_layout { | ||
Ok(layout) => layout, | ||
Err(_) => return std::ptr::null_mut(), | ||
}; | ||
|
||
match allocator.allocate(layout, Scope::from_c(scope)) { | ||
Ok(ptr) => ptr.as_ptr() as *mut ffi::c_void, | ||
Err(_) => std::ptr::null_mut(), | ||
} | ||
} | ||
|
||
unsafe extern "C" fn vulkan_dealloc_fn<T: Allocator>( | ||
data: *mut ffi::c_void, | ||
memory: *mut ffi::c_void, | ||
) { | ||
let allocator: &mut T = unsafe { &mut *(data as *mut T) }; | ||
|
||
allocator.deallocate(memory as *mut u8); | ||
} | ||
|
||
unsafe extern "C" fn vulkan_realloc_fn<T: Allocator>( | ||
data: *mut ffi::c_void, | ||
ptr: *mut ffi::c_void, | ||
size: usize, | ||
alignment: usize, | ||
scope: c::VkSystemAllocationScope, | ||
) -> *mut ffi::c_void { | ||
let allocator: &mut T = unsafe { &mut *(data as *mut T) }; | ||
let layout = Layout::from_size_align(size, alignment).expect("Invalid alignment or size"); | ||
|
||
match allocator.reallocate(ptr as *mut u8, layout, Scope::from_c(scope)) { | ||
Ok(ptr) => ptr.as_ptr() as *mut ffi::c_void, | ||
Err(_) => std::ptr::null_mut(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//! The [`debug`] module provides utilities for working with the Vulkan | ||
//! debugging layer extensions | ||
//! | ||
//! [`debug`]: crate::debug | ||
// use crate::c; | ||
|
||
// #[repr(transparent)] | ||
// struct CallbackData(c::VkDebugUtilsMessengerCallbackDataEXT); | ||
|
||
// unsafe impl foundation::Transparent for CallbackData { | ||
// type Wrapped = CallbackData; | ||
// } | ||
|
||
// pub trait DebugHook {} | ||
|
||
// pub trait PerformanceHook {} | ||
|
||
// pub trait GeneralHook {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//! This module provides wrappers for both logical and physical Vulkan devices | ||
//! (e.g. [`VkPhysicalDevice`]) | ||
//! | ||
//! [`VkPhysicalDevice`]: crate::c::VkPhysicalDevice | ||
pub mod logical; | ||
pub mod physical; |
Oops, something went wrong.