Implement vkMapMemory, vkUnmapMemory, vkBindBufferMemory, vkGetBufferMemoryRequirements, vkDestroyBuffer and vkDestroyImage

This commit is contained in:
msiglreith 2018-01-04 01:37:07 +01:00
parent 092c522b8e
commit 728e338ffa
5 changed files with 217 additions and 31 deletions

View file

@ -1,3 +1,4 @@
use VK_NULL_HANDLE;
use std::{fmt, ops}; use std::{fmt, ops};
@ -13,6 +14,10 @@ impl<T> Handle<T> {
pub fn unwrap(self) -> Box<T> { pub fn unwrap(self) -> Box<T> {
unsafe { Box::from_raw(self.0) } 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> { impl<T> Clone for Handle<T> {

View file

@ -295,14 +295,31 @@ pub extern fn gfxFreeMemory(
) { ) {
gpu.device.free_memory(*memory.unwrap()); gpu.device.free_memory(*memory.unwrap());
} }
extern "C" { #[inline]
pub fn vkMapMemory(device: VkDevice, memory: VkDeviceMemory, pub extern fn gfxMapMemory(
offset: VkDeviceSize, size: VkDeviceSize, gpu: VkDevice,
flags: VkMemoryMapFlags, memory: VkDeviceMemory,
ppData: *mut *mut ::std::os::raw::c_void) -> VkResult; offset: VkDeviceSize,
size: VkDeviceSize,
_flags: VkMemoryMapFlags,
ppData: *mut *mut ::std::os::raw::c_void,
) -> VkResult {
if size == VK_WHOLE_SIZE as VkDeviceSize {
unimplemented!()
}
unsafe {
*ppData = gpu
.device
.map_memory(&memory, offset..offset+size)
.unwrap() as *mut _; // TODO
}
VkResult::VK_SUCCESS
} }
extern "C" { #[inline]
pub fn vkUnmapMemory(device: VkDevice, memory: VkDeviceMemory); pub extern fn gfxUnmapMemory(gpu: VkDevice, memory: VkDeviceMemory) {
gpu.device.unmap_memory(&memory);
} }
extern "C" { extern "C" {
pub fn vkFlushMappedMemoryRanges(device: VkDevice, memoryRangeCount: u32, pub fn vkFlushMappedMemoryRanges(device: VkDevice, memoryRangeCount: u32,
@ -323,10 +340,28 @@ extern "C" {
pCommittedMemoryInBytes: pCommittedMemoryInBytes:
*mut VkDeviceSize); *mut VkDeviceSize);
} }
extern "C" { #[inline]
pub fn vkBindBufferMemory(device: VkDevice, buffer: VkBuffer, pub extern fn gfxBindBufferMemory(
gpu: VkDevice,
mut buffer: VkBuffer,
memory: VkDeviceMemory, 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] #[inline]
pub extern fn gfxBindImageMemory( pub extern fn gfxBindImageMemory(
@ -351,10 +386,23 @@ pub extern fn gfxBindImageMemory(
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
extern "C" { #[inline]
pub fn vkGetBufferMemoryRequirements(device: VkDevice, buffer: VkBuffer, pub extern fn gfxGetBufferMemoryRequirements(
pMemoryRequirements: gpu: VkDevice,
*mut VkMemoryRequirements); 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] #[inline]
pub extern fn gfxGetImageMemoryRequirements( pub extern fn gfxGetImageMemoryRequirements(
@ -479,9 +527,18 @@ extern "C" {
pAllocator: *const VkAllocationCallbacks, pAllocator: *const VkAllocationCallbacks,
pBuffer: *mut VkBuffer) -> VkResult; pBuffer: *mut VkBuffer) -> VkResult;
} }
extern "C" { #[inline]
pub fn vkDestroyBuffer(device: VkDevice, buffer: VkBuffer, pub extern fn gfxDestroyBuffer(
pAllocator: *const VkAllocationCallbacks); 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" { extern "C" {
pub fn vkCreateBufferView(device: VkDevice, pub fn vkCreateBufferView(device: VkDevice,
@ -515,9 +572,18 @@ pub extern fn gfxCreateImage(
unsafe { *pImage = Handle::new(Image::Unbound(image)); } unsafe { *pImage = Handle::new(Image::Unbound(image)); }
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
extern "C" { #[inline]
pub fn vkDestroyImage(device: VkDevice, image: VkImage, pub extern fn gfxDestroyImage(
pAllocator: *const VkAllocationCallbacks); 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" { extern "C" {
pub fn vkGetImageSubresourceLayout(device: VkDevice, image: VkImage, pub fn vkGetImageSubresourceLayout(device: VkDevice, image: VkImage,

View file

@ -39,6 +39,13 @@ pub enum Image<B: hal::Backend> {
pub type VkImage = Handle<Image<B>>; pub type VkImage = Handle<Image<B>>;
pub type VkImageView = Handle<<B as hal::Backend>::ImageView>; 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 //NOTE: all *KHR types have to be pure `Handle` things for compatibility with
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h` //`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>; pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
@ -514,13 +521,6 @@ pub struct VkFence_T {
_unused: [u8; 0], _unused: [u8; 0],
} }
pub type VkFence = *mut VkFence_T; 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)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VkEvent_T { pub struct VkEvent_T {

View file

@ -81,6 +81,15 @@ pub extern fn vkBindImageMemory(
gfxBindImageMemory(device, image, memory, memoryOffset) gfxBindImageMemory(device, image, memory, memoryOffset)
} }
#[no_mangle] #[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( pub extern fn vkDestroyDevice(
device: VkDevice, device: VkDevice,
pAllocator: *const VkAllocationCallbacks, pAllocator: *const VkAllocationCallbacks,
@ -261,3 +270,54 @@ pub extern fn vkCreateWin32SurfaceKHR(
) -> VkResult { ) -> VkResult {
gfxCreateWin32SurfaceKHR(instance, pCreateInfos, pAllocator, pSurface) 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)
}

View file

@ -342,6 +342,56 @@ int main() {
auto mvp = clip * projection * view * model; 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; VkCommandPool cmd_pool = 0;
VkCommandPoolCreateInfo cmd_pool_info = {}; VkCommandPoolCreateInfo cmd_pool_info = {};
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@ -370,12 +420,17 @@ int main() {
} }
// TODO: destroy depth image vkDestroyBuffer(device, uniform_buf, NULL);
printf("\tvkDestroyBuffer\n");
vkFreeMemory(device, depth_memory, NULL); vkFreeMemory(device, uniform_mem, NULL);
printf("\tvkFreeMemory\n"); printf("\tvkFreeMemory\n");
vkDestroyImageView(device, depth_view, NULL); vkDestroyImageView(device, depth_view, NULL);
printf("\tvkDestroyImageView\n"); printf("\tvkDestroyImageView\n");
vkDestroyImage(device, depth_image, NULL);
printf("\tvkDestroyImage\n");
vkFreeMemory(device, depth_memory, NULL);
printf("\tvkFreeMemory\n");
for(auto view : swapchain_views) { for(auto view : swapchain_views) {
vkDestroyImageView(device, view, NULL); vkDestroyImageView(device, view, NULL);