mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-10-30 05:51:42 +00:00
hal/vk: enable vulkan portability support on macos
This commit is contained in:
parent
67dfdb9193
commit
1952ecb99c
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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<NonNull<Object>>, 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<NonNull<Object>> = 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<super::Api> 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),
|
||||
|
@ -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<super::Api> 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),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user