mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-22 23:11:30 +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};
|
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> {
|
||||||
|
|
|
@ -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!()
|
||||||
}
|
}
|
||||||
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" {
|
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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue