diff --git a/Cargo.lock b/Cargo.lock index 766c0d77f..04c2a2eb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -968,12 +968,11 @@ dependencies = [ [[package]] name = "metal" version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c12e48c737ee9a55e8bb2352bcde588f79ae308d3529ee888f7cc0f469b5777" +source = "git+https://github.com/kvark/metal-rs?branch=core-graphics-types#457518722ac2ca51cf1e668a2d2be57b751c8071" dependencies = [ "bitflags", "block", - "cocoa-foundation", + "core-graphics-types", "foreign-types", "log", "objc", @@ -1997,6 +1996,7 @@ dependencies = [ "ash", "bitflags", "block", + "core-graphics-types", "foreign-types", "fxhash", "gpu-alloc", @@ -2012,6 +2012,7 @@ dependencies = [ "renderdoc-sys", "thiserror", "wgpu-types", + "winapi 0.3.9", "winit", ] diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 9145c10a6..2124b9977 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -13,7 +13,7 @@ license = "MIT OR Apache-2.0" [features] default = [] -metal = ["naga/msl-out", "block", "foreign-types", "mtl", "objc"] +metal = ["naga/msl-out", "block", "foreign-types"] vulkan = ["naga/spv-out", "ash", "gpu-alloc", "gpu-descriptor", "libloading", "inplace_it", "renderdoc-sys"] [dependencies] @@ -31,8 +31,6 @@ log = "0.4" # backend: Metal block = { version = "0.1", optional = true } foreign-types = { version = "0.3", optional = true } -mtl = { package = "metal", version = "0.22", optional = true } -objc = { version = "0.2.5", optional = true } # backend: Vulkan ash = { version = "0.32", optional = true } gpu-alloc = { version = "0.4", optional = true } @@ -40,6 +38,14 @@ gpu-descriptor = { version = "0.1", optional = true } inplace_it = { version ="0.3.3", optional = true } renderdoc-sys = { version = "0.7.1", optional = true } +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi", "windef", "winuser"] } + +[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies] +mtl = { package = "metal", version = "0.22", git="https://github.com/kvark/metal-rs", branch="core-graphics-types" } +objc = "0.2.5" +core-graphics-types = "0.1" + [dependencies.naga] git = "https://github.com/gfx-rs/naga" tag = "gfx-25" diff --git a/wgpu-hal/src/metal/surface.rs b/wgpu-hal/src/metal/surface.rs index 18db5d93a..5c672da77 100644 --- a/wgpu-hal/src/metal/surface.rs +++ b/wgpu-hal/src/metal/surface.rs @@ -1,5 +1,9 @@ use std::{mem, os::raw::c_void, ptr::NonNull, thread}; +use core_graphics_types::{ + base::CGFloat, + geometry::{CGRect, CGSize}, +}; use objc::{ class, msg_send, rc::autoreleasepool, @@ -14,22 +18,6 @@ extern "C" { static kCAGravityTopLeft: *mut Object; } -#[repr(C)] -#[derive(Clone, Copy, Debug, Default)] -#[allow(clippy::upper_case_acronyms)] -pub struct CGPoint { - pub x: mtl::CGFloat, - pub y: mtl::CGFloat, -} - -#[repr(C)] -#[derive(Clone, Copy, Debug, Default)] -#[allow(clippy::upper_case_acronyms)] -pub struct CGRect { - pub origin: CGPoint, - pub size: mtl::CGSize, -} - impl super::Surface { fn new(view: Option>, layer: mtl::MetalLayer) -> Self { Self { @@ -117,7 +105,7 @@ impl super::Surface { let window: *mut Object = msg_send![view, window]; if !window.is_null() { - let scale_factor: mtl::CGFloat = msg_send![window, backingScaleFactor]; + let scale_factor: CGFloat = msg_send![window, backingScaleFactor]; let () = msg_send![layer, setContentsScale: scale_factor]; } //let () = msg_send![layer, setDelegate: self.gfx_managed_metal_layer_delegate.0]; @@ -138,7 +126,7 @@ impl super::Surface { } pub(super) fn dimensions(&self) -> wgt::Extent3d { - let (size, scale): (mtl::CGSize, mtl::CGFloat) = match self.view { + let (size, scale): (CGSize, CGFloat) = match self.view { Some(view) if !cfg!(target_os = "macos") => unsafe { let bounds: CGRect = msg_send![view.as_ptr(), bounds]; let window: Option> = msg_send![view.as_ptr(), window]; @@ -149,7 +137,7 @@ impl super::Surface { Some(screen) => { let screen_space: *mut Object = msg_send![screen.as_ptr(), coordinateSpace]; let rect: CGRect = msg_send![view.as_ptr(), convertRect:bounds toCoordinateSpace:screen_space]; - let scale_factor: mtl::CGFloat = msg_send![screen.as_ptr(), nativeScale]; + let scale_factor: CGFloat = msg_send![screen.as_ptr(), nativeScale]; (rect.size, scale_factor) } None => (bounds.size, 1.0), @@ -159,7 +147,7 @@ impl super::Surface { let render_layer_borrow = self.render_layer.lock(); let render_layer = render_layer_borrow.as_ref(); let bounds: CGRect = msg_send![render_layer, bounds]; - let contents_scale: mtl::CGFloat = msg_send![render_layer, contentsScale]; + let contents_scale: CGFloat = msg_send![render_layer, contentsScale]; (bounds.size, contents_scale) }, }; @@ -186,8 +174,7 @@ impl crate::Surface for super::Surface { let render_layer = self.render_layer.lock(); let framebuffer_only = config.usage == crate::TextureUse::COLOR_TARGET; let display_sync = config.present_mode != wgt::PresentMode::Immediate; - let drawable_size = - mtl::CGSize::new(config.extent.width as f64, config.extent.height as f64); + let drawable_size = CGSize::new(config.extent.width as f64, config.extent.height as f64); match config.composite_alpha_mode { crate::CompositeAlphaMode::Opaque => render_layer.set_opaque(true), diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 487dd5b66..37e04c5d6 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -230,14 +230,23 @@ impl super::Instance { self.create_surface_from_vk_surface_khr(surface) } - #[cfg(feature = "disabled")] + #[cfg(any(target_os = "macos", target_os = "ios"))] fn create_surface_from_ns_view(&self, view: *mut c_void) -> super::Surface { - use ash::extensions::mvk; use core_graphics_types::{base::CGFloat, geometry::CGRect}; - use objc::runtime::{Object, BOOL, YES}; + use objc::{ + class, msg_send, + runtime::{Object, BOOL, YES}, + sel, sel_impl, + }; - // TODO: this logic is duplicated from gfx-backend-metal, refactor? - unsafe { + if !self.extensions.contains(&ext::MetalSurface::name()) { + panic!( + "Vulkan Portability driver does not support {:?}", + ext::MetalSurface::name() + ); + } + + let layer = unsafe { let view = view as *mut Object; let existing: *mut Object = msg_send![view, layer]; let class = class!(CAMetalLayer); @@ -249,7 +258,9 @@ impl super::Instance { result == YES }; - if !use_current { + if use_current { + existing + } else { let layer: *mut Object = msg_send![class, new]; let () = msg_send![view, setLayer: layer]; let bounds: CGRect = msg_send![view, bounds]; @@ -260,26 +271,18 @@ impl super::Instance { let scale_factor: CGFloat = msg_send![window, backingScaleFactor]; let () = msg_send![layer, setContentsScale: scale_factor]; } + layer } - } - - if !self.extensions.contains(&mvk::MacOSSurface::name()) { - panic!("Vulkan driver does not support VK_MVK_MACOS_SURFACE"); - } + }; let surface = { - let mac_os_loader = mvk::MacOSSurface::new(&self.entry, &self.shared.raw); - let mut info = vk::MacOSSurfaceCreateInfoMVK::builder() - .flags(vk::MacOSSurfaceCreateFlagsMVK::empty()); - if let Some(view) = unsafe { view.as_ref() } { - info = info.view(view); - } + let metal_loader = ext::MetalSurface::new(&self.entry, &self.shared.raw); + let vk_info = vk::MetalSurfaceCreateInfoEXT::builder() + .flags(vk::MetalSurfaceCreateFlagsEXT::empty()) + .layer(layer as *mut _) + .build(); - unsafe { - mac_os_loader - .create_mac_os_surface_mvk(&info, None) - .expect("Unable to create macOS surface") - } + unsafe { metal_loader.create_metal_surface(&vk_info, None).unwrap() } }; self.create_surface_from_vk_surface_khr(surface) @@ -542,7 +545,7 @@ impl crate::Instance for super::Instance { let hinstance = GetModuleHandleW(std::ptr::null()); Ok(self.create_surface_from_hwnd(hinstance as *mut _, handle.hwnd)) } - #[cfg(target_os = "macos_disabled")] + #[cfg(target_os = "macos")] RawWindowHandle::MacOS(handle) => Ok(self.create_surface_from_ns_view(handle.ns_view)), _ => Err(crate::InstanceError), }