Add capability to function as a guest in Metal

WIP
This commit is contained in:
Raph Levien 2021-12-25 16:55:13 -08:00 committed by Raph Levien
parent 41c7118e91
commit 5e221d2e91
3 changed files with 47 additions and 36 deletions

View file

@ -16,7 +16,7 @@ mod macros;
mod mux;
pub use crate::mux::{
DescriptorSet, Fence, Instance, Pipeline, QueryPool, Sampler, Semaphore, ShaderCode, Surface,
DescriptorSet, Device, Fence, Instance, Pipeline, QueryPool, Sampler, Semaphore, ShaderCode, Surface,
Swapchain,
};
pub use bufwrite::BufWrite;

View file

@ -153,6 +153,33 @@ impl MtlInstance {
pub fn device(&self, _surface: Option<&MtlSurface>) -> Result<MtlDevice, Error> {
if let Some(device) = metal::Device::system_default() {
let cmd_queue = device.new_command_queue();
Ok(MtlDevice::new_from_raw_mtl(device, cmd_queue))
} else {
Err("can't create system default Metal device".into())
}
}
pub unsafe fn swapchain(
&self,
_width: usize,
_height: usize,
device: &MtlDevice,
surface: &MtlSurface,
) -> Result<MtlSwapchain, Error> {
surface.layer.set_device(&device.device);
let n_drawables = surface.layer.maximum_drawable_count() as usize;
Ok(MtlSwapchain {
layer: surface.layer.to_owned(),
cmd_queue: device.cmd_queue.clone(),
drawable: Default::default(),
n_drawables,
drawable_ix: 0,
})
}
}
impl MtlDevice {
pub fn new_from_raw_mtl(device: metal::Device, cmd_queue: metal::CommandQueue) -> MtlDevice {
let is_mac = device.supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v1);
let is_ios = device.supports_feature_set(MTLFeatureSet::iOS_GPUFamily1_v1);
let version = NSOperatingSystemVersion::get();
@ -182,34 +209,13 @@ impl MtlInstance {
let helpers = Arc::new(Helpers {
clear_pipeline: clear::make_clear_pipeline(&device),
});
Ok(MtlDevice {
MtlDevice {
device,
cmd_queue: Arc::new(Mutex::new(cmd_queue)),
gpu_info,
helpers,
})
} else {
Err("can't create system default Metal device".into())
}
}
pub unsafe fn swapchain(
&self,
_width: usize,
_height: usize,
device: &MtlDevice,
surface: &MtlSurface,
) -> Result<MtlSwapchain, Error> {
surface.layer.set_device(&device.device);
let n_drawables = surface.layer.maximum_drawable_count() as usize;
Ok(MtlSwapchain {
layer: surface.layer.to_owned(),
cmd_queue: device.cmd_queue.clone(),
drawable: Default::default(),
n_drawables,
drawable_ix: 0,
})
}
}
impl crate::backend::Device for MtlDevice {

View file

@ -208,6 +208,11 @@ impl Instance {
// but not doing so lets us diverge more easily (at the moment, the divergence is
// missing functionality).
impl Device {
#[cfg(target_os = "macos")]
pub fn new_from_raw_mtl(device: &::metal::DeviceRef, queue: &::metal::CommandQueueRef) -> Device {
Device::Mtl(metal::MtlDevice::new_from_raw_mtl(device.to_owned(), queue.to_owned()))
}
pub fn query_gpu_info(&self) -> GpuInfo {
mux_match! { self;
Device::Vk(d) => d.query_gpu_info(),