mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-10-30 14:01:39 +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]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/kvark/metal-rs?branch=core-graphics-types#457518722ac2ca51cf1e668a2d2be57b751c8071"
|
||||||
checksum = "1c12e48c737ee9a55e8bb2352bcde588f79ae308d3529ee888f7cc0f469b5777"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"block",
|
"block",
|
||||||
"cocoa-foundation",
|
"core-graphics-types",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"log",
|
"log",
|
||||||
"objc",
|
"objc",
|
||||||
@ -1997,6 +1996,7 @@ dependencies = [
|
|||||||
"ash",
|
"ash",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"block",
|
"block",
|
||||||
|
"core-graphics-types",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"gpu-alloc",
|
"gpu-alloc",
|
||||||
@ -2012,6 +2012,7 @@ dependencies = [
|
|||||||
"renderdoc-sys",
|
"renderdoc-sys",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wgpu-types",
|
"wgpu-types",
|
||||||
|
"winapi 0.3.9",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ license = "MIT OR Apache-2.0"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
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"]
|
vulkan = ["naga/spv-out", "ash", "gpu-alloc", "gpu-descriptor", "libloading", "inplace_it", "renderdoc-sys"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -31,8 +31,6 @@ log = "0.4"
|
|||||||
# backend: Metal
|
# backend: Metal
|
||||||
block = { version = "0.1", optional = true }
|
block = { version = "0.1", optional = true }
|
||||||
foreign-types = { version = "0.3", 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
|
# backend: Vulkan
|
||||||
ash = { version = "0.32", optional = true }
|
ash = { version = "0.32", optional = true }
|
||||||
gpu-alloc = { version = "0.4", 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 }
|
inplace_it = { version ="0.3.3", optional = true }
|
||||||
renderdoc-sys = { version = "0.7.1", 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]
|
[dependencies.naga]
|
||||||
git = "https://github.com/gfx-rs/naga"
|
git = "https://github.com/gfx-rs/naga"
|
||||||
tag = "gfx-25"
|
tag = "gfx-25"
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
use std::{mem, os::raw::c_void, ptr::NonNull, thread};
|
use std::{mem, os::raw::c_void, ptr::NonNull, thread};
|
||||||
|
|
||||||
|
use core_graphics_types::{
|
||||||
|
base::CGFloat,
|
||||||
|
geometry::{CGRect, CGSize},
|
||||||
|
};
|
||||||
use objc::{
|
use objc::{
|
||||||
class, msg_send,
|
class, msg_send,
|
||||||
rc::autoreleasepool,
|
rc::autoreleasepool,
|
||||||
@ -14,22 +18,6 @@ extern "C" {
|
|||||||
static kCAGravityTopLeft: *mut Object;
|
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 {
|
impl super::Surface {
|
||||||
fn new(view: Option<NonNull<Object>>, layer: mtl::MetalLayer) -> Self {
|
fn new(view: Option<NonNull<Object>>, layer: mtl::MetalLayer) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -117,7 +105,7 @@ impl super::Surface {
|
|||||||
|
|
||||||
let window: *mut Object = msg_send![view, window];
|
let window: *mut Object = msg_send![view, window];
|
||||||
if !window.is_null() {
|
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, setContentsScale: scale_factor];
|
||||||
}
|
}
|
||||||
//let () = msg_send![layer, setDelegate: self.gfx_managed_metal_layer_delegate.0];
|
//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 {
|
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 {
|
Some(view) if !cfg!(target_os = "macos") => unsafe {
|
||||||
let bounds: CGRect = msg_send![view.as_ptr(), bounds];
|
let bounds: CGRect = msg_send![view.as_ptr(), bounds];
|
||||||
let window: Option<NonNull<Object>> = msg_send![view.as_ptr(), window];
|
let window: Option<NonNull<Object>> = msg_send![view.as_ptr(), window];
|
||||||
@ -149,7 +137,7 @@ impl super::Surface {
|
|||||||
Some(screen) => {
|
Some(screen) => {
|
||||||
let screen_space: *mut Object = msg_send![screen.as_ptr(), coordinateSpace];
|
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 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)
|
(rect.size, scale_factor)
|
||||||
}
|
}
|
||||||
None => (bounds.size, 1.0),
|
None => (bounds.size, 1.0),
|
||||||
@ -159,7 +147,7 @@ impl super::Surface {
|
|||||||
let render_layer_borrow = self.render_layer.lock();
|
let render_layer_borrow = self.render_layer.lock();
|
||||||
let render_layer = render_layer_borrow.as_ref();
|
let render_layer = render_layer_borrow.as_ref();
|
||||||
let bounds: CGRect = msg_send![render_layer, bounds];
|
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)
|
(bounds.size, contents_scale)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -186,8 +174,7 @@ impl crate::Surface<super::Api> for super::Surface {
|
|||||||
let render_layer = self.render_layer.lock();
|
let render_layer = self.render_layer.lock();
|
||||||
let framebuffer_only = config.usage == crate::TextureUse::COLOR_TARGET;
|
let framebuffer_only = config.usage == crate::TextureUse::COLOR_TARGET;
|
||||||
let display_sync = config.present_mode != wgt::PresentMode::Immediate;
|
let display_sync = config.present_mode != wgt::PresentMode::Immediate;
|
||||||
let drawable_size =
|
let drawable_size = CGSize::new(config.extent.width as f64, config.extent.height as f64);
|
||||||
mtl::CGSize::new(config.extent.width as f64, config.extent.height as f64);
|
|
||||||
|
|
||||||
match config.composite_alpha_mode {
|
match config.composite_alpha_mode {
|
||||||
crate::CompositeAlphaMode::Opaque => render_layer.set_opaque(true),
|
crate::CompositeAlphaMode::Opaque => render_layer.set_opaque(true),
|
||||||
|
@ -230,14 +230,23 @@ impl super::Instance {
|
|||||||
self.create_surface_from_vk_surface_khr(surface)
|
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 {
|
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 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?
|
if !self.extensions.contains(&ext::MetalSurface::name()) {
|
||||||
unsafe {
|
panic!(
|
||||||
|
"Vulkan Portability driver does not support {:?}",
|
||||||
|
ext::MetalSurface::name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let layer = unsafe {
|
||||||
let view = view as *mut Object;
|
let view = view as *mut Object;
|
||||||
let existing: *mut Object = msg_send![view, layer];
|
let existing: *mut Object = msg_send![view, layer];
|
||||||
let class = class!(CAMetalLayer);
|
let class = class!(CAMetalLayer);
|
||||||
@ -249,7 +258,9 @@ impl super::Instance {
|
|||||||
result == YES
|
result == YES
|
||||||
};
|
};
|
||||||
|
|
||||||
if !use_current {
|
if use_current {
|
||||||
|
existing
|
||||||
|
} else {
|
||||||
let layer: *mut Object = msg_send![class, new];
|
let layer: *mut Object = msg_send![class, new];
|
||||||
let () = msg_send![view, setLayer: layer];
|
let () = msg_send![view, setLayer: layer];
|
||||||
let bounds: CGRect = msg_send![view, bounds];
|
let bounds: CGRect = msg_send![view, bounds];
|
||||||
@ -260,26 +271,18 @@ impl super::Instance {
|
|||||||
let scale_factor: CGFloat = msg_send![window, backingScaleFactor];
|
let scale_factor: CGFloat = msg_send![window, backingScaleFactor];
|
||||||
let () = msg_send![layer, setContentsScale: scale_factor];
|
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 surface = {
|
||||||
let mac_os_loader = mvk::MacOSSurface::new(&self.entry, &self.shared.raw);
|
let metal_loader = ext::MetalSurface::new(&self.entry, &self.shared.raw);
|
||||||
let mut info = vk::MacOSSurfaceCreateInfoMVK::builder()
|
let vk_info = vk::MetalSurfaceCreateInfoEXT::builder()
|
||||||
.flags(vk::MacOSSurfaceCreateFlagsMVK::empty());
|
.flags(vk::MetalSurfaceCreateFlagsEXT::empty())
|
||||||
if let Some(view) = unsafe { view.as_ref() } {
|
.layer(layer as *mut _)
|
||||||
info = info.view(view);
|
.build();
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
unsafe { metal_loader.create_metal_surface(&vk_info, None).unwrap() }
|
||||||
mac_os_loader
|
|
||||||
.create_mac_os_surface_mvk(&info, None)
|
|
||||||
.expect("Unable to create macOS surface")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.create_surface_from_vk_surface_khr(surface)
|
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());
|
let hinstance = GetModuleHandleW(std::ptr::null());
|
||||||
Ok(self.create_surface_from_hwnd(hinstance as *mut _, handle.hwnd))
|
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)),
|
RawWindowHandle::MacOS(handle) => Ok(self.create_surface_from_ns_view(handle.ns_view)),
|
||||||
_ => Err(crate::InstanceError),
|
_ => Err(crate::InstanceError),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user