diff --git a/libportability-gfx/src/conv.rs b/libportability-gfx/src/conv.rs index c003d9d..24d5416 100644 --- a/libportability-gfx/src/conv.rs +++ b/libportability-gfx/src/conv.rs @@ -1,5 +1,5 @@ use super::*; -use hal::{format, image, window}; +use hal::{self, format, image, memory, window}; pub fn format_from_hal(format: format::Format) -> VkFormat { use VkFormat::*; @@ -256,3 +256,25 @@ pub fn map_image_usage(usage: VkImageUsageFlags) -> image::Usage { flags } + +pub fn memory_properties_from_hal(properties: memory::Properties) -> VkMemoryPropertyFlags { + let mut flags = 0; + + if properties.contains(memory::Properties::DEVICE_LOCAL) { + flags |= VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT as u32; + } + if properties.contains(memory::Properties::COHERENT) { + flags |= VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT as u32; + } + if properties.contains(memory::Properties::CPU_VISIBLE) { + flags |= VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT as u32; + } + if properties.contains(memory::Properties::CPU_CACHED) { + flags |= VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_HOST_CACHED_BIT as u32; + } + if properties.contains(memory::Properties::LAZILY_ALLOCATED) { + flags |= VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT as u32; + } + + flags +} diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 1cc49be..37f0555 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -100,12 +100,32 @@ extern "C" { pProperties: *mut VkPhysicalDeviceProperties); } +#[inline] +pub extern fn gfxGetPhysicalDeviceMemoryProperties( + adapter: VkPhysicalDevice, + pMemoryProperties: *mut VkPhysicalDeviceMemoryProperties, +) { + let properties = adapter.physical_device.memory_properties(); + let memory_properties = unsafe { &mut *pMemoryProperties }; -extern "C" { - pub fn vkGetPhysicalDeviceMemoryProperties(physicalDevice: - VkPhysicalDevice, - pMemoryProperties: - *mut VkPhysicalDeviceMemoryProperties); + let num_types = properties.memory_types.len(); + memory_properties.memoryTypeCount = num_types as _; + for i in 0..num_types { + let flags = conv::memory_properties_from_hal(properties.memory_types[i].properties); + memory_properties.memoryTypes[i] = VkMemoryType { + propertyFlags: flags, // propertyFlags + heapIndex: properties.memory_types[i].heap_index as _, + }; + } + + let num_heaps = properties.memory_heaps.len(); + memory_properties.memoryHeapCount = num_heaps as _; + for i in 0..num_heaps { + memory_properties.memoryHeaps[i] = VkMemoryHeap { + size: properties.memory_heaps[i], + flags: 0, // TODO + }; + } } extern "C" { pub fn vkGetInstanceProcAddr(instance: VkInstance, @@ -235,11 +255,14 @@ extern "C" { extern "C" { pub fn vkDeviceWaitIdle(device: VkDevice) -> VkResult; } -extern "C" { - pub fn vkAllocateMemory(device: VkDevice, - pAllocateInfo: *const VkMemoryAllocateInfo, - pAllocator: *const VkAllocationCallbacks, - pMemory: *mut VkDeviceMemory) -> VkResult; +#[inline] +pub extern fn gfxAllocateMemory( + gpu: VkDevice, + pAllocateInfo: *const VkMemoryAllocateInfo, + _pAllocator: *const VkAllocationCallbacks, + pMemory: *mut VkDeviceMemory, +) -> VkResult { + unimplemented!() } extern "C" { pub fn vkFreeMemory(device: VkDevice, memory: VkDeviceMemory, @@ -278,10 +301,14 @@ extern "C" { memory: VkDeviceMemory, memoryOffset: VkDeviceSize) -> VkResult; } -extern "C" { - pub fn vkBindImageMemory(device: VkDevice, image: VkImage, - memory: VkDeviceMemory, - memoryOffset: VkDeviceSize) -> VkResult; +#[inline] +pub extern fn gfxBindImageMemory( + device: VkDevice, + image: VkImage, + memory: VkDeviceMemory, + memoryOffset: VkDeviceSize, +) -> VkResult { + unimplemented!() } extern "C" { pub fn vkGetBufferMemoryRequirements(device: VkDevice, buffer: VkBuffer, diff --git a/libportability/src/lib.rs b/libportability/src/lib.rs index 95fd57b..15a37ac 100644 --- a/libportability/src/lib.rs +++ b/libportability/src/lib.rs @@ -38,7 +38,13 @@ pub extern fn vkGetPhysicalDeviceQueueFamilyProperties( ) { gfxGetPhysicalDeviceQueueFamilyProperties(adapter, pQueueFamilyPropertyCount, pQueueFamilyProperties) } - +#[no_mangle] +pub extern fn vkGetPhysicalDeviceMemoryProperties( + physicalDevice: VkPhysicalDevice, + pMemoryProperties: *mut VkPhysicalDeviceMemoryProperties, +) { + gfxGetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties) +} #[no_mangle] pub extern fn vkCreateDevice( adapter: VkPhysicalDevice, @@ -48,7 +54,24 @@ pub extern fn vkCreateDevice( ) -> VkResult { gfxCreateDevice(adapter, pCreateInfo, pAllocator, pDevice) } - +#[no_mangle] +pub extern fn vkAllocateMemory( + device: VkDevice, + pAllocateInfo: *const VkMemoryAllocateInfo, + pAllocator: *const VkAllocationCallbacks, + pMemory: *mut VkDeviceMemory, +) -> VkResult { + gfxAllocateMemory(device, pAllocateInfo, pAllocator, pMemory) +} +#[no_mangle] +pub extern fn vkBindImageMemory( + device: VkDevice, + image: VkImage, + memory: VkDeviceMemory, + memoryOffset: VkDeviceSize, +) -> VkResult { + gfxBindImageMemory(device, image, memory, memoryOffset) +} #[no_mangle] pub extern fn vkDestroyDevice( device: VkDevice, diff --git a/native/test.cpp b/native/test.cpp index e6ada73..a5beb93 100644 --- a/native/test.cpp +++ b/native/test.cpp @@ -30,6 +30,27 @@ #include #include "window.hpp" +bool memory_type_from_properties( + const VkPhysicalDeviceMemoryProperties &memory_properties, + uint32_t type_bits, + const VkFlags requirements_mask, + uint32_t *type_index) +{ + // Search memtypes to find first index with those properties + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) { + if ((type_bits & 1) == 1) { + // Type is available, does it match user properties? + if ((memory_properties.memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask) { + *type_index = i; + return true; + } + } + type_bits >>= 1; + } + // No memory types matched, return failure + return false; +} + int main() { printf("starting the portability test\n"); @@ -91,6 +112,10 @@ int main() { printf("\tusing queue family index %d\n", queue_family_index); assert(queue_family_index >= 0); + VkPhysicalDeviceMemoryProperties memory_properties = {}; + vkGetPhysicalDeviceMemoryProperties(physical_devices[0], &memory_properties); + printf("\tvkGetPhysicalDeviceMemoryProperties\n"); + VkDeviceQueueCreateInfo queue_info = {}; float queue_priorities[1] = {0.0}; queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -278,6 +303,14 @@ int main() { mem_reqs.alignment, mem_reqs.memoryTypeBits); + mem_alloc.allocationSize = mem_reqs.size; + bool pass = memory_type_from_properties( + memory_properties, + mem_reqs.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &mem_alloc.memoryTypeIndex); + assert(pass); + VkCommandPool cmd_pool = 0; VkCommandPoolCreateInfo cmd_pool_info = {}; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;