mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-22 15:01:31 +11:00
Implement vkMapMemory, vkUnmapMemory, vkBindBufferMemory, vkGetBufferMemoryRequirements, vkDestroyBuffer and vkDestroyImage
This commit is contained in:
parent
092c522b8e
commit
728e338ffa
|
@ -1,3 +1,4 @@
|
|||
use VK_NULL_HANDLE;
|
||||
use std::{fmt, ops};
|
||||
|
||||
|
||||
|
@ -13,6 +14,10 @@ impl<T> Handle<T> {
|
|||
pub fn unwrap(self) -> Box<T> {
|
||||
unsafe { Box::from_raw(self.0) }
|
||||
}
|
||||
|
||||
pub fn is_null(&self) -> bool {
|
||||
self.0 == VK_NULL_HANDLE as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for Handle<T> {
|
||||
|
|
|
@ -295,14 +295,31 @@ pub extern fn gfxFreeMemory(
|
|||
) {
|
||||
gpu.device.free_memory(*memory.unwrap());
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkMapMemory(device: VkDevice, memory: VkDeviceMemory,
|
||||
offset: VkDeviceSize, size: VkDeviceSize,
|
||||
flags: VkMemoryMapFlags,
|
||||
ppData: *mut *mut ::std::os::raw::c_void) -> VkResult;
|
||||
#[inline]
|
||||
pub extern fn gfxMapMemory(
|
||||
gpu: VkDevice,
|
||||
memory: VkDeviceMemory,
|
||||
offset: VkDeviceSize,
|
||||
size: VkDeviceSize,
|
||||
_flags: VkMemoryMapFlags,
|
||||
ppData: *mut *mut ::std::os::raw::c_void,
|
||||
) -> VkResult {
|
||||
if size == VK_WHOLE_SIZE as VkDeviceSize {
|
||||
unimplemented!()
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkUnmapMemory(device: VkDevice, memory: VkDeviceMemory);
|
||||
|
||||
unsafe {
|
||||
*ppData = gpu
|
||||
.device
|
||||
.map_memory(&memory, offset..offset+size)
|
||||
.unwrap() as *mut _; // TODO
|
||||
}
|
||||
|
||||
VkResult::VK_SUCCESS
|
||||
}
|
||||
#[inline]
|
||||
pub extern fn gfxUnmapMemory(gpu: VkDevice, memory: VkDeviceMemory) {
|
||||
gpu.device.unmap_memory(&memory);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkFlushMappedMemoryRanges(device: VkDevice, memoryRangeCount: u32,
|
||||
|
@ -323,10 +340,28 @@ extern "C" {
|
|||
pCommittedMemoryInBytes:
|
||||
*mut VkDeviceSize);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkBindBufferMemory(device: VkDevice, buffer: VkBuffer,
|
||||
#[inline]
|
||||
pub extern fn gfxBindBufferMemory(
|
||||
gpu: VkDevice,
|
||||
mut buffer: VkBuffer,
|
||||
memory: VkDeviceMemory,
|
||||
memoryOffset: VkDeviceSize) -> VkResult;
|
||||
memoryOffset: VkDeviceSize,
|
||||
) -> VkResult {
|
||||
let new_buffer = match *buffer.unwrap() {
|
||||
Buffer::Buffer(_) => panic!("An Buffer can only be bound once!"),
|
||||
Buffer::Unbound(unbound) => {
|
||||
gpu.device.bind_buffer_memory(
|
||||
&memory,
|
||||
memoryOffset,
|
||||
unbound,
|
||||
).unwrap() // TODO
|
||||
}
|
||||
};
|
||||
|
||||
// Replace the unbound buffer with an actual buffer under the hood.
|
||||
*buffer = Buffer::Buffer(new_buffer);
|
||||
|
||||
VkResult::VK_SUCCESS
|
||||
}
|
||||
#[inline]
|
||||
pub extern fn gfxBindImageMemory(
|
||||
|
@ -351,10 +386,23 @@ pub extern fn gfxBindImageMemory(
|
|||
|
||||
VkResult::VK_SUCCESS
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkGetBufferMemoryRequirements(device: VkDevice, buffer: VkBuffer,
|
||||
pMemoryRequirements:
|
||||
*mut VkMemoryRequirements);
|
||||
#[inline]
|
||||
pub extern fn gfxGetBufferMemoryRequirements(
|
||||
gpu: VkDevice,
|
||||
buffer: VkBuffer,
|
||||
pMemoryRequirements: *mut VkMemoryRequirements,
|
||||
) {
|
||||
let req = match *buffer.deref() {
|
||||
Buffer::Buffer(ref buffer) => unimplemented!(),
|
||||
Buffer::Unbound(ref buffer) => {
|
||||
gpu.device.get_buffer_requirements(buffer)
|
||||
}
|
||||
};
|
||||
|
||||
let memory_requirements = unsafe { &mut *pMemoryRequirements };
|
||||
memory_requirements.size = req.size;
|
||||
memory_requirements.alignment = req.alignment;
|
||||
memory_requirements.memoryTypeBits = req.type_mask as _;
|
||||
}
|
||||
#[inline]
|
||||
pub extern fn gfxGetImageMemoryRequirements(
|
||||
|
@ -479,9 +527,18 @@ extern "C" {
|
|||
pAllocator: *const VkAllocationCallbacks,
|
||||
pBuffer: *mut VkBuffer) -> VkResult;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkDestroyBuffer(device: VkDevice, buffer: VkBuffer,
|
||||
pAllocator: *const VkAllocationCallbacks);
|
||||
#[inline]
|
||||
pub extern fn gfxDestroyBuffer(
|
||||
gpu: VkDevice,
|
||||
buffer: VkBuffer,
|
||||
pAllocator: *const VkAllocationCallbacks,
|
||||
) {
|
||||
if !buffer.is_null() {
|
||||
match *buffer.unwrap() {
|
||||
Buffer::Buffer(buffer) => gpu.device.destroy_buffer(buffer),
|
||||
Buffer::Unbound(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkCreateBufferView(device: VkDevice,
|
||||
|
@ -515,9 +572,18 @@ pub extern fn gfxCreateImage(
|
|||
unsafe { *pImage = Handle::new(Image::Unbound(image)); }
|
||||
VkResult::VK_SUCCESS
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkDestroyImage(device: VkDevice, image: VkImage,
|
||||
pAllocator: *const VkAllocationCallbacks);
|
||||
#[inline]
|
||||
pub extern fn gfxDestroyImage(
|
||||
gpu: VkDevice,
|
||||
image: VkImage,
|
||||
pAllocator: *const VkAllocationCallbacks,
|
||||
) {
|
||||
if !image.is_null() {
|
||||
match *image.unwrap() {
|
||||
Image::Image(image) => gpu.device.destroy_image(image),
|
||||
Image::Unbound(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
pub fn vkGetImageSubresourceLayout(device: VkDevice, image: VkImage,
|
||||
|
|
|
@ -39,6 +39,13 @@ pub enum Image<B: hal::Backend> {
|
|||
pub type VkImage = Handle<Image<B>>;
|
||||
pub type VkImageView = Handle<<B as hal::Backend>::ImageView>;
|
||||
|
||||
pub enum Buffer<B: hal::Backend> {
|
||||
Buffer(B::Buffer),
|
||||
Unbound(B::UnboundBuffer),
|
||||
}
|
||||
|
||||
pub type VkBuffer = Handle<Buffer<B>>;
|
||||
|
||||
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with
|
||||
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
|
||||
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
|
||||
|
@ -514,13 +521,6 @@ pub struct VkFence_T {
|
|||
_unused: [u8; 0],
|
||||
}
|
||||
pub type VkFence = *mut VkFence_T;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct VkBuffer_T {
|
||||
_unused: [u8; 0],
|
||||
}
|
||||
pub type VkBuffer = *mut VkBuffer_T;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct VkEvent_T {
|
||||
|
|
|
@ -81,6 +81,15 @@ pub extern fn vkBindImageMemory(
|
|||
gfxBindImageMemory(device, image, memory, memoryOffset)
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern fn vkBindBufferMemory(
|
||||
device: VkDevice,
|
||||
buffer: VkBuffer,
|
||||
memory: VkDeviceMemory,
|
||||
memoryOffset: VkDeviceSize,
|
||||
) -> VkResult {
|
||||
gfxBindBufferMemory(device, buffer, memory, memoryOffset)
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern fn vkDestroyDevice(
|
||||
device: VkDevice,
|
||||
pAllocator: *const VkAllocationCallbacks,
|
||||
|
@ -261,3 +270,54 @@ pub extern fn vkCreateWin32SurfaceKHR(
|
|||
) -> VkResult {
|
||||
gfxCreateWin32SurfaceKHR(instance, pCreateInfos, pAllocator, pSurface)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn vkMapMemory(
|
||||
device: VkDevice,
|
||||
memory: VkDeviceMemory,
|
||||
offset: VkDeviceSize,
|
||||
size: VkDeviceSize,
|
||||
flags: VkMemoryMapFlags,
|
||||
ppData: *mut *mut ::std::os::raw::c_void,
|
||||
) -> VkResult {
|
||||
gfxMapMemory(
|
||||
device,
|
||||
memory,
|
||||
offset,
|
||||
size,
|
||||
flags,
|
||||
ppData,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn vkUnmapMemory(device: VkDevice, memory: VkDeviceMemory) {
|
||||
gfxUnmapMemory(device, memory)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn vkDestroyImage(
|
||||
device: VkDevice,
|
||||
image: VkImage,
|
||||
pAllocator: *const VkAllocationCallbacks,
|
||||
) {
|
||||
gfxDestroyImage(device, image, pAllocator)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn vkDestroyBuffer(
|
||||
device: VkDevice,
|
||||
buffer: VkBuffer,
|
||||
pAllocator: *const VkAllocationCallbacks,
|
||||
) {
|
||||
gfxDestroyBuffer(device, buffer, pAllocator)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn vkGetBufferMemoryRequirements(
|
||||
device: VkDevice,
|
||||
buffer: VkBuffer,
|
||||
pMemoryRequirements: *mut VkMemoryRequirements,
|
||||
) {
|
||||
gfxGetBufferMemoryRequirements(device, buffer, pMemoryRequirements)
|
||||
}
|
||||
|
|
|
@ -342,6 +342,56 @@ int main() {
|
|||
|
||||
auto mvp = clip * projection * view * model;
|
||||
|
||||
VkBuffer uniform_buf = 0;
|
||||
|
||||
VkBufferCreateInfo buf_info = {};
|
||||
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buf_info.pNext = NULL;
|
||||
buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
buf_info.size = sizeof(mvp);
|
||||
buf_info.queueFamilyIndexCount = 0;
|
||||
buf_info.pQueueFamilyIndices = NULL;
|
||||
buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
buf_info.flags = 0;
|
||||
res = vkCreateBuffer(device, &buf_info, NULL, &uniform_buf);
|
||||
printf("\tvkCreateBuffer: res=%d\n", res);
|
||||
assert(!res);
|
||||
|
||||
VkMemoryRequirements mem_reqs_uniform;
|
||||
vkGetBufferMemoryRequirements(device, uniform_buf, &mem_reqs_uniform);
|
||||
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.pNext = NULL;
|
||||
alloc_info.memoryTypeIndex = 0;
|
||||
|
||||
alloc_info.allocationSize = mem_reqs_uniform.size;
|
||||
pass = memory_type_from_properties(
|
||||
memory_properties,
|
||||
mem_reqs_uniform.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
&alloc_info.memoryTypeIndex);
|
||||
assert(pass && "No mappable, coherent memory");
|
||||
|
||||
VkDeviceMemory uniform_mem = 0;
|
||||
res = vkAllocateMemory(device, &alloc_info, NULL, &uniform_mem);
|
||||
printf("\tvkAllocateMemory: res=%d\n", res);
|
||||
assert(!res);
|
||||
|
||||
uint8_t *pData;
|
||||
res = vkMapMemory(device, uniform_mem, 0, mem_reqs_uniform.size, 0, (void **)&pData);
|
||||
printf("\tvkMapMemory: res=%d\n", res);
|
||||
assert(!res);
|
||||
|
||||
memcpy(pData, &mvp, sizeof(mvp));
|
||||
|
||||
vkUnmapMemory(device, uniform_mem);
|
||||
printf("\tvkUnmapMemory");
|
||||
|
||||
res = vkBindBufferMemory(device, uniform_buf, uniform_mem, 0);
|
||||
printf("\tvkBindBufferMemory: res=%d\n", res);
|
||||
assert(!res);
|
||||
|
||||
VkCommandPool cmd_pool = 0;
|
||||
VkCommandPoolCreateInfo cmd_pool_info = {};
|
||||
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
|
@ -370,12 +420,17 @@ int main() {
|
|||
|
||||
}
|
||||
|
||||
// TODO: destroy depth image
|
||||
|
||||
vkFreeMemory(device, depth_memory, NULL);
|
||||
vkDestroyBuffer(device, uniform_buf, NULL);
|
||||
printf("\tvkDestroyBuffer\n");
|
||||
vkFreeMemory(device, uniform_mem, NULL);
|
||||
printf("\tvkFreeMemory\n");
|
||||
|
||||
vkDestroyImageView(device, depth_view, NULL);
|
||||
printf("\tvkDestroyImageView\n");
|
||||
vkDestroyImage(device, depth_image, NULL);
|
||||
printf("\tvkDestroyImage\n");
|
||||
vkFreeMemory(device, depth_memory, NULL);
|
||||
printf("\tvkFreeMemory\n");
|
||||
|
||||
for(auto view : swapchain_views) {
|
||||
vkDestroyImageView(device, view, NULL);
|
||||
|
|
Loading…
Reference in a new issue