diff --git a/Cargo.toml b/Cargo.toml index 3781c40..f2ab380 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,4 @@ branch = "portability" #path = "../gfx/src/backend/vulkan" git = "https://github.com/kvark/gfx-rs" branch = "portability" -features = ["portable"] +#features = ["portable"] diff --git a/Makefile b/Makefile index 21f1f05..11d66ef 100644 --- a/Makefile +++ b/Makefile @@ -10,12 +10,16 @@ CFLAGS=-I$(VULKAN_DIR) DEPS= LDFLAGS=-lpthread -ldl -lm +.PHONY: all binding run + all: $(TARGET) +binding: $(BINDING) + $(BINDING): $(VULKAN_DIR)/vulkan/*.h bindgen --no-layout-tests --rustfmt-bindings $(VULKAN_DIR)/vulkan/vulkan.h -o $(BINDING) -$(LIBRARY): $(BINDING) src/*.rs +$(LIBRARY): src/*.rs cargo build mkdir -p target/native diff --git a/README.md b/README.md index 846f18b..b361393 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ ## gfx-portability [![Build Status](https://travis-ci.org/kvark/portability.svg?branch=master)](https://travis-ci.org/kvark/portability) -This is a prototype static library implementing [Vulkan Portability Initiative](https://www.khronos.org/blog/khronos-announces-the-vulkan-portability-initiative) using gfx-rs [low-level core](http://gfx-rs.github.io/2017/07/24/low-level.html). See [gfx-rs meta issue](https://github.com/gfx-rs/gfx/issues/1354) for backend limitations and further details. +This is a prototype static library implementing [Vulkan Portability Initiative](https://www.khronos.org/blog/khronos-announces-the-vulkan-portability-initiative) using gfx-rs [low-level core](http://gfx-rs.github.io/2017/07/24/low-level.html). See gfx-rs [meta issue](https://github.com/gfx-rs/gfx/issues/1354) for backend limitations and further details. diff --git a/native/test.c b/native/test.c index 6594cf3..6abe528 100644 --- a/native/test.c +++ b/native/test.c @@ -20,12 +20,48 @@ int main() { return -1; } - uint32_t gpu_count = 1; + uint32_t adapter_count = 1; VkPhysicalDevice physical_devices[1] = {}; - res = vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices); - printf("\tvkEnumeratePhysicalDevices: res=%d count=%d\n", res, gpu_count); - assert(!res && gpu_count); + res = vkEnumeratePhysicalDevices(instance, &adapter_count, physical_devices); + printf("\tvkEnumeratePhysicalDevices: res=%d count=%d\n", res, adapter_count); + assert(!res && adapter_count); + VkQueueFamilyProperties queue_family_properties[5]; + uint32_t queue_family_count = sizeof(queue_family_properties) / sizeof(VkQueueFamilyProperties); + + vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[0], &queue_family_count, queue_family_properties); + printf("\tvkGetPhysicalDeviceQueueFamilyProperties: count=%d\n", queue_family_count); + assert(queue_family_count); + + int queue_family_index = -1; + for (unsigned int i = 0; i < queue_family_count; i++) { + if (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + queue_family_index = i; + break; + } + } + printf("\tusing queue family index %d\n", queue_family_index); + assert(queue_family_index >= 0); + + VkDeviceQueueCreateInfo queue_info = {}; + float queue_priorities[1] = {0.0}; + queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info.queueCount = 1; + queue_info.pQueuePriorities = queue_priorities; + + VkDeviceCreateInfo device_info = {}; + device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device_info.queueCreateInfoCount = 1; + device_info.pQueueCreateInfos = &queue_info; + + VkDevice device = 0; + res = vkCreateDevice(physical_devices[0], &device_info, NULL, &device); + printf("\tvkCreateDevice: res=%d\n", res); + assert(!res); + + //TODO + + vkDestroyDevice(device, NULL); vkDestroyInstance(instance, NULL); printf("done.\n"); diff --git a/src/lib.rs b/src/lib.rs index 7a490bf..eb24807 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ extern crate gfx_backend_vulkan as back; mod handle; use std::{cmp, slice}; -use core::Instance; +use core::{Adapter, Instance, QueueFamily}; // traits only use back::Backend as B; use handle::Handle; @@ -460,13 +460,8 @@ pub type VkSampleMask = u32; pub type VkInstance = Handle; pub type VkPhysicalDevice = Handle<::Adapter>; +pub type VkDevice = Handle>; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct VkDevice_T { - _unused: [u8; 0], -} -pub type VkDevice = *mut VkDevice_T; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct VkQueue_T { @@ -4372,14 +4367,35 @@ extern "C" { pProperties: *mut VkPhysicalDeviceProperties); } -extern "C" { - pub fn vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice: - VkPhysicalDevice, - pQueueFamilyPropertyCount: - *mut u32, - pQueueFamilyProperties: - *mut VkQueueFamilyProperties); + +#[no_mangle] +pub extern fn vkGetPhysicalDeviceQueueFamilyProperties( + physicalDevice: VkPhysicalDevice, + pQueueFamilyPropertyCount: *mut u32, + pQueueFamilyProperties: *mut VkQueueFamilyProperties, +) { + let output = unsafe { + slice::from_raw_parts_mut(pQueueFamilyProperties, *pQueueFamilyPropertyCount as _) + }; + let families = physicalDevice.get_queue_families(); + if output.len() > families.len() { + unsafe { *pQueueFamilyPropertyCount = families.len() as _ }; + } + for (ref mut out, &(ref family, ty)) in output.iter_mut().zip(families.iter()) { + **out = VkQueueFamilyProperties { + queueFlags: match ty { + core::QueueType::General => VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT as u32 | VkQueueFlagBits::VK_QUEUE_COMPUTE_BIT as u32, + core::QueueType::Graphics => VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT as u32, + core::QueueType::Compute => VkQueueFlagBits::VK_QUEUE_COMPUTE_BIT as u32, + core::QueueType::Transfer => VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT as u32, + }, + queueCount: family.num_queues(), + timestampValidBits: 0, //TODO + minImageTransferGranularity: VkExtent3D { width: 0, height: 0, depth: 0 }, //TODO + } + } } + extern "C" { pub fn vkGetPhysicalDeviceMemoryProperties(physicalDevice: VkPhysicalDevice, @@ -4396,16 +4412,38 @@ extern "C" { pName: *const ::std::os::raw::c_char) -> PFN_vkVoidFunction; } -extern "C" { - pub fn vkCreateDevice(physicalDevice: VkPhysicalDevice, - pCreateInfo: *const VkDeviceCreateInfo, - pAllocator: *const VkAllocationCallbacks, - pDevice: *mut VkDevice) -> VkResult; + +#[no_mangle] +pub extern fn vkCreateDevice( + physicalDevice: VkPhysicalDevice, + pCreateInfo: *const VkDeviceCreateInfo, + _pAllocator: *const VkAllocationCallbacks, + pDevice: *mut VkDevice, +) -> VkResult { + let dev_info = unsafe { &*pCreateInfo }; + let queue_infos = unsafe { + slice::from_raw_parts(dev_info.pQueueCreateInfos, dev_info.queueCreateInfoCount as _) + }; + let families = physicalDevice.get_queue_families(); + let request_infos = queue_infos.iter().map(|info| { + let (ref family, ty) = families[info.queueFamilyIndex as usize]; + (family, ty, info.queueCount) + }).collect::>(); + + let gpu = physicalDevice.open(&request_infos); + unsafe { *pDevice = Handle::new(gpu) }; + + VkResult::VK_SUCCESS } -extern "C" { - pub fn vkDestroyDevice(device: VkDevice, - pAllocator: *const VkAllocationCallbacks); + +#[no_mangle] +pub extern fn vkDestroyDevice( + device: VkDevice, + _pAllocator: *const VkAllocationCallbacks, +) { + let _ = device.unwrap(); //TODO? } + extern "C" { pub fn vkEnumerateInstanceExtensionProperties(pLayerName: *const ::std::os::raw::c_char,