diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 9cc61b1..95b9233 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -14,13 +14,11 @@ use hal::{ use std::{ borrow::Cow, ffi::{CStr, CString}, - os::raw::c_int, + os::raw::{c_int, c_void}, mem, ptr, str, }; #[cfg(feature = "gfx-backend-metal")] use std::env; -#[cfg(feature = "renderdoc")] -use std::os::raw::c_void; use super::*; @@ -64,6 +62,16 @@ pub extern "C" fn gfxCreateInstance( #[cfg(feature = "env_logger")] { let _ = env_logger::try_init(); + let backend = if cfg!(feature = "gfx-backend-vulkan") { + "Vulkan" + } else if cfg!(feature = "gfx-backend-dx12") { + "DX12" + } else if cfg!(feature = "gfx-backend-metal") { + "Metal" + } else { + "Other" + }; + println!("gfx-portability backend: {}", backend); } #[allow(unused_mut)] @@ -275,7 +283,7 @@ pub extern "C" fn gfxGetPhysicalDeviceFeatures2KHR( other => { warn!("Unrecognized {:?}, skipping", other); unsafe { - (ptr as *const VkPhysicalDeviceFeatures2KHR) + (ptr as *const VkBaseStruct) .as_ref() .unwrap() } @@ -385,7 +393,7 @@ pub extern "C" fn gfxGetPhysicalDeviceImageFormatProperties2KHR( other => { warn!("Unrecognized {:?}, skipping", other); unsafe { - (ptr as *const VkPhysicalDeviceImageFormatInfo2KHR) + (ptr as *const VkBaseStruct) .as_ref() .unwrap() } @@ -470,7 +478,7 @@ pub extern "C" fn gfxGetPhysicalDeviceProperties2KHR( other => { warn!("Unrecognized {:?}, skipping", other); unsafe { - (ptr as *const VkPhysicalDeviceProperties2KHR).as_ref().unwrap() + (ptr as *const VkBaseStruct).as_ref().unwrap() }.pNext } } as *const VkStructureType; @@ -544,7 +552,9 @@ pub extern "C" fn gfxGetInstanceProcAddr( vkGetPhysicalDeviceSurfaceSupportKHR, PFN_vkGetPhysicalDeviceSurfaceSupportKHR => gfxGetPhysicalDeviceSurfaceSupportKHR, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR => gfxGetPhysicalDeviceSurfaceCapabilitiesKHR, + vkGetPhysicalDeviceSurfaceCapabilities2KHR, PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR => gfxGetPhysicalDeviceSurfaceCapabilities2KHR, vkGetPhysicalDeviceSurfaceFormatsKHR, PFN_vkGetPhysicalDeviceSurfaceFormatsKHR => gfxGetPhysicalDeviceSurfaceFormatsKHR, + vkGetPhysicalDeviceSurfaceFormats2KHR, PFN_vkGetPhysicalDeviceSurfaceFormats2KHR => gfxGetPhysicalDeviceSurfaceFormats2KHR, vkGetPhysicalDeviceSurfacePresentModesKHR, PFN_vkGetPhysicalDeviceSurfacePresentModesKHR => gfxGetPhysicalDeviceSurfacePresentModesKHR, vkGetPhysicalDeviceWin32PresentationSupportKHR, PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR => gfxGetPhysicalDeviceWin32PresentationSupportKHR, @@ -961,6 +971,7 @@ lazy_static! { #[cfg(target_os="macos")] VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, ] }; @@ -1272,7 +1283,7 @@ pub extern "C" fn gfxMapMemory( offset: VkDeviceSize, size: VkDeviceSize, _flags: VkMemoryMapFlags, - ppData: *mut *mut ::std::os::raw::c_void, + ppData: *mut *mut c_void, ) -> VkResult { let range = hal::memory::Segment { offset, @@ -1422,7 +1433,7 @@ pub extern "C" fn gfxGetImageMemoryRequirements2KHR( other => { warn!("Unrecognized {:?}, skipping", other); unsafe { - (ptr as *const VkMemoryRequirements2KHR).as_ref().unwrap() + (ptr as *const VkBaseStruct).as_ref().unwrap() }.pNext } } as *const VkStructureType; @@ -1691,7 +1702,7 @@ pub extern "C" fn gfxGetQueryPoolResults( firstQuery: u32, queryCount: u32, dataSize: usize, - pData: *mut ::std::os::raw::c_void, + pData: *mut c_void, stride: VkDeviceSize, flags: VkQueryResultFlags, ) -> VkResult { @@ -1988,7 +1999,7 @@ pub extern "C" fn gfxGetPipelineCacheData( _gpu: VkDevice, _pipelineCache: VkPipelineCache, pDataSize: *mut usize, - _pData: *mut ::std::os::raw::c_void, + _pData: *mut c_void, ) -> VkResult { //TODO: save unsafe { @@ -2982,11 +2993,22 @@ impl<'a> Iterator for DescriptorIter<'a> { pso::DescriptorType::Image { ty: pso::ImageDescriptorType::Sampled { with_sampler: true }, } => self.image_infos.next().map(|image| { - pso::Descriptor::CombinedImageSampler( - image.imageView.to_native().unwrap(), - conv::map_image_layout(image.imageLayout), - &*image.sampler, - ) + // It is valid for the sampler to be NULL in case the descriptor is + // actually associated with an immutable sampler. + // It's still bad to try to derefence it, even theough the implementation + // will not try to use the value. (TODO: make this nicer) + if image.sampler != Handle::null() { + pso::Descriptor::CombinedImageSampler( + image.imageView.to_native().unwrap(), + conv::map_image_layout(image.imageLayout), + &*image.sampler, + ) + } else { + pso::Descriptor::Image( + image.imageView.to_native().unwrap(), + conv::map_image_layout(image.imageLayout), + ) + } }), pso::DescriptorType::InputAttachment | pso::DescriptorType::Image { .. } => { @@ -3805,8 +3827,20 @@ pub extern "C" fn gfxCmdBlitImage( pRegions: *const VkImageBlit, filter: VkFilter, ) { - let src = srcImage.to_native().unwrap(); - let dst = dstImage.to_native().unwrap(); + let src = match srcImage.to_native() { + Ok(img) => img, + Err(_) => { + warn!("Unable to copy from a swapchain image!"); + return; + } + }; + let dst = match dstImage.to_native() { + Ok(img) => img, + Err(_) => { + warn!("Unable to copy into a swapchain image!"); + return; + } + }; let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) } .iter() @@ -3896,7 +3930,7 @@ pub extern "C" fn gfxCmdUpdateBuffer( dstBuffer: VkBuffer, dstOffset: VkDeviceSize, dataSize: VkDeviceSize, - pData: *const ::std::os::raw::c_void, + pData: *const c_void, ) { unsafe { commandBuffer.update_buffer( @@ -4277,7 +4311,7 @@ pub extern "C" fn gfxCmdPushConstants( stageFlags: VkShaderStageFlags, offset: u32, size: u32, - pValues: *const ::std::os::raw::c_void, + pValues: *const c_void, ) { assert_eq!(size % 4, 0); unsafe { @@ -4415,6 +4449,35 @@ pub extern "C" fn gfxGetPhysicalDeviceSurfaceCapabilitiesKHR( VkResult::VK_SUCCESS } +#[inline] +pub extern "C" fn gfxGetPhysicalDeviceSurfaceCapabilities2KHR( + adapter: VkPhysicalDevice, + pSurfaceInfo: *const VkPhysicalDeviceSurfaceInfo2KHR, + pSurfaceCapabilities: *mut VkSurfaceCapabilities2KHR, +) -> VkResult { + let surface = unsafe { (*pSurfaceInfo).surface }; + let mut ptr = pSurfaceCapabilities as *const VkStructureType; + while !ptr.is_null() { + ptr = match unsafe { *ptr } { + VkStructureType::VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR => { + let data = unsafe { (ptr as *mut VkSurfaceCapabilities2KHR).as_mut().unwrap() }; + gfxGetPhysicalDeviceSurfaceCapabilitiesKHR(adapter, surface, &mut data.surfaceCapabilities); + data.pNext + } + other => { + warn!("Unrecognized {:?}, skipping", other); + unsafe { + (ptr as *const VkBaseStruct) + .as_ref() + .unwrap() + } + .pNext + } + } as *const VkStructureType; + } + VkResult::VK_SUCCESS +} + #[inline] pub extern "C" fn gfxGetPhysicalDeviceSurfaceFormatsKHR( adapter: VkPhysicalDevice, @@ -4447,6 +4510,38 @@ pub extern "C" fn gfxGetPhysicalDeviceSurfaceFormatsKHR( VkResult::VK_SUCCESS } +#[inline] +pub extern "C" fn gfxGetPhysicalDeviceSurfaceFormats2KHR( + adapter: VkPhysicalDevice, + pSurfaceInfo: *const VkPhysicalDeviceSurfaceInfo2KHR, + pSurfaceFormatCount: *mut u32, + pSurfaceFormats: *mut VkSurfaceFormat2KHR, +) -> VkResult { + let formats = unsafe { (*pSurfaceInfo).surface } + .supported_formats(&adapter.physical_device) + .map(|formats| formats.into_iter().map(conv::format_from_hal).collect()) + .unwrap_or(vec![VkFormat::VK_FORMAT_UNDEFINED]); + + if pSurfaceFormats.is_null() { + // Return only the number of formats + unsafe { *pSurfaceFormatCount = formats.len() as u32 }; + } 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.surfaceFormat = VkSurfaceFormatKHR { + format, + colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO + }; + } + } + + VkResult::VK_SUCCESS +} + #[inline] pub extern "C" fn gfxGetPhysicalDeviceSurfacePresentModesKHR( adapter: VkPhysicalDevice, diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index 7daf8f3..000baf2 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -404,6 +404,10 @@ pub const VK_KHR_get_physical_device_properties2: ::std::os::raw::c_uint = 1; pub const VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION: ::std::os::raw::c_uint = 1; pub const VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME: &'static [u8; 39usize] = b"VK_KHR_get_physical_device_properties2\x00"; +pub const VK_KHR_get_surface_capabilities2: ::std::os::raw::c_uint = 1; +pub const VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION: ::std::os::raw::c_uint = 1; +pub const VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME: &'static [u8; 33usize] = + b"VK_KHR_get_surface_capabilities2\x00"; pub const VK_KHR_shader_draw_parameters: ::std::os::raw::c_uint = 1; pub const VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION: ::std::os::raw::c_uint = 1; pub const VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME: &'static [u8; 30usize] = @@ -866,7 +870,7 @@ pub enum VkStructureType { VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = 1000090000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000090000, VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001, VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002, @@ -1973,6 +1977,12 @@ pub type PFN_vkInternalFreeNotification = ::std::option::Option< >; pub type PFN_vkVoidFunction = ::std::option::Option; #[repr(C)] +#[derive(Debug)] +pub struct VkBaseStruct { + pub sType: VkStructureType, + pub pNext: *const ::std::os::raw::c_void, +} +#[repr(C)] #[derive(Debug, Copy)] pub struct VkApplicationInfo { pub sType: VkStructureType, @@ -4745,6 +4755,18 @@ impl Clone for VkSurfaceCapabilitiesKHR { } #[repr(C)] #[derive(Debug, Copy)] +pub struct VkSurfaceCapabilities2KHR { + pub sType: VkStructureType, + pub pNext: *const ::std::os::raw::c_void, + pub surfaceCapabilities: VkSurfaceCapabilitiesKHR, +} +impl Clone for VkSurfaceCapabilities2KHR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[derive(Debug, Copy)] pub struct VkSurfaceFormatKHR { pub format: VkFormat, pub colorSpace: VkColorSpaceKHR, @@ -4754,6 +4776,30 @@ impl Clone for VkSurfaceFormatKHR { *self } } +#[repr(C)] +#[derive(Debug, Copy)] +pub struct VkSurfaceFormat2KHR { + pub sType: VkStructureType, + pub pNext: *const ::std::os::raw::c_void, + pub surfaceFormat: VkSurfaceFormatKHR, +} +impl Clone for VkSurfaceFormat2KHR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[derive(Debug, Copy)] +pub struct VkPhysicalDeviceSurfaceInfo2KHR { + pub sType: VkStructureType, + pub pNext: *const ::std::os::raw::c_void, + pub surface: VkSurfaceKHR, +} +impl Clone for VkPhysicalDeviceSurfaceInfo2KHR { + fn clone(&self) -> Self { + *self + } +} pub type PFN_vkDestroySurfaceKHR = ::std::option::Option< unsafe extern "C" fn( instance: VkInstance, @@ -4776,6 +4822,13 @@ pub type PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = ::std::option::Option< pSurfaceCapabilities: *mut VkSurfaceCapabilitiesKHR, ) -> VkResult, >; +pub type PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR = ::std::option::Option< + unsafe extern "C" fn( + physicalDevice: VkPhysicalDevice, + pSurfaceInfo: *const VkPhysicalDeviceSurfaceInfo2KHR, + pSurfaceCapabilities: *mut VkSurfaceCapabilities2KHR, + ) -> VkResult, +>; pub type PFN_vkGetPhysicalDeviceSurfaceFormatsKHR = ::std::option::Option< unsafe extern "C" fn( physicalDevice: VkPhysicalDevice, @@ -4784,6 +4837,14 @@ pub type PFN_vkGetPhysicalDeviceSurfaceFormatsKHR = ::std::option::Option< pSurfaceFormats: *mut VkSurfaceFormatKHR, ) -> VkResult, >; +pub type PFN_vkGetPhysicalDeviceSurfaceFormats2KHR = ::std::option::Option< + unsafe extern "C" fn( + physicalDevice: VkPhysicalDevice, + pSurfaceInfo: *const VkPhysicalDeviceSurfaceInfo2KHR, + pSurfaceFormatCount: *mut u32, + pSurfaceFormats: *mut VkSurfaceFormat2KHR, + ) -> VkResult, +>; pub type PFN_vkGetPhysicalDeviceSurfacePresentModesKHR = ::std::option::Option< unsafe extern "C" fn( physicalDevice: VkPhysicalDevice, diff --git a/libportability/src/lib.rs b/libportability/src/lib.rs index 2203088..6b21a12 100644 --- a/libportability/src/lib.rs +++ b/libportability/src/lib.rs @@ -1500,3 +1500,10 @@ pub extern "C" fn vkEnumerateInstanceExtensionProperties( ) -> VkResult { gfxEnumerateInstanceExtensionProperties(pLayerName, pPropertyCount, pProperties) } + +//TODO: remove this once Dota2 stops asking for it +#[no_mangle] +pub extern "C" fn vkGetPhysicalDeviceMetalFeaturesMVK( + _adapter: VkPhysicalDevice, + _metal_features: *mut ::std::os::raw::c_void, +) {}