diff --git a/CMakeLists.txt b/CMakeLists.txt index 3046ee6..a6435e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,21 @@ project (portability) include_directories("modules/vulkan-docs/src") add_executable(native_test native/test.cpp native/window.cpp) -find_library(PORTABILITY_LIB portability "target/debug") -target_link_libraries(native_test ${PORTABILITY_LIB}) - +# That's quite a mess, cleanup if possible.. if (WIN32) + # TODO: can we use `find_library`? It seemed to search for `portability.lib` always.. + target_link_libraries(native_test "../target/debug/portability.dll") target_link_libraries(native_test Dwmapi Userenv ws2_32) + + # Copy dll over to build directory + add_custom_command(TARGET native_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${PROJECT_SOURCE_DIR}/target/debug/portability.dll" + $) + else (WIN32) + find_library(PORTABILITY_LIB portability "target/debug") + target_link_libraries(native_test ${PORTABILITY_LIB}) target_link_libraries(native_test pthread dl m X11 xcb) + endif (WIN32) diff --git a/libportability-gfx/src/conv.rs b/libportability-gfx/src/conv.rs index 24d5416..cbe4e5a 100644 --- a/libportability-gfx/src/conv.rs +++ b/libportability-gfx/src/conv.rs @@ -1,42 +1,13 @@ + +use hal::{adapter, format, image, memory, window}; + +use std::mem; + use super::*; -use hal::{self, format, image, memory, window}; pub fn format_from_hal(format: format::Format) -> VkFormat { - use VkFormat::*; - use hal::format::ChannelType::*; - use hal::format::SurfaceType::*; - - match format.0 { - R5_G6_B5 => match format.1 { - Unorm => VK_FORMAT_R5G6B5_UNORM_PACK16, - _ => unreachable!(), - }, - R4_G4_B4_A4 => match format.1 { - Unorm => VK_FORMAT_R4G4B4A4_UNORM_PACK16, - _ => unreachable!(), - }, - R8_G8_B8_A8 => match format.1 { - Unorm => VK_FORMAT_R8G8B8A8_UNORM, - Inorm => VK_FORMAT_R8G8B8A8_SNORM, - Srgb => VK_FORMAT_R8G8B8A8_SRGB, - _ => panic!("format {:?}", format), - }, - B8_G8_R8_A8 => match format.1 { - Unorm => VK_FORMAT_B8G8R8A8_UNORM, - Inorm => VK_FORMAT_B8G8R8A8_SNORM, - Srgb => VK_FORMAT_B8G8R8A8_SRGB, - _ => panic!("format {:?}", format), - }, - R16_G16_B16_A16 => match format.1 { - Unorm => VK_FORMAT_R16G16B16A16_UNORM, - Inorm => VK_FORMAT_R16G16B16A16_SNORM, - Float => VK_FORMAT_R16G16B16A16_SFLOAT, - _ => panic!("format {:?}", format), - }, - _ => { - panic!("format {:?}", format); - } - } + // HAL formats have the same numeric representation as Vulkan formats + unsafe { mem::transmute(format) } } pub fn format_properties_from_hal(properties: format::Properties) -> VkFormatProperties { @@ -101,19 +72,12 @@ fn buffer_features_from_hal(features: format::BufferFeature) -> VkFormatFeatureF } pub fn map_format(format: VkFormat) -> format::Format { - use VkFormat::*; - use hal::format::ChannelType::*; - use hal::format::SurfaceType::*; - - let (sf, cf) = match format { - VK_FORMAT_B8G8R8A8_UNORM => (B8_G8_R8_A8, Unorm), - VK_FORMAT_D16_UNORM => (D16, Unorm), - _ => { - panic!("format {:?}", format); - } - }; - - format::Format(sf, cf) + if (format as usize) < format::NUM_FORMATS { + // HAL formats have the same numeric representation as Vulkan formats + unsafe { mem::transmute(format) } + } else { + unimplemented!("Unknown format {:?}", format); + } } pub fn extent2d_from_hal(extent: window::Extent2d) -> VkExtent2D { @@ -158,16 +122,16 @@ pub fn map_subresource_range(subresource: VkImageSubresourceRange) -> image::Sub } } -fn map_aspect(aspects: VkImageAspectFlags) -> image::AspectFlags { - let mut flags = image::AspectFlags::empty(); +fn map_aspect(aspects: VkImageAspectFlags) -> format::AspectFlags { + let mut flags = format::AspectFlags::empty(); if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT as u32 != 0 { - flags |= image::AspectFlags::COLOR; + flags |= format::AspectFlags::COLOR; } if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_DEPTH_BIT as u32 != 0 { - flags |= image::AspectFlags::DEPTH; + flags |= format::AspectFlags::DEPTH; } if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_STENCIL_BIT as u32 != 0 { - flags |= image::AspectFlags::DEPTH; + flags |= format::AspectFlags::DEPTH; } if aspects & VkImageAspectFlagBits::VK_IMAGE_ASPECT_METADATA_BIT as u32 != 0 { unimplemented!() @@ -278,3 +242,17 @@ pub fn memory_properties_from_hal(properties: memory::Properties) -> VkMemoryPro flags } + +pub fn map_err_device_creation(err: adapter::DeviceCreationError) -> VkResult { + use hal::adapter::DeviceCreationError::*; + + match err { + OutOfHostMemory => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY, + OutOfDeviceMemory => VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY, + InitializationFailed => VkResult::VK_ERROR_INITIALIZATION_FAILED, + MissingExtension => VkResult::VK_ERROR_EXTENSION_NOT_PRESENT, + MissingFeature => VkResult::VK_ERROR_FEATURE_NOT_PRESENT, + TooManyObjects => VkResult::VK_ERROR_TOO_MANY_OBJECTS, + DeviceLost => VkResult::VK_ERROR_DEVICE_LOST, + } +} diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 28253e3..07dbe3e 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,8 +1,11 @@ -use super::*; +use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; + use std::mem; use std::ops::Deref; +use super::*; + #[inline] pub extern fn gfxCreateInstance( _pCreateInfo: *const VkInstanceCreateInfo, @@ -80,7 +83,12 @@ pub extern fn gfxGetPhysicalDeviceFormatProperties( format: VkFormat, pFormatProperties: *mut VkFormatProperties, ) { - let properties = adapter.physical_device.format_properties(conv::map_format(format)); + let format = match format { + VkFormat::VK_FORMAT_UNDEFINED => None, + format => Some(conv::map_format(format)), + }; + + let properties = adapter.physical_device.format_properties(format); unsafe { *pFormatProperties = conv::format_properties_from_hal(properties); } } extern "C" { @@ -157,9 +165,14 @@ pub extern fn gfxCreateDevice( }).collect::>(); let gpu = adapter.physical_device.open(request_infos); - unsafe { *pDevice = Handle::new(gpu) }; - VkResult::VK_SUCCESS + match gpu { + Ok(device) => { + unsafe { *pDevice = Handle::new(device); } + VkResult::VK_SUCCESS + } + Err(err) => conv::map_err_device_creation(err), + } } #[inline] @@ -1132,17 +1145,31 @@ pub extern fn gfxGetPhysicalDeviceSurfaceFormatsKHR( pSurfaceFormatCount: *mut u32, pSurfaceFormats: *mut VkSurfaceFormatKHR, ) -> VkResult { - let (_, formats) = surface.capabilities_and_formats(&adapter.physical_device); - let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; + let formats = surface + .capabilities_and_formats(&adapter.physical_device) + .1 + .map(|formats| + formats + .into_iter() + .map(conv::format_from_hal) + .collect() + ) + .unwrap_or(vec![VkFormat::VK_FORMAT_UNDEFINED]); - if output.len() > formats.len() { + if pSurfaceFormats.is_null() { + // Return only the number of formats unsafe { *pSurfaceFormatCount = formats.len() as u32 }; - } - for (out, format) in output.iter_mut().zip(formats) { - *out = VkSurfaceFormatKHR { - format: conv::format_from_hal(format), - colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO - }; + } else { + let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; + if output.len() > formats.len() { + unsafe { *pSurfaceFormatCount = formats.len() as u32 }; + } + for (out, format) in output.iter_mut().zip(formats) { + *out = VkSurfaceFormatKHR { + format, + colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO + }; + } } VkResult::VK_SUCCESS diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index 9513303..0bb0f9b 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -17,7 +17,6 @@ mod handle; mod impls; use std::{cmp, slice}; -use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; // traits only use hal::pool::RawCommandPool; use back::Backend as B; use handle::Handle; diff --git a/native/test.cpp b/native/test.cpp index 63059da..6430ddc 100644 --- a/native/test.cpp +++ b/native/test.cpp @@ -193,12 +193,12 @@ int main() { uint32_t image_count = 0; res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, NULL); - printf("\tvkCreateSwapchainKHR (query): res=%d image_count=%d\n", res, image_count); + printf("\tvkGetSwapchainImagesKHR (query): res=%d image_count=%d\n", res, image_count); assert(!res); std::vector swapchain_images(image_count); res = vkGetSwapchainImagesKHR(device, swapchain, &image_count, &swapchain_images[0]); - printf("\tvkCreateSwapchainKHR: res=%d\n", res); + printf("\tvkGetSwapchainImagesKHR: res=%d\n", res); assert(!res); std::vector swapchain_views(image_count);