From f00dc5d65540857e06ae4cfd05c37d27b86f8a26 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 4 Dec 2025 15:41:52 +0100 Subject: [PATCH 1/2] Use `objc2-metal` with `metal` naming scheme To keep the diff smaller and easier to review, this uses a temporary fork of `objc2-metal` and `objc2-quartz-core` whose methods use the naming scheme of the `metal` crate. One particular difficult part with this is that the `metal` crate has several methods where the order of the arguments are swapped relative to the corresponding Objective-C methods. This includes most perilously the following, since these have both an offset and an index argument, both of which are integers: - `set_bytes` - `set_vertex_bytes` - `set_fragment_bytes` - `set_buffer` - `set_vertex_buffer` - `set_fragment_buffer` - `set_threadgroup_memory_length` But also: - `set_vertex_texture` - `set_fragment_texture` - `set_sampler_state` - `set_vertex_sampler_state` - `set_fragment_sampler_state` --- CHANGELOG.md | 6 + Cargo.lock | 188 ++++---- Cargo.toml | 57 ++- wgpu-hal/Cargo.toml | 29 +- wgpu-hal/src/gles/egl.rs | 7 +- wgpu-hal/src/metal/adapter.rs | 130 +++--- wgpu-hal/src/metal/command.rs | 855 ++++++++++++++++++++-------------- wgpu-hal/src/metal/conv.rs | 34 +- wgpu-hal/src/metal/device.rs | 468 +++++++++++-------- wgpu-hal/src/metal/mod.rs | 255 +++++----- wgpu-hal/src/metal/surface.rs | 55 +-- 11 files changed, 1187 insertions(+), 897 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c98f5e61cb4..77bfc07071c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,12 @@ Bottom level categories: - Allow parsing shaders which make use of `SPV_KHR_non_semantic_info` for debug info. Also removes `naga::front::spv::SUPPORTED_EXT_SETS`. By @inner-daemons in #8827. +### Changes + +#### Metal + +- Use autogenerated `objc2` bindings internally, which should resolve a lot of leaks and unsoundness. By @madsmtm in [#5641](https://github.com/gfx-rs/wgpu/pull/5641). + ### Bug Fixes #### General diff --git a/Cargo.lock b/Cargo.lock index 341a8c74260..6f21791b92a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,12 +400,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-sys" version = "0.2.1" @@ -434,6 +428,14 @@ dependencies = [ "objc2 0.5.2", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", +] + [[package]] name = "boxed_error" version = "0.2.3" @@ -792,16 +794,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -815,8 +807,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", + "core-foundation", + "core-graphics-types", "foreign-types", "libc", ] @@ -828,18 +820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.10.1", + "core-foundation", "libc", ] @@ -1196,7 +1177,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", ] [[package]] @@ -1701,7 +1691,7 @@ dependencies = [ "bitflags 2.10.0", "cfg_aliases 0.1.1", "cgl", - "core-foundation 0.9.4", + "core-foundation", "dispatch", "glutin_egl_sys", "glutin_wgl_sys 0.5.0", @@ -2304,15 +2294,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "matchers" version = "0.2.0" @@ -2337,21 +2318,6 @@ dependencies = [ "libc", ] -[[package]] -name = "metal" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" -dependencies = [ - "bitflags 2.10.0", - "block", - "core-graphics-types 0.2.0", - "foreign-types", - "log", - "objc", - "paste", -] - [[package]] name = "minicov" version = "0.3.8" @@ -2695,15 +2661,6 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "059c95245738cdc7b40078cdd51a23200252a4c0a0a6dd005136152b3f467a4a" -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "objc-sys" version = "0.3.5" @@ -2727,7 +2684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ "objc-sys", - "objc2-encode 4.1.0", + "objc2-encode 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2736,7 +2693,15 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ - "objc2-encode 4.1.0", + "objc2-encode 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "objc2-encode 4.1.0 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", ] [[package]] @@ -2798,8 +2763,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.10.0", - "dispatch2", - "objc2 0.6.3", + "dispatch2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "bitflags 2.10.0", + "dispatch2 0.3.0 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", ] [[package]] @@ -2838,6 +2813,11 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" + [[package]] name = "objc2-foundation" version = "0.2.2" @@ -2858,8 +2838,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", + "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-core-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", ] [[package]] @@ -2893,8 +2882,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-foundation 0.3.2", + "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "bitflags 2.10.0", + "block2 0.6.2", + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", ] [[package]] @@ -2917,10 +2917,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-foundation 0.3.2", - "objc2-metal 0.3.2", + "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-core-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-metal 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-core-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-metal 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", ] [[package]] @@ -3393,10 +3405,10 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" dependencies = [ - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-foundation 0.3.2", - "objc2-quartz-core 0.3.2", + "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-core-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-quartz-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4921,11 +4933,10 @@ dependencies = [ "ash", "bit-set", "bitflags 2.10.0", - "block", + "block2 0.6.2", "bytemuck", "cfg-if", "cfg_aliases 0.2.1", - "core-graphics-types 0.2.0", "env_logger", "glam", "glow", @@ -4941,10 +4952,13 @@ dependencies = [ "libloading", "log", "mach-dxcompiler-rs", - "metal", "naga", "ndk-sys 0.6.0+11769913", - "objc", + "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-core-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-metal 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-quartz-core 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", "once_cell", "ordered-float", "parking_lot", @@ -5534,7 +5548,7 @@ dependencies = [ "bytemuck", "calloop 0.12.4", "cfg_aliases 0.1.1", - "core-foundation 0.9.4", + "core-foundation", "core-graphics", "cursor-icon", "icrate", @@ -5585,7 +5599,7 @@ dependencies = [ "calloop 0.13.0", "cfg_aliases 0.2.1", "concurrent-queue", - "core-foundation 0.9.4", + "core-foundation", "core-graphics", "cursor-icon", "dpi", diff --git a/Cargo.toml b/Cargo.toml index 2e77193ef5a..58f4eafcb34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -202,10 +202,59 @@ which = "8" xshell = "0.2.2" # Metal dependencies -metal = "0.33" -block = "0.1.6" -core-graphics-types = "0.2" -objc = "0.2.5" +block2 = { version = "0.6.2", git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +objc2 = { version = "0.6.3", git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +objc2-core-foundation = { version = "0.3.2", default-features = false, features = [ + "std", + "CFCGTypes", +], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +objc2-foundation = { version = "0.3.2", default-features = false, features = [ + "std", + "NSError", + "NSProcessInfo", + "NSRange", + "NSString", +], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +objc2-metal = { version = "0.3.2", default-features = false, features = [ + "std", + "block2", + "MTLAllocation", + "MTLBlitCommandEncoder", + "MTLBlitPass", + "MTLBuffer", + "MTLCaptureManager", + "MTLCaptureScope", + "MTLCommandBuffer", + "MTLCommandEncoder", + "MTLCommandQueue", + "MTLComputeCommandEncoder", + "MTLComputePass", + "MTLComputePipeline", + "MTLCounters", + "MTLDepthStencil", + "MTLDevice", + "MTLDrawable", + "MTLEvent", + "MTLLibrary", + "MTLPipeline", + "MTLPixelFormat", + "MTLRenderCommandEncoder", + "MTLRenderPass", + "MTLRenderPipeline", + "MTLResource", + "MTLSampler", + "MTLStageInputOutputDescriptor", + "MTLTexture", + "MTLTypes", + "MTLVertexDescriptor", +], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +objc2-quartz-core = { version = "0.3.2", default-features = false, features = [ + "std", + "objc2-core-foundation", + "CALayer", + "CAMetalLayer", + "objc2-metal", +], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } raw-window-metal = "1.0" # Vulkan dependencies diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 48aaa1abe0c..ba5fcec70a9 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -18,10 +18,9 @@ rust-version = "1.82.0" [package.metadata.docs.rs] # Ideally we would enable all the features. # -# However, the metal features fail to be documented because the docs.rs runner cross-compiling under -# x86_64-unknown-linux-gnu and metal-rs cannot compile in that environment at the moment. The same applies -# for the dx12 feature. -features = ["vulkan", "gles", "renderdoc"] +# However, the dx12 features fail to be documented because the docs.rs runner cross-compiling under +# x86_64-unknown-linux-gnu cannot compile in that environment at the moment. +features = ["metal", "vulkan", "gles", "renderdoc"] rustdoc-args = ["--cfg", "docsrs"] targets = [ "x86_64-unknown-linux-gnu", @@ -75,13 +74,15 @@ metal = [ # Metal is only available on Apple platforms, therefore request MSL output also only if we target an Apple platform. "naga/msl-out", "dep:arrayvec", - "dep:block", - "dep:core-graphics-types", + "dep:block2", "dep:hashbrown", "dep:libc", "dep:log", - "dep:metal", - "dep:objc", + "dep:objc2", + "dep:objc2-core-foundation", + "dep:objc2-foundation", + "dep:objc2-metal", + "dep:objc2-quartz-core", "dep:parking_lot", "dep:profiling", "dep:smallvec", @@ -120,7 +121,7 @@ gles = [ "dep:libloading", "dep:log", "dep:ndk-sys", - "dep:objc", + "dep:objc2", "dep:parking_lot", "dep:profiling", "dep:wasm-bindgen", @@ -281,10 +282,12 @@ mach-dxcompiler-rs = { workspace = true, optional = true } [target.'cfg(target_vendor = "apple")'.dependencies] # Backend: Metal -block = { workspace = true, optional = true } -core-graphics-types = { workspace = true, optional = true } -metal = { workspace = true, optional = true } -objc = { workspace = true, optional = true } +block2 = { workspace = true, optional = true } +objc2 = { workspace = true, optional = true } +objc2-core-foundation = { workspace = true, optional = true } +objc2-foundation = { workspace = true, optional = true } +objc2-metal = { workspace = true, optional = true } +objc2-quartz-core = { workspace = true, optional = true } # backend: Metal + Vulkan raw-window-metal = { workspace = true, optional = true } diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index 606d1b2d4ab..58fc34040a3 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -1253,10 +1253,11 @@ impl crate::Surface for Surface { let window_ptr = handle.ns_view.as_ptr(); #[cfg(target_os = "macos")] let window_ptr = { - use objc::{msg_send, runtime::Object, sel, sel_impl}; + use objc2::msg_send; + use objc2::runtime::AnyObject; // ns_view always have a layer and don't need to verify that it exists. - let layer: *mut Object = - msg_send![handle.ns_view.as_ptr().cast::(), layer]; + let layer: *mut AnyObject = + msg_send![handle.ns_view.as_ptr().cast::(), layer]; layer.cast::() }; window_ptr diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 03f5b382889..8df3c85d903 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -1,12 +1,13 @@ -use metal::{ - MTLArgumentBuffersTier, MTLCounterSamplingPoint, MTLFeatureSet, MTLGPUFamily, - MTLLanguageVersion, MTLPixelFormat, MTLReadWriteTextureTier, NSInteger, +use objc2::runtime::ProtocolObject; +use objc2_foundation::{NSOperatingSystemVersion, NSProcessInfo}; +use objc2_metal::{ + MTLArgumentBuffersTier, MTLCounterSamplingPoint, MTLDevice, MTLFeatureSet, MTLGPUFamily, + MTLLanguageVersion, MTLPixelFormat, MTLReadWriteTextureTier, }; -use objc::{class, msg_send, sel, sel_impl}; use parking_lot::Mutex; use wgt::{AstcBlock, AstcChannel}; -use alloc::{sync::Arc, vec::Vec}; +use alloc::{string::ToString as _, sync::Arc, vec::Vec}; use super::TimestampQuerySupport; @@ -27,7 +28,7 @@ use super::TimestampQuerySupport; /// . /// /// [new command buffer]: https://developer.apple.com/documentation/metal/mtlcommandqueue/makecommandbuffer()?language=objc -const MAX_COMMAND_BUFFERS: u64 = 4096; +const MAX_COMMAND_BUFFERS: usize = 4096; unsafe impl Send for super::Adapter {} unsafe impl Sync for super::Adapter {} @@ -50,7 +51,8 @@ impl crate::Adapter for super::Adapter { let queue = self .shared .device - .new_command_queue_with_max_command_buffer_count(MAX_COMMAND_BUFFERS); + .new_command_queue_with_max_command_buffer_count(MAX_COMMAND_BUFFERS) + .unwrap(); // Acquiring the meaning of timestamp ticks is hard with Metal! // The only thing there is a method correlating cpu & gpu timestamps (`device.sample_timestamps`). @@ -71,7 +73,7 @@ impl crate::Adapter for super::Adapter { // Based on: // * https://github.com/gfx-rs/wgpu/pull/2528 // * https://github.com/gpuweb/gpuweb/issues/1325#issuecomment-761041326 - let timestamp_period = if self.shared.device.name().starts_with("Intel") { + let timestamp_period = if self.shared.device.name().to_string().starts_with("Intel") { 83.333 } else { // Known for Apple Silicon (at least M1 & M2, iPad Pro 2018) and AMD GPUs. @@ -106,6 +108,8 @@ impl crate::Adapter for super::Adapter { MTLReadWriteTextureTier::TierNone => (Tfc::empty(), Tfc::empty()), MTLReadWriteTextureTier::Tier1 => (Tfc::STORAGE_READ_WRITE, Tfc::empty()), MTLReadWriteTextureTier::Tier2 => (Tfc::STORAGE_READ_WRITE, Tfc::STORAGE_READ_WRITE), + // Unknown levels of support are likely higher than Tier 2. + _ => (Tfc::STORAGE_READ_WRITE, Tfc::STORAGE_READ_WRITE), }; let msaa_count = pc.sample_count_mask; @@ -128,7 +132,7 @@ impl crate::Adapter for super::Adapter { ], ); - let image_atomic_if = if pc.msl_version >= MTLLanguageVersion::V3_1 { + let image_atomic_if = if pc.msl_version >= MTLLanguageVersion::Version3_1 { Tfc::STORAGE_ATOMIC } else { Tfc::empty() @@ -515,22 +519,18 @@ const DEPTH_CLIP_MODE: &[MTLFeatureSet] = &[ MTLFeatureSet::macOS_GPUFamily1_v1, ]; -const OS_NOT_SUPPORT: (usize, usize) = (10000, 0); +const OS_NOT_SUPPORT: (isize, isize) = (10000, 0); impl super::PrivateCapabilities { - fn supports_any(raw: &metal::DeviceRef, features_sets: &[MTLFeatureSet]) -> bool { + fn supports_any(raw: &ProtocolObject, features_sets: &[MTLFeatureSet]) -> bool { features_sets .iter() .cloned() .any(|x| raw.supports_feature_set(x)) } - pub fn new(device: &metal::Device) -> Self { - let version: NSOperatingSystemVersion = unsafe { - let process_info: *mut objc::runtime::Object = - msg_send![class!(NSProcessInfo), processInfo]; - msg_send![process_info, operatingSystemVersion] - }; + pub fn new(device: &ProtocolObject) -> Self { + let version = NSProcessInfo::processInfo().operatingSystemVersion(); let os_type = super::OsType::new(version, device); let family_check = version.at_least((10, 15), (13, 0), (13, 0), (1, 0), os_type); @@ -588,7 +588,7 @@ impl super::PrivateCapabilities { .at_least((10, 13), (11, 0), (11, 0), (1, 0), os_type) .then(|| device.argument_buffers_support()); - let is_virtual = device.name().to_lowercase().contains("virtual"); + let is_virtual = device.name().to_string().to_lowercase().contains("virtual"); let mesh_shaders = family_check && (device.supports_family(MTLGPUFamily::Metal3) @@ -598,25 +598,25 @@ impl super::PrivateCapabilities { && !is_virtual; let msl_version = if version.at_least((14, 0), (17, 0), (17, 0), (1, 0), os_type) { - MTLLanguageVersion::V3_1 + MTLLanguageVersion::Version3_1 } else if version.at_least((13, 0), (16, 0), (16, 0), (1, 0), os_type) { - MTLLanguageVersion::V3_0 + MTLLanguageVersion::Version3_0 } else if version.at_least((12, 0), (15, 0), (15, 0), (1, 0), os_type) { - MTLLanguageVersion::V2_4 + MTLLanguageVersion::Version2_4 } else if version.at_least((11, 0), (14, 0), (14, 0), (1, 0), os_type) { - MTLLanguageVersion::V2_3 + MTLLanguageVersion::Version2_3 } else if version.at_least((10, 15), (13, 0), (13, 0), (1, 0), os_type) { - MTLLanguageVersion::V2_2 + MTLLanguageVersion::Version2_2 } else if version.at_least((10, 14), (12, 0), (12, 0), (1, 0), os_type) { - MTLLanguageVersion::V2_1 + MTLLanguageVersion::Version2_1 } else if version.at_least((10, 13), (11, 0), (11, 0), (1, 0), os_type) { - MTLLanguageVersion::V2_0 + MTLLanguageVersion::Version2_0 } else if version.at_least((10, 12), (10, 0), (10, 0), (1, 0), os_type) { - MTLLanguageVersion::V1_2 + MTLLanguageVersion::Version1_2 } else if version.at_least((10, 11), (9, 0), (9, 0), (1, 0), os_type) { - MTLLanguageVersion::V1_1 + MTLLanguageVersion::Version1_1 } else { - MTLLanguageVersion::V1_0 + MTLLanguageVersion::Version1_0 }; // The `PrivateCapabilities` we are constructing here duplicates many of the limits @@ -654,8 +654,9 @@ impl super::PrivateCapabilities { texture_cube_array: Self::supports_any(device, TEXTURE_CUBE_ARRAY_SUPPORT), supports_float_filtering: os_type == super::OsType::Macos || (version.at_least((11, 0), (14, 0), (16, 0), (1, 0), os_type) - && device.supports_32bit_float_filtering()), - format_depth24_stencil8: os_type == super::OsType::Macos && device.d24_s8_supported(), + && device.supports32_bit_float_filtering()), + format_depth24_stencil8: os_type == super::OsType::Macos + && device.is_depth24_stencil8_pixel_format_supported(), format_depth32_stencil8_filter: os_type == super::OsType::Macos, format_depth32_stencil8_none: os_type != super::OsType::Macos, format_min_srgb_channels: if os_type == super::OsType::Macos { @@ -767,8 +768,7 @@ impl super::PrivateCapabilities { 64 }, max_buffer_size: if version.at_least((10, 14), (12, 0), (12, 0), (1, 0), os_type) { - let buffer_size: NSInteger = unsafe { msg_send![device.as_ref(), maxBufferLength] }; - buffer_size as _ + device.max_buffer_length() as u64 } else if os_type == super::OsType::Macos { 1 << 30 // 1GB on macOS 10.11 and up } else { @@ -1046,7 +1046,7 @@ impl super::PrivateCapabilities { ); features.set( F::DUAL_SOURCE_BLENDING, - self.msl_version >= MTLLanguageVersion::V1_2 && self.dual_source_blending, + self.msl_version >= MTLLanguageVersion::Version1_2 && self.dual_source_blending, ); features.set(F::TEXTURE_COMPRESSION_ASTC, self.format_astc); features.set(F::TEXTURE_COMPRESSION_ASTC_HDR, self.format_astc_hdr); @@ -1066,42 +1066,42 @@ impl super::PrivateCapabilities { | F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING | F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING | F::PARTIALLY_BOUND_BINDING_ARRAY, - self.msl_version >= MTLLanguageVersion::V3_0 + self.msl_version >= MTLLanguageVersion::Version3_0 && self.supports_arrays_of_textures && self .argument_buffers - .unwrap_or(MTLArgumentBuffersTier::Tier1) as u64 - >= MTLArgumentBuffersTier::Tier2 as u64, + .unwrap_or(MTLArgumentBuffersTier::Tier1) + >= MTLArgumentBuffersTier::Tier2, ); features.set( F::STORAGE_RESOURCE_BINDING_ARRAY, - self.msl_version >= MTLLanguageVersion::V3_0 + self.msl_version >= MTLLanguageVersion::Version3_0 && self.supports_arrays_of_textures && self.supports_arrays_of_textures_write && self .argument_buffers - .unwrap_or(MTLArgumentBuffersTier::Tier1) as u64 - >= MTLArgumentBuffersTier::Tier2 as u64, + .unwrap_or(MTLArgumentBuffersTier::Tier1) + >= MTLArgumentBuffersTier::Tier2, ); features.set( F::SHADER_INT64, - self.int64 && self.msl_version >= MTLLanguageVersion::V2_3, + self.int64 && self.msl_version >= MTLLanguageVersion::Version2_3, ); features.set( F::SHADER_INT64_ATOMIC_MIN_MAX, - self.int64_atomics_min_max && self.msl_version >= MTLLanguageVersion::V2_4, + self.int64_atomics_min_max && self.msl_version >= MTLLanguageVersion::Version2_4, ); features.set( F::TEXTURE_INT64_ATOMIC, - self.int64_atomics && self.msl_version >= MTLLanguageVersion::V3_1, + self.int64_atomics && self.msl_version >= MTLLanguageVersion::Version3_1, ); features.set( F::TEXTURE_ATOMIC, - self.msl_version >= MTLLanguageVersion::V3_1, + self.msl_version >= MTLLanguageVersion::Version3_1, ); features.set( F::SHADER_FLOAT32_ATOMIC, - self.float_atomics && self.msl_version >= MTLLanguageVersion::V3_0, + self.float_atomics && self.msl_version >= MTLLanguageVersion::Version3_0, ); features.set( @@ -1114,7 +1114,7 @@ impl super::PrivateCapabilities { features.set( F::SHADER_BARYCENTRICS, - self.shader_barycentrics && self.msl_version >= MTLLanguageVersion::V2_2, + self.shader_barycentrics && self.msl_version >= MTLLanguageVersion::Version2_2, ); if self.supports_simd_scoped_operations { @@ -1126,7 +1126,7 @@ impl super::PrivateCapabilities { // Cooperative matrix (simdgroup matrix) requires MSL 2.3+ features.set( F::EXPERIMENTAL_COOPERATIVE_MATRIX, - self.supports_cooperative_matrix && self.msl_version >= MTLLanguageVersion::V2_3, + self.supports_cooperative_matrix && self.msl_version >= MTLLanguageVersion::Version2_3, ); if self.supported_vertex_amplification_factor > 1 { @@ -1275,7 +1275,7 @@ impl super::PrivateCapabilities { /// /// Metal's simdgroup_matrix supports 8x8 tiles with f16 and f32 element types. fn cooperative_matrix_properties(&self) -> Vec { - if !self.supports_cooperative_matrix || self.msl_version < MTLLanguageVersion::V2_3 { + if !self.supports_cooperative_matrix || self.msl_version < MTLLanguageVersion::Version2_3 { return Vec::new(); } @@ -1482,8 +1482,8 @@ impl super::PrivateCapabilities { } impl super::PrivateDisabilities { - pub fn new(device: &metal::Device) -> Self { - let is_intel = device.name().starts_with("Intel"); + pub fn new(device: &ProtocolObject) -> Self { + let is_intel = device.name().to_string().starts_with("Intel"); Self { broken_viewport_near_depth: is_intel && !device.supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v4), @@ -1493,12 +1493,12 @@ impl super::PrivateDisabilities { } impl super::OsType { - fn new(version: NSOperatingSystemVersion, device: &metal::Device) -> Self { + fn new(version: NSOperatingSystemVersion, device: &ProtocolObject) -> Self { // Metal was first introduced in OS X 10.11 and iOS 8. The current version number of visionOS is 1.0.0. Additionally, // on the Simulator, Apple only provides the Apple2 GPU capability, and the Apple2+ GPU capability covers the capabilities of Apple2. // Therefore, the following conditions can be used to determine if it is visionOS. // https://developer.apple.com/documentation/metal/developing_metal_apps_that_run_in_simulator - let os_is_vision = version.major < 8 && device.supports_family(MTLGPUFamily::Apple2); + let os_is_vision = version.majorVersion < 8 && device.supports_family(MTLGPUFamily::Apple2); let os_is_mac = device.supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v1); let os_is_tvos = device.supports_feature_set(MTLFeatureSet::tvOS_GPUFamily1_v1); if os_is_vision { @@ -1513,22 +1513,24 @@ impl super::OsType { } } -#[repr(C)] -#[derive(Clone, Copy, Debug)] -#[allow(clippy::upper_case_acronyms)] -struct NSOperatingSystemVersion { - major: usize, - minor: usize, - patch: usize, +trait AtLeast { + fn at_least( + &self, + mac_version: (isize, isize), + ios_version: (isize, isize), + tvos_version: (isize, isize), + visionos_version: (isize, isize), + os_type: super::OsType, + ) -> bool; } -impl NSOperatingSystemVersion { +impl AtLeast for NSOperatingSystemVersion { fn at_least( &self, - mac_version: (usize, usize), - ios_version: (usize, usize), - tvos_version: (usize, usize), - visionos_version: (usize, usize), + mac_version: (isize, isize), + ios_version: (isize, isize), + tvos_version: (isize, isize), + visionos_version: (isize, isize), os_type: super::OsType, ) -> bool { let required = match os_type { @@ -1537,6 +1539,6 @@ impl NSOperatingSystemVersion { super::OsType::Tvos => tvos_version, super::OsType::VisionOs => visionos_version, }; - (self.major, self.minor) >= required + (self.majorVersion, self.minorVersion) >= required } } diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 276ac72c356..1318e0b54e9 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -1,14 +1,23 @@ -use super::{conv, AsNative, TimestampQuerySupport}; +use objc2::{ + rc::{autoreleasepool, Retained}, + runtime::ProtocolObject, +}; +use objc2_foundation::{NSRange, NSString, NSUInteger}; +use objc2_metal::{ + MTLBlitCommandEncoder, MTLBlitPassDescriptor, MTLBuffer, MTLCommandBuffer, MTLCommandEncoder, + MTLCommandQueue, MTLComputeCommandEncoder, MTLComputePassDescriptor, MTLCounterDontSample, + MTLIndexType, MTLLoadAction, MTLPrimitiveType, MTLRenderCommandEncoder, + MTLRenderPassDescriptor, MTLSamplerState, MTLScissorRect, MTLSize, MTLStoreAction, MTLTexture, + MTLVertexAmplificationViewMapping, MTLViewport, MTLVisibilityResultMode, +}; + +use super::{conv, TimestampQuerySupport}; use crate::CommandEncoder as _; use alloc::{ borrow::{Cow, ToOwned as _}, vec::Vec, }; -use core::ops::Range; -use metal::{ - MTLIndexType, MTLLoadAction, MTLPrimitiveType, MTLScissorRect, MTLSize, MTLStoreAction, - MTLViewport, MTLVisibilityResultMode, NSRange, NSUInteger, -}; +use core::{ops::Range, ptr::NonNull}; use smallvec::SmallVec; // has to match `Temp::binding_sizes` @@ -36,11 +45,11 @@ impl Default for super::CommandState { /// Combines [`naga::ShaderStage`] and an encoder of the appropriate type for /// that stage. enum Encoder<'e> { - Vertex(&'e metal::RenderCommandEncoder), - Fragment(&'e metal::RenderCommandEncoder), - Task(&'e metal::RenderCommandEncoder), - Mesh(&'e metal::RenderCommandEncoder), - Compute(&'e metal::ComputeCommandEncoder), + Vertex(&'e ProtocolObject), + Fragment(&'e ProtocolObject), + Task(&'e ProtocolObject), + Mesh(&'e ProtocolObject), + Compute(&'e ProtocolObject), } impl Encoder<'_> { @@ -56,56 +65,68 @@ impl Encoder<'_> { fn set_buffer( &self, + buffer: Option<&ProtocolObject>, + offset: NSUInteger, index: NSUInteger, - buffer: Option<&metal::BufferRef>, - offset: wgt::BufferAddress, ) { - match *self { - Self::Vertex(enc) => enc.set_vertex_buffer(index, buffer, offset), - Self::Fragment(enc) => enc.set_fragment_buffer(index, buffer, offset), - Self::Task(enc) => enc.set_object_buffer(index, buffer, offset), - Self::Mesh(enc) => enc.set_mesh_buffer(index, buffer, offset), - Self::Compute(enc) => enc.set_buffer(index, buffer, offset), + unsafe { + match *self { + Self::Vertex(enc) => enc.setVertexBuffer_offset_atIndex_(buffer, offset, index), + Self::Fragment(enc) => enc.setFragmentBuffer_offset_atIndex_(buffer, offset, index), + Self::Task(enc) => enc.setObjectBuffer_offset_atIndex_(buffer, offset, index), + Self::Mesh(enc) => enc.setMeshBuffer_offset_atIndex_(buffer, offset, index), + Self::Compute(enc) => enc.setBuffer_offset_atIndex_(buffer, offset, index), + } } } - fn set_bytes(&self, index: NSUInteger, length: u64, bytes: *const core::ffi::c_void) { - match *self { - Self::Vertex(enc) => enc.set_vertex_bytes(index, length, bytes), - Self::Fragment(enc) => enc.set_fragment_bytes(index, length, bytes), - Self::Task(enc) => enc.set_object_bytes(index, length, bytes), - Self::Mesh(enc) => enc.set_mesh_bytes(index, length, bytes), - Self::Compute(enc) => enc.set_bytes(index, length, bytes), + fn set_bytes(&self, bytes: NonNull, length: NSUInteger, index: NSUInteger) { + unsafe { + match *self { + Self::Vertex(enc) => enc.set_vertex_bytes_length_at_index(bytes, length, index), + Self::Fragment(enc) => enc.set_fragment_bytes_length_at_index(bytes, length, index), + Self::Task(enc) => enc.set_object_bytes_length_at_index(bytes, length, index), + Self::Mesh(enc) => enc.set_mesh_bytes_length_at_index(bytes, length, index), + Self::Compute(enc) => enc.set_bytes_length_at_index(bytes, length, index), + } } } - fn set_sampler_state(&self, index: NSUInteger, state: Option<&metal::SamplerStateRef>) { - match *self { - Self::Vertex(enc) => enc.set_vertex_sampler_state(index, state), - Self::Fragment(enc) => enc.set_fragment_sampler_state(index, state), - Self::Task(enc) => enc.set_object_sampler_state(index, state), - Self::Mesh(enc) => enc.set_mesh_sampler_state(index, state), - Self::Compute(enc) => enc.set_sampler_state(index, state), + fn set_sampler_state( + &self, + state: Option<&ProtocolObject>, + index: NSUInteger, + ) { + unsafe { + match *self { + Self::Vertex(enc) => enc.set_vertex_sampler_state_at_index(state, index), + Self::Fragment(enc) => enc.set_fragment_sampler_state_at_index(state, index), + Self::Task(enc) => enc.set_object_sampler_state_at_index(state, index), + Self::Mesh(enc) => enc.set_mesh_sampler_state_at_index(state, index), + Self::Compute(enc) => enc.set_sampler_state_at_index(state, index), + } } } - fn set_texture(&self, index: NSUInteger, texture: Option<&metal::TextureRef>) { - match *self { - Self::Vertex(enc) => enc.set_vertex_texture(index, texture), - Self::Fragment(enc) => enc.set_fragment_texture(index, texture), - Self::Task(enc) => enc.set_object_texture(index, texture), - Self::Mesh(enc) => enc.set_mesh_texture(index, texture), - Self::Compute(enc) => enc.set_texture(index, texture), + fn set_texture(&self, texture: Option<&ProtocolObject>, index: NSUInteger) { + unsafe { + match *self { + Self::Vertex(enc) => enc.set_vertex_texture_at_index(texture, index), + Self::Fragment(enc) => enc.set_fragment_texture_at_index(texture, index), + Self::Task(enc) => enc.set_object_texture_at_index(texture, index), + Self::Mesh(enc) => enc.set_mesh_texture_at_index(texture, index), + Self::Compute(enc) => enc.set_texture_at_index(texture, index), + } } } } impl super::CommandEncoder { - pub fn raw_command_buffer(&self) -> Option<&metal::CommandBuffer> { - self.raw_cmd_buf.as_ref() + pub fn raw_command_buffer(&self) -> Option<&ProtocolObject> { + self.raw_cmd_buf.as_deref() } - fn enter_blit(&mut self) -> &metal::BlitCommandEncoderRef { + fn enter_blit(&mut self) -> Retained> { if self.state.blit.is_none() { debug_assert!(self.state.render.is_none() && self.state.compute.is_none()); let cmd_buf = self.raw_cmd_buf.as_ref().unwrap(); @@ -132,36 +153,41 @@ impl super::CommandEncoder { .contains(TimestampQuerySupport::ON_BLIT_ENCODER); if !self.state.pending_timer_queries.is_empty() && !supports_sample_counters_in_buffer { - objc::rc::autoreleasepool(|| { - let descriptor = metal::BlitPassDescriptor::new(); + autoreleasepool(|_| { + let descriptor = MTLBlitPassDescriptor::new(); let mut last_query = None; for (i, (set, index)) in self.state.pending_timer_queries.drain(..).enumerate() { - let sba_descriptor = descriptor - .sample_buffer_attachments() - .object_at(i as _) - .unwrap(); + let sba_descriptor = unsafe { + descriptor + .sample_buffer_attachments() + .object_at_indexed_subscript(i) + }; sba_descriptor - .set_sample_buffer(set.counter_sample_buffer.as_ref().unwrap()); + .set_sample_buffer(Some(set.counter_sample_buffer.as_ref().unwrap())); // Here be dragons: // As mentioned above, for some reasons using the start of the encoder won't yield any results sometimes! - sba_descriptor - .set_start_of_encoder_sample_index(metal::COUNTER_DONT_SAMPLE); - sba_descriptor.set_end_of_encoder_sample_index(index as _); + unsafe { + sba_descriptor.set_start_of_encoder_sample_index(MTLCounterDontSample) + }; + unsafe { sba_descriptor.set_end_of_encoder_sample_index(index as _) }; last_query = Some((set, index)); } - let encoder = cmd_buf.blit_command_encoder_with_descriptor(descriptor); + let encoder = cmd_buf + .blit_command_encoder_with_descriptor(&descriptor) + .unwrap(); // As explained above, we need to do some write: // Conveniently, we have a buffer with every query set, that we can use for this for a dummy write, // since we know that it is going to be overwritten again on timer resolve and HAL doesn't define its state before that. let raw_range = NSRange { - location: last_query.as_ref().unwrap().1 as u64 * crate::QUERY_SIZE, + location: last_query.as_ref().unwrap().1 as usize + * crate::QUERY_SIZE as usize, length: 1, }; - encoder.fill_buffer( + encoder.fill_buffer_range_value( &last_query.as_ref().unwrap().0.raw_buffer, raw_range, 255, // Don't write 0, so it's easier to identify if something went wrong. @@ -171,8 +197,8 @@ impl super::CommandEncoder { }); } - objc::rc::autoreleasepool(|| { - self.state.blit = Some(cmd_buf.new_blit_command_encoder().to_owned()); + autoreleasepool(|_| { + self.state.blit = Some(cmd_buf.blit_command_encoder().unwrap()); }); let encoder = self.state.blit.as_ref().unwrap(); @@ -181,14 +207,16 @@ impl super::CommandEncoder { // If the above described issue with empty blit encoder applies to `sample_counters_in_buffer` as well, we should use the same workaround instead! for (set, index) in self.state.pending_timer_queries.drain(..) { debug_assert!(supports_sample_counters_in_buffer); - encoder.sample_counters_in_buffer( - set.counter_sample_buffer.as_ref().unwrap(), - index as _, - true, - ) + unsafe { + encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + set.counter_sample_buffer.as_ref().unwrap(), + index as _, + true, + ) + } } } - self.state.blit.as_ref().unwrap() + self.state.blit.as_ref().unwrap().clone() } pub(super) fn leave_blit(&mut self) { @@ -197,13 +225,13 @@ impl super::CommandEncoder { } } - fn active_encoder(&mut self) -> Option<&metal::CommandEncoderRef> { + fn active_encoder(&mut self) -> Option<&ProtocolObject> { if let Some(ref encoder) = self.state.render { - Some(encoder) + Some(ProtocolObject::from_ref(&**encoder)) } else if let Some(ref encoder) = self.state.compute { - Some(encoder) + Some(ProtocolObject::from_ref(&**encoder)) } else if let Some(ref encoder) = self.state.blit { - Some(encoder) + Some(ProtocolObject::from_ref(&**encoder)) } else { None } @@ -242,13 +270,13 @@ impl super::CommandEncoder { let mut changes_sizes_buffer = false; for index in 0..buffers { let buf = &group.buffers[(index_base.buffers + index) as usize]; + let buffer = Some(unsafe { buf.ptr.as_ref() }); let mut offset = buf.offset; if let Some(dyn_index) = buf.dynamic_index { offset += dynamic_offsets[dyn_index as usize] as wgt::BufferAddress; } - let index = (resource_indices.buffers + index) as u64; - let buffer = Some(buf.ptr.as_native()); - encoder.set_buffer(index, buffer, offset); + let index = (resource_indices.buffers + index) as usize; + encoder.set_buffer(buffer, offset as usize, index); if let Some(size) = buf.binding_size { let br = naga::ResourceBinding { group: group_index, @@ -263,10 +291,10 @@ impl super::CommandEncoder { .state .make_sizes_buffer_update(encoder.stage(), &mut self.temp.binding_sizes) { + let bytes_ptr = NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(); + let length = sizes.len() * WORD_SIZE; let index = index as _; - let length = (sizes.len() * WORD_SIZE) as u64; - let bytes_ptr = sizes.as_ptr().cast(); - encoder.set_bytes(index, length, bytes_ptr); + encoder.set_bytes(bytes_ptr, length, index); } } let samplers = match encoder.stage() { @@ -278,9 +306,9 @@ impl super::CommandEncoder { }; for index in 0..samplers { let res = group.samplers[(index_base.samplers + index) as usize]; - let index = (resource_indices.samplers + index) as u64; - let state = Some(res.as_native()); - encoder.set_sampler_state(index, state); + let index = (resource_indices.samplers + index) as usize; + let state = Some(unsafe { res.as_ref() }); + encoder.set_sampler_state(state, index); } let textures = match encoder.stage() { @@ -292,9 +320,9 @@ impl super::CommandEncoder { }; for index in 0..textures { let res = group.textures[(index_base.textures + index) as usize]; - let index = (resource_indices.textures + index) as u64; - let texture = Some(res.as_native()); - encoder.set_texture(index, texture); + let index = (resource_indices.textures + index) as usize; + let texture = Some(unsafe { res.as_ref() }); + encoder.set_texture(texture, index); } } } @@ -350,14 +378,15 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> { let queue = &self.raw_queue.lock(); let retain_references = self.shared.settings.retain_command_buffer_references; - let raw = objc::rc::autoreleasepool(move || { + let raw = autoreleasepool(move |_| { let cmd_buf_ref = if retain_references { - queue.new_command_buffer() + queue.command_buffer() } else { - queue.new_command_buffer_with_unretained_references() - }; + queue.command_buffer_with_unretained_references() + } + .unwrap(); if let Some(label) = label { - cmd_buf_ref.set_label(label); + cmd_buf_ref.set_label(Some(&NSString::from_str(label))); } cmd_buf_ref.to_owned() }); @@ -418,7 +447,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) { let encoder = self.enter_blit(); - encoder.fill_buffer(&buffer.raw, conv::map_range(&range), 0); + encoder.fill_buffer_range_value(&buffer.raw, conv::map_range(&range), 0); } unsafe fn copy_buffer_to_buffer( @@ -431,13 +460,15 @@ impl crate::CommandEncoder for super::CommandEncoder { { let encoder = self.enter_blit(); for copy in regions { - encoder.copy_from_buffer( - &src.raw, - copy.src_offset, - &dst.raw, - copy.dst_offset, - copy.size.get(), - ); + unsafe { + encoder.copy_from_buffer_source_offset_to_buffer_destination_offset_size( + &src.raw, + copy.src_offset as usize, + &dst.raw, + copy.dst_offset as usize, + copy.size.get() as usize, + ) + }; } } @@ -452,8 +483,10 @@ impl crate::CommandEncoder for super::CommandEncoder { { let dst_texture = if src.format != dst.format { let raw_format = self.shared.private_caps.map_format(src.format); - Cow::Owned(objc::rc::autoreleasepool(|| { - dst.raw.new_texture_view(raw_format) + Cow::Owned(autoreleasepool(|_| { + dst.raw + .new_texture_view_with_pixel_format(raw_format) + .unwrap() })) } else { Cow::Borrowed(&dst.raw) @@ -464,17 +497,19 @@ impl crate::CommandEncoder for super::CommandEncoder { let dst_origin = conv::map_origin(©.dst_base.origin); // no clamping is done: Metal expects physical sizes here let extent = conv::map_copy_extent(©.size); - encoder.copy_from_texture( - &src.raw, - copy.src_base.array_layer as u64, - copy.src_base.mip_level as u64, - src_origin, - extent, - &dst_texture, - copy.dst_base.array_layer as u64, - copy.dst_base.mip_level as u64, - dst_origin, - ); + unsafe { + encoder.copy_from_texture_source_slice_source_level_source_origin_source_size_to_texture_destination_slice_destination_level_destination_origin( + &src.raw, + copy.src_base.array_layer as usize, + copy.src_base.mip_level as usize, + src_origin, + extent, + &dst_texture, + copy.dst_base.array_layer as usize, + copy.dst_base.mip_level as usize, + dst_origin, + ) + }; } } @@ -505,18 +540,20 @@ impl crate::CommandEncoder for super::CommandEncoder { // the amount of data to copy. 0 }; - encoder.copy_from_buffer_to_texture( - &src.raw, - copy.buffer_layout.offset, - bytes_per_row, - image_byte_stride, - conv::map_copy_extent(&extent), - &dst.raw, - copy.texture_base.array_layer as u64, - copy.texture_base.mip_level as u64, - dst_origin, - conv::get_blit_option(dst.format, copy.texture_base.aspect), - ); + unsafe { + encoder.copy_from_buffer_source_offset_source_bytes_per_row_source_bytes_per_image_source_size_to_texture_destination_slice_destination_level_destination_origin_options( + &src.raw, + copy.buffer_layout.offset as usize, + bytes_per_row as usize, + image_byte_stride as usize, + conv::map_copy_extent(&extent), + &dst.raw, + copy.texture_base.array_layer as usize, + copy.texture_base.mip_level as usize, + dst_origin, + conv::get_blit_option(dst.format, copy.texture_base.aspect), + ) + }; } } @@ -542,18 +579,20 @@ impl crate::CommandEncoder for super::CommandEncoder { .buffer_layout .rows_per_image .map_or(0, |v| v as u64 * bytes_per_row); - encoder.copy_from_texture_to_buffer( - &src.raw, - copy.texture_base.array_layer as u64, - copy.texture_base.mip_level as u64, - src_origin, - conv::map_copy_extent(&extent), - &dst.raw, - copy.buffer_layout.offset, - bytes_per_row, - bytes_per_image, - conv::get_blit_option(src.format, copy.texture_base.aspect), - ); + unsafe { + encoder.copy_from_texture_source_slice_source_level_source_origin_source_size_to_buffer_destination_offset_destination_bytes_per_row_destination_bytes_per_image_options( + &src.raw, + copy.texture_base.array_layer as usize, + copy.texture_base.mip_level as usize, + src_origin, + conv::map_copy_extent(&extent), + &dst.raw, + copy.buffer_layout.offset as usize, + bytes_per_row as usize, + bytes_per_image as usize, + conv::get_blit_option(src.format, copy.texture_base.aspect), + ) + }; } } @@ -573,9 +612,9 @@ impl crate::CommandEncoder for super::CommandEncoder { .render .as_ref() .unwrap() - .set_visibility_result_mode( + .set_visibility_result_mode_offset( MTLVisibilityResultMode::Boolean, - index as u64 * crate::QUERY_SIZE, + index as usize * crate::QUERY_SIZE as usize, ); } _ => {} @@ -588,7 +627,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .render .as_ref() .unwrap() - .set_visibility_result_mode(MTLVisibilityResultMode::Disabled, 0); + .set_visibility_result_mode_offset(MTLVisibilityResultMode::Disabled, 0); } _ => {} } @@ -608,17 +647,35 @@ impl crate::CommandEncoder for super::CommandEncoder { support.contains(TimestampQuerySupport::ON_BLIT_ENCODER), self.state.blit.as_ref(), ) { - encoder.sample_counters_in_buffer(sample_buffer, index as _, with_barrier); + unsafe { + encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + sample_buffer, + index as _, + with_barrier, + ) + }; } else if let (true, Some(encoder)) = ( support.contains(TimestampQuerySupport::ON_RENDER_ENCODER), self.state.render.as_ref(), ) { - encoder.sample_counters_in_buffer(sample_buffer, index as _, with_barrier); + unsafe { + encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + sample_buffer, + index as _, + with_barrier, + ) + }; } else if let (true, Some(encoder)) = ( support.contains(TimestampQuerySupport::ON_COMPUTE_ENCODER), self.state.compute.as_ref(), ) { - encoder.sample_counters_in_buffer(sample_buffer, index as _, with_barrier); + unsafe { + encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + sample_buffer, + index as _, + with_barrier, + ) + }; } else { // If we're here it means we either have no encoder open, or it's not supported to sample within them. // If this happens with render/compute open, this is an invalid usage! @@ -635,10 +692,10 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn reset_queries(&mut self, set: &super::QuerySet, range: Range) { let encoder = self.enter_blit(); let raw_range = NSRange { - location: range.start as u64 * crate::QUERY_SIZE, - length: (range.end - range.start) as u64 * crate::QUERY_SIZE, + location: range.start as usize * crate::QUERY_SIZE as usize, + length: (range.end - range.start) as usize * crate::QUERY_SIZE as usize, }; - encoder.fill_buffer(&set.raw_buffer, raw_range, 0); + encoder.fill_buffer_range_value(&set.raw_buffer, raw_range, 0); } unsafe fn copy_query_results( @@ -653,21 +710,25 @@ impl crate::CommandEncoder for super::CommandEncoder { match set.ty { wgt::QueryType::Occlusion => { let size = (range.end - range.start) as u64 * crate::QUERY_SIZE; - encoder.copy_from_buffer( - &set.raw_buffer, - range.start as u64 * crate::QUERY_SIZE, - &buffer.raw, - offset, - size, - ); + unsafe { + encoder.copy_from_buffer_source_offset_to_buffer_destination_offset_size( + &set.raw_buffer, + range.start as usize * crate::QUERY_SIZE as usize, + &buffer.raw, + offset as usize, + size as usize, + ) + }; } wgt::QueryType::Timestamp => { - encoder.resolve_counters( - set.counter_sample_buffer.as_ref().unwrap(), - NSRange::new(range.start as u64, (range.end - range.start) as u64), - &buffer.raw, - offset, - ); + unsafe { + encoder.resolve_counters_in_range_destination_buffer_destination_offset( + set.counter_sample_buffer.as_ref().unwrap(), + NSRange::new(range.start as usize, (range.end - range.start) as usize), + &buffer.raw, + offset as usize, + ) + }; } wgt::QueryType::PipelineStatistics(_) => todo!(), } @@ -686,15 +747,19 @@ impl crate::CommandEncoder for super::CommandEncoder { assert!(self.state.compute.is_none()); assert!(self.state.render.is_none()); - objc::rc::autoreleasepool(|| { - let descriptor = metal::RenderPassDescriptor::new(); + autoreleasepool(|_| { + let descriptor = MTLRenderPassDescriptor::new(); for (i, at) in desc.color_attachments.iter().enumerate() { if let Some(at) = at.as_ref() { - let at_descriptor = descriptor.color_attachments().object_at(i as u64).unwrap(); + let at_descriptor = unsafe { + descriptor + .color_attachments() + .object_at_indexed_subscript(i) + }; at_descriptor.set_texture(Some(&at.target.view.raw)); if let Some(depth_slice) = at.depth_slice { - at_descriptor.set_depth_plane(depth_slice as u64); + at_descriptor.set_depth_plane(depth_slice as usize); } if let Some(ref resolve) = at.resolve_target { //Note: the selection of levels and slices is already handled by `TextureView` @@ -721,7 +786,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if let Some(ref at) = desc.depth_stencil_attachment { if at.target.view.aspects.contains(crate::FormatAspects::DEPTH) { - let at_descriptor = descriptor.depth_attachment().unwrap(); + let at_descriptor = descriptor.depth_attachment(); at_descriptor.set_texture(Some(&at.target.view.raw)); let load_action = if at.depth_ops.contains(crate::AttachmentOps::LOAD) { @@ -748,7 +813,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .aspects .contains(crate::FormatAspects::STENCIL) { - let at_descriptor = descriptor.stencil_attachment().unwrap(); + let at_descriptor = descriptor.stencil_attachment(); at_descriptor.set_texture(Some(&at.target.view.raw)); let load_action = if at.stencil_ops.contains(crate::AttachmentOps::LOAD) { @@ -776,13 +841,14 @@ impl crate::CommandEncoder for super::CommandEncoder { let mut sba_index = 0; let mut next_sba_descriptor = || { - let sba_descriptor = descriptor - .sample_buffer_attachments() - .object_at(sba_index) - .unwrap(); + let sba_descriptor = unsafe { + descriptor + .sample_buffer_attachments() + .object_at_indexed_subscript(sba_index) + }; - sba_descriptor.set_end_of_vertex_sample_index(metal::COUNTER_DONT_SAMPLE); - sba_descriptor.set_start_of_fragment_sample_index(metal::COUNTER_DONT_SAMPLE); + unsafe { sba_descriptor.set_end_of_vertex_sample_index(MTLCounterDontSample) }; + unsafe { sba_descriptor.set_start_of_fragment_sample_index(MTLCounterDontSample) }; sba_index += 1; sba_descriptor @@ -790,31 +856,35 @@ impl crate::CommandEncoder for super::CommandEncoder { for (set, index) in self.state.pending_timer_queries.drain(..) { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer(set.counter_sample_buffer.as_ref().unwrap()); - sba_descriptor.set_start_of_vertex_sample_index(index as _); - sba_descriptor.set_end_of_fragment_sample_index(metal::COUNTER_DONT_SAMPLE); + sba_descriptor.set_sample_buffer(Some(set.counter_sample_buffer.as_ref().unwrap())); + unsafe { sba_descriptor.set_start_of_vertex_sample_index(index as _) }; + unsafe { sba_descriptor.set_end_of_fragment_sample_index(MTLCounterDontSample) }; } if let Some(ref timestamp_writes) = desc.timestamp_writes { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer( + sba_descriptor.set_sample_buffer(Some( timestamp_writes .query_set .counter_sample_buffer .as_ref() .unwrap(), - ); + )); - sba_descriptor.set_start_of_vertex_sample_index( - timestamp_writes - .beginning_of_pass_write_index - .map_or(metal::COUNTER_DONT_SAMPLE, |i| i as _), - ); - sba_descriptor.set_end_of_fragment_sample_index( - timestamp_writes - .end_of_pass_write_index - .map_or(metal::COUNTER_DONT_SAMPLE, |i| i as _), - ); + unsafe { + sba_descriptor.set_start_of_vertex_sample_index( + timestamp_writes + .beginning_of_pass_write_index + .map_or(MTLCounterDontSample, |i| i as _), + ) + }; + unsafe { + sba_descriptor.set_end_of_fragment_sample_index( + timestamp_writes + .end_of_pass_write_index + .map_or(MTLCounterDontSample, |i| i as _), + ) + }; } if let Some(occlusion_query_set) = desc.occlusion_query_set { @@ -827,31 +897,37 @@ impl crate::CommandEncoder for super::CommandEncoder { // However, when I don't set this, I get undefined behavior in nonzero layers, and all non-apple examples of vertex amplification set it. // So this is just one of those undocumented requirements. if let Some(mv) = desc.multiview_mask { - descriptor.set_render_target_array_length(32 - mv.leading_zeros() as u64); + descriptor.set_render_target_array_length(32 - mv.leading_zeros() as usize); } let raw = self.raw_cmd_buf.as_ref().unwrap(); - let encoder = raw.new_render_command_encoder(descriptor); + let encoder = raw + .render_command_encoder_with_descriptor(&descriptor) + .unwrap(); if let Some(mv) = desc.multiview_mask { // Most likely the API just wasn't thought about enough. It's not like they ever allow you // to use enough views to overflow a 32-bit bitmask. let mv = mv.get(); let msb = 32 - mv.leading_zeros(); - let mut maps: SmallVec<[metal::VertexAmplificationViewMapping; 32]> = - SmallVec::new(); + let mut maps: SmallVec<[MTLVertexAmplificationViewMapping; 32]> = SmallVec::new(); for i in 0..msb { if (mv & (1 << i)) != 0 { - maps.push(metal::VertexAmplificationViewMapping { + maps.push(MTLVertexAmplificationViewMapping { renderTargetArrayIndexOffset: i, viewportArrayIndexOffset: i, }); } } - encoder.set_vertex_amplification_count(mv.count_ones() as u64, Some(&maps)); + unsafe { + encoder.set_vertex_amplification_count_view_mappings( + mv.count_ones() as usize, + maps.as_ptr(), + ) + }; } if let Some(label) = desc.label { - encoder.set_label(label); + encoder.set_label(Some(&NSString::from_str(label))); } - self.state.render = Some(encoder.to_owned()); + self.state.render = Some(encoder); }); Ok(()) @@ -918,7 +994,11 @@ impl crate::CommandEncoder for super::CommandEncoder { ); // Call useResource on all textures and buffers used indirectly so they are alive for (resource, use_info) in group.resources_to_use.iter() { - encoder.use_resource_at(resource.as_native(), use_info.uses, use_info.stages); + encoder.use_resource_usage_stages( + unsafe { resource.as_ref() }, + use_info.uses, + use_info.stages, + ); } } if let Some(encoder) = compute_encoder { @@ -948,7 +1028,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if !use_info.visible_in_compute { continue; } - encoder.use_resource(resource.as_native(), use_info.uses); + encoder.use_resource_usage(unsafe { resource.as_ref() }, use_info.uses); } } } @@ -968,44 +1048,55 @@ impl crate::CommandEncoder for super::CommandEncoder { let offset_words = offset_bytes as usize / WORD_SIZE; state_pc[offset_words..offset_words + data.len()].copy_from_slice(data); + let bytes = NonNull::new(state_pc.as_ptr().cast_mut().cast()).unwrap(); if let Some(ref compute) = self.state.compute { - compute.set_bytes( - layout.immediates_infos.cs.unwrap().buffer_index as _, - (layout.total_immediates as usize * WORD_SIZE) as _, - state_pc.as_ptr().cast(), - ) + unsafe { + compute.set_bytes_length_at_index( + bytes, + layout.total_immediates as usize * WORD_SIZE, + layout.immediates_infos.cs.unwrap().buffer_index as usize, + ) + }; } if let Some(ref render) = self.state.render { if let Some(vs) = layout.immediates_infos.vs { - render.set_vertex_bytes( - vs.buffer_index as _, - (layout.total_immediates as usize * WORD_SIZE) as _, - state_pc.as_ptr().cast(), - ) + unsafe { + render.set_vertex_bytes_length_at_index( + bytes, + layout.total_immediates as usize * WORD_SIZE, + vs.buffer_index as _, + ) + } } if let Some(fs) = layout.immediates_infos.fs { - render.set_fragment_bytes( - fs.buffer_index as _, - (layout.total_immediates as usize * WORD_SIZE) as _, - state_pc.as_ptr().cast(), - ) + unsafe { + render.set_fragment_bytes_length_at_index( + bytes, + layout.total_immediates as usize * WORD_SIZE, + fs.buffer_index as _, + ) + } } if let Some(ts) = layout.immediates_infos.ts { if self.shared.private_caps.mesh_shaders { - render.set_object_bytes( - ts.buffer_index as _, - (layout.total_immediates as usize * WORD_SIZE) as _, - state_pc.as_ptr().cast(), - ) + unsafe { + render.set_object_bytes_length_at_index( + bytes, + layout.total_immediates as usize * WORD_SIZE, + ts.buffer_index as _, + ) + } } } if let Some(ms) = layout.immediates_infos.ms { if self.shared.private_caps.mesh_shaders { - render.set_object_bytes( - ms.buffer_index as _, - (layout.total_immediates as usize * WORD_SIZE) as _, - state_pc.as_ptr().cast(), - ) + unsafe { + render.set_object_bytes_length_at_index( + bytes, + layout.total_immediates as usize * WORD_SIZE, + ms.buffer_index as _, + ) + } } } } @@ -1013,14 +1104,14 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn insert_debug_marker(&mut self, label: &str) { if let Some(encoder) = self.active_encoder() { - encoder.insert_debug_signpost(label); + encoder.insert_debug_signpost(&NSString::from_str(label)); } } unsafe fn begin_debug_marker(&mut self, group_label: &str) { if let Some(encoder) = self.active_encoder() { - encoder.push_debug_group(group_label); + encoder.push_debug_group(&NSString::from_str(group_label)); } else if let Some(ref buf) = self.raw_cmd_buf { - buf.push_debug_group(group_label); + buf.push_debug_group(&NSString::from_str(group_label)); } } unsafe fn end_debug_marker(&mut self) { @@ -1059,8 +1150,12 @@ impl crate::CommandEncoder for super::CommandEncoder { encoder.set_depth_clip_mode(depth_clip); } if let Some((ref state, bias)) = pipeline.depth_stencil { - encoder.set_depth_stencil_state(state); - encoder.set_depth_bias(bias.constant as f32, bias.slope_scale, bias.clamp); + encoder.set_depth_stencil_state(Some(state)); + encoder.set_depth_bias_slope_scale_clamp( + bias.constant as f32, + bias.slope_scale, + bias.clamp, + ); } if pipeline.vs_info.is_some() { @@ -1068,11 +1163,13 @@ impl crate::CommandEncoder for super::CommandEncoder { .state .make_sizes_buffer_update(naga::ShaderStage::Vertex, &mut self.temp.binding_sizes) { - encoder.set_vertex_bytes( - index as _, - (sizes.len() * WORD_SIZE) as u64, - sizes.as_ptr().cast(), - ); + unsafe { + encoder.set_vertex_bytes_length_at_index( + NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), + sizes.len() * WORD_SIZE, + index as _, + ) + }; } } if pipeline.fs_info.is_some() { @@ -1080,11 +1177,13 @@ impl crate::CommandEncoder for super::CommandEncoder { .state .make_sizes_buffer_update(naga::ShaderStage::Fragment, &mut self.temp.binding_sizes) { - encoder.set_fragment_bytes( - index as _, - (sizes.len() * WORD_SIZE) as u64, - sizes.as_ptr().cast(), - ); + unsafe { + encoder.set_fragment_bytes_length_at_index( + NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), + sizes.len() * WORD_SIZE, + index as _, + ) + }; } } if let Some(ts_info) = &pipeline.ts_info { @@ -1106,18 +1205,22 @@ impl crate::CommandEncoder for super::CommandEncoder { let size = pipeline_size.next_multiple_of(16); if *cur_size != size { *cur_size = size; - encoder.set_object_threadgroup_memory_length(index as _, size as _); + unsafe { + encoder.set_object_threadgroup_memory_length_at_index(size as _, index) + }; } } if let Some((index, sizes)) = self .state .make_sizes_buffer_update(naga::ShaderStage::Task, &mut self.temp.binding_sizes) { - encoder.set_object_bytes( - index as _, - (sizes.len() * WORD_SIZE) as u64, - sizes.as_ptr().cast(), - ); + unsafe { + encoder.set_object_bytes_length_at_index( + NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), + sizes.len() * WORD_SIZE, + index as _, + ) + }; } } if let Some(_ms_info) = &pipeline.ms_info { @@ -1130,11 +1233,13 @@ impl crate::CommandEncoder for super::CommandEncoder { .state .make_sizes_buffer_update(naga::ShaderStage::Mesh, &mut self.temp.binding_sizes) { - encoder.set_mesh_bytes( - index as _, - (sizes.len() * WORD_SIZE) as u64, - sizes.as_ptr().cast(), - ); + unsafe { + encoder.set_mesh_bytes_length_at_index( + NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), + sizes.len() * WORD_SIZE, + index as _, + ) + }; } } } @@ -1149,7 +1254,7 @@ impl crate::CommandEncoder for super::CommandEncoder { wgt::IndexFormat::Uint32 => (4, MTLIndexType::UInt32), }; self.state.index = Some(super::IndexState { - buffer_ptr: AsNative::from(binding.buffer.raw.as_ref()), + buffer_ptr: NonNull::from(&*binding.buffer.raw), offset: binding.offset, stride, raw_type, @@ -1163,7 +1268,13 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let buffer_index = self.shared.private_caps.max_vertex_buffers as u64 - 1 - index as u64; let encoder = self.state.render.as_ref().unwrap(); - encoder.set_vertex_buffer(buffer_index, Some(&binding.buffer.raw), binding.offset); + unsafe { + encoder.setVertexBuffer_offset_atIndex_( + Some(&binding.buffer.raw), + binding.offset as usize, + buffer_index as usize, + ) + }; let buffer_size = binding.resolve_size(); if buffer_size > 0 { @@ -1179,11 +1290,13 @@ impl crate::CommandEncoder for super::CommandEncoder { .state .make_sizes_buffer_update(naga::ShaderStage::Vertex, &mut self.temp.binding_sizes) { - encoder.set_vertex_bytes( - index as _, - (sizes.len() * WORD_SIZE) as u64, - sizes.as_ptr().cast(), - ); + unsafe { + encoder.set_vertex_bytes_length_at_index( + NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), + sizes.len() * WORD_SIZE, + index as _, + ) + }; } } @@ -1216,11 +1329,11 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn set_stencil_reference(&mut self, value: u32) { let encoder = self.state.render.as_ref().unwrap(); - encoder.set_stencil_front_back_reference_value(value, value); + encoder.set_stencil_front_reference_value_back_reference_value(value, value); } unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) { let encoder = self.state.render.as_ref().unwrap(); - encoder.set_blend_color(color[0], color[1], color[2], color[3]); + encoder.set_blend_color_red_green_blue_alpha(color[0], color[1], color[2], color[3]); } unsafe fn draw( @@ -1232,26 +1345,32 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let encoder = self.state.render.as_ref().unwrap(); if first_instance != 0 { - encoder.draw_primitives_instanced_base_instance( - self.state.raw_primitive_type, - first_vertex as _, - vertex_count as _, - instance_count as _, - first_instance as _, - ); + unsafe { + encoder.draw_primitives_vertex_start_vertex_count_instance_count_base_instance( + self.state.raw_primitive_type, + first_vertex as _, + vertex_count as _, + instance_count as _, + first_instance as _, + ) + }; } else if instance_count != 1 { - encoder.draw_primitives_instanced( - self.state.raw_primitive_type, - first_vertex as _, - vertex_count as _, - instance_count as _, - ); + unsafe { + encoder.draw_primitives_vertex_start_vertex_count_instance_count( + self.state.raw_primitive_type, + first_vertex as _, + vertex_count as _, + instance_count as _, + ) + }; } else { - encoder.draw_primitives( - self.state.raw_primitive_type, - first_vertex as _, - vertex_count as _, - ); + unsafe { + encoder.draw_primitives_vertex_start_vertex_count( + self.state.raw_primitive_type, + first_vertex as _, + vertex_count as _, + ) + }; } } @@ -1265,35 +1384,41 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let encoder = self.state.render.as_ref().unwrap(); let index = self.state.index.as_ref().unwrap(); - let offset = index.offset + index.stride * first_index as wgt::BufferAddress; + let offset = (index.offset + index.stride * first_index as wgt::BufferAddress) as usize; if base_vertex != 0 || first_instance != 0 { - encoder.draw_indexed_primitives_instanced_base_instance( - self.state.raw_primitive_type, - index_count as _, - index.raw_type, - index.buffer_ptr.as_native(), - offset, - instance_count as _, - base_vertex as _, - first_instance as _, - ); + unsafe { + encoder.draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_offset_instance_count_base_vertex_base_instance( + self.state.raw_primitive_type, + index_count as _, + index.raw_type, + index.buffer_ptr.as_ref(), + offset, + instance_count as _, + base_vertex as _, + first_instance as _, + ) + }; } else if instance_count != 1 { - encoder.draw_indexed_primitives_instanced( - self.state.raw_primitive_type, - index_count as _, - index.raw_type, - index.buffer_ptr.as_native(), - offset, - instance_count as _, - ); + unsafe { + encoder.draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_offset_instance_count( + self.state.raw_primitive_type, + index_count as _, + index.raw_type, + index.buffer_ptr.as_ref(), + offset, + instance_count as _, + ) + }; } else { - encoder.draw_indexed_primitives( - self.state.raw_primitive_type, - index_count as _, - index.raw_type, - index.buffer_ptr.as_native(), - offset, - ); + unsafe { + encoder.draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_offset( + self.state.raw_primitive_type, + index_count as _, + index.raw_type, + index.buffer_ptr.as_ref(), + offset, + ) + }; } } @@ -1305,11 +1430,11 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let encoder = self.state.render.as_ref().unwrap(); let size = MTLSize { - width: group_count_x as u64, - height: group_count_y as u64, - depth: group_count_z as u64, + width: group_count_x as usize, + height: group_count_y as usize, + depth: group_count_z as usize, }; - encoder.draw_mesh_threadgroups( + encoder.draw_mesh_threadgroups_threads_per_object_threadgroup_threads_per_mesh_threadgroup( size, self.state.stage_infos.ts.raw_wg_size, self.state.stage_infos.ms.raw_wg_size, @@ -1324,7 +1449,13 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let encoder = self.state.render.as_ref().unwrap(); for _ in 0..draw_count { - encoder.draw_primitives_indirect(self.state.raw_primitive_type, &buffer.raw, offset); + unsafe { + encoder.draw_primitives_indirect_buffer_indirect_buffer_offset( + self.state.raw_primitive_type, + &buffer.raw, + offset as usize, + ) + }; offset += size_of::() as wgt::BufferAddress; } } @@ -1338,14 +1469,16 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.render.as_ref().unwrap(); let index = self.state.index.as_ref().unwrap(); for _ in 0..draw_count { - encoder.draw_indexed_primitives_indirect( - self.state.raw_primitive_type, - index.raw_type, - index.buffer_ptr.as_native(), - index.offset, - &buffer.raw, - offset, - ); + unsafe { + encoder.draw_indexed_primitives_index_type_index_buffer_index_buffer_offset_indirect_buffer_indirect_buffer_offset( + self.state.raw_primitive_type, + index.raw_type, + index.buffer_ptr.as_ref(), + index.offset as usize, + &buffer.raw, + offset as usize, + ) + }; offset += size_of::() as wgt::BufferAddress; } } @@ -1358,12 +1491,14 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let encoder = self.state.render.as_ref().unwrap(); for _ in 0..draw_count { - encoder.draw_mesh_threadgroups_with_indirect_buffer( - &buffer.raw, - offset, - self.state.stage_infos.ts.raw_wg_size, - self.state.stage_infos.ms.raw_wg_size, - ); + unsafe { + encoder.draw_mesh_threadgroups_with_indirect_buffer_indirect_buffer_offset_threads_per_object_threadgroup_threads_per_mesh_threadgroup( + &buffer.raw, + offset as usize, + self.state.stage_infos.ts.raw_wg_size, + self.state.stage_infos.ms.raw_wg_size, + ) + }; offset += size_of::() as wgt::BufferAddress; } } @@ -1411,58 +1546,65 @@ impl crate::CommandEncoder for super::CommandEncoder { let raw = self.raw_cmd_buf.as_ref().unwrap(); - objc::rc::autoreleasepool(|| { + autoreleasepool(|_| { // TimeStamp Queries and ComputePassDescriptor were both introduced in Metal 2.3 (macOS 11, iOS 14) // and we currently only need ComputePassDescriptor for timestamp queries let encoder = if self.shared.private_caps.timestamp_query_support.is_empty() { - raw.new_compute_command_encoder() + raw.compute_command_encoder().unwrap() } else { - let descriptor = metal::ComputePassDescriptor::new(); + let descriptor = MTLComputePassDescriptor::new(); let mut sba_index = 0; let mut next_sba_descriptor = || { - let sba_descriptor = descriptor - .sample_buffer_attachments() - .object_at(sba_index) - .unwrap(); + let sba_descriptor = unsafe { + descriptor + .sample_buffer_attachments() + .object_at_indexed_subscript(sba_index) + }; sba_index += 1; sba_descriptor }; for (set, index) in self.state.pending_timer_queries.drain(..) { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer(set.counter_sample_buffer.as_ref().unwrap()); - sba_descriptor.set_start_of_encoder_sample_index(index as _); - sba_descriptor.set_end_of_encoder_sample_index(metal::COUNTER_DONT_SAMPLE); + sba_descriptor + .set_sample_buffer(Some(set.counter_sample_buffer.as_ref().unwrap())); + unsafe { sba_descriptor.set_start_of_encoder_sample_index(index as _) }; + unsafe { sba_descriptor.set_end_of_encoder_sample_index(MTLCounterDontSample) }; } if let Some(timestamp_writes) = desc.timestamp_writes.as_ref() { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer( + sba_descriptor.set_sample_buffer(Some( timestamp_writes .query_set .counter_sample_buffer .as_ref() .unwrap(), - ); - - sba_descriptor.set_start_of_encoder_sample_index( - timestamp_writes - .beginning_of_pass_write_index - .map_or(metal::COUNTER_DONT_SAMPLE, |i| i as _), - ); - sba_descriptor.set_end_of_encoder_sample_index( - timestamp_writes - .end_of_pass_write_index - .map_or(metal::COUNTER_DONT_SAMPLE, |i| i as _), - ); + )); + + unsafe { + sba_descriptor.set_start_of_encoder_sample_index( + timestamp_writes + .beginning_of_pass_write_index + .map_or(MTLCounterDontSample, |i| i as _), + ) + }; + unsafe { + sba_descriptor.set_end_of_encoder_sample_index( + timestamp_writes + .end_of_pass_write_index + .map_or(MTLCounterDontSample, |i| i as _), + ) + }; } - raw.compute_command_encoder_with_descriptor(descriptor) + raw.compute_command_encoder_with_descriptor(&descriptor) + .unwrap() }; if let Some(label) = desc.label { - encoder.set_label(label); + encoder.set_label(Some(&NSString::from_str(label))); } self.state.compute = Some(encoder.to_owned()); @@ -1484,11 +1626,13 @@ impl crate::CommandEncoder for super::CommandEncoder { .state .make_sizes_buffer_update(naga::ShaderStage::Compute, &mut self.temp.binding_sizes) { - encoder.set_bytes( - index as _, - (sizes.len() * WORD_SIZE) as u64, - sizes.as_ptr().cast(), - ); + unsafe { + encoder.set_bytes_length_at_index( + NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), + sizes.len() * WORD_SIZE, + index as _, + ) + }; } // update the threadgroup memory sizes @@ -1508,7 +1652,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let size: u32 = current_size.next_multiple_of(16); *current_size = size; if size != prev_size { - encoder.set_threadgroup_memory_length(i as _, size as _); + unsafe { encoder.set_threadgroup_memory_length_at_index(size as _, i) }; } } } @@ -1517,21 +1661,26 @@ impl crate::CommandEncoder for super::CommandEncoder { if count[0] > 0 && count[1] > 0 && count[2] > 0 { let encoder = self.state.compute.as_ref().unwrap(); let raw_count = MTLSize { - width: count[0] as u64, - height: count[1] as u64, - depth: count[2] as u64, + width: count[0] as usize, + height: count[1] as usize, + depth: count[2] as usize, }; - encoder.dispatch_thread_groups(raw_count, self.state.stage_infos.cs.raw_wg_size); + encoder.dispatch_threadgroups_threads_per_threadgroup( + raw_count, + self.state.stage_infos.cs.raw_wg_size, + ); } } unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) { let encoder = self.state.compute.as_ref().unwrap(); - encoder.dispatch_thread_groups_indirect( - &buffer.raw, - offset, - self.state.stage_infos.cs.raw_wg_size, - ); + unsafe { + encoder.dispatch_threadgroups_with_indirect_buffer_indirect_buffer_offset_threads_per_threadgroup( + &buffer.raw, + offset as usize, + self.state.stage_infos.cs.raw_wg_size, + ) + }; } unsafe fn build_acceleration_structures<'a, T>( @@ -1577,7 +1726,7 @@ impl Drop for super::CommandEncoder { // appears to be a requirement for all MTLCommandEncoder objects. Failing to call // endEncoding causes a crash with the message 'Command encoder released without // endEncoding'. To prevent this, we explicitiy call discard_encoding, which - // calls end_encoding on any still-held metal::CommandEncoders. + // calls end_encoding on any still-held MTLCommandEncoders. unsafe { self.discard_encoding(); } diff --git a/wgpu-hal/src/metal/conv.rs b/wgpu-hal/src/metal/conv.rs index 260b6c15a32..265bbd04d22 100644 --- a/wgpu-hal/src/metal/conv.rs +++ b/wgpu-hal/src/metal/conv.rs @@ -1,9 +1,10 @@ -use metal::{ +use objc2_foundation::NSRange; +use objc2_metal::{ MTLBlendFactor, MTLBlendOperation, MTLBlitOption, MTLClearColor, MTLColorWriteMask, MTLCompareFunction, MTLCullMode, MTLOrigin, MTLPrimitiveTopologyClass, MTLPrimitiveType, MTLRenderStages, MTLResourceUsage, MTLSamplerAddressMode, MTLSamplerBorderColor, MTLSamplerMinMagFilter, MTLSize, MTLStencilOperation, MTLStoreAction, MTLTextureType, - MTLTextureUsage, MTLVertexFormat, MTLVertexStepFunction, MTLWinding, NSRange, + MTLTextureUsage, MTLVertexFormat, MTLVertexStepFunction, MTLWinding, }; pub fn map_texture_usage(format: wgt::TextureFormat, usage: wgt::TextureUses) -> MTLTextureUsage { @@ -44,12 +45,12 @@ pub fn map_texture_view_dimension(dim: wgt::TextureViewDimension) -> MTLTextureT use wgt::TextureViewDimension as Tvd; use MTLTextureType as MTL; match dim { - Tvd::D1 => MTL::D1, - Tvd::D2 => MTL::D2, - Tvd::D2Array => MTL::D2Array, - Tvd::D3 => MTL::D3, - Tvd::Cube => MTL::Cube, - Tvd::CubeArray => MTL::CubeArray, + Tvd::D1 => MTL::Type1D, + Tvd::D2 => MTL::Type2D, + Tvd::D2Array => MTL::Type2DArray, + Tvd::D3 => MTL::Type3D, + Tvd::Cube => MTL::TypeCube, + Tvd::CubeArray => MTL::TypeCubeArray, } } @@ -274,24 +275,24 @@ pub fn map_cull_mode(face: Option) -> MTLCullMode { pub fn map_range(range: &crate::MemoryRange) -> NSRange { NSRange { - location: range.start, - length: range.end - range.start, + location: range.start as usize, + length: (range.end - range.start) as usize, } } pub fn map_copy_extent(extent: &crate::CopyExtent) -> MTLSize { MTLSize { - width: extent.width as u64, - height: extent.height as u64, - depth: extent.depth as u64, + width: extent.width as usize, + height: extent.height as usize, + depth: extent.depth as usize, } } pub fn map_origin(origin: &wgt::Origin3d) -> MTLOrigin { MTLOrigin { - x: origin.x as u64, - y: origin.y as u64, - z: origin.z as u64, + x: origin.x as usize, + y: origin.y as usize, + z: origin.z as usize, } } @@ -341,6 +342,7 @@ pub fn map_render_stages(stage: wgt::ShaderStages) -> MTLRenderStages { pub fn map_resource_usage(ty: &wgt::BindingType) -> MTLResourceUsage { match ty { + #[allow(deprecated)] wgt::BindingType::Texture { .. } => MTLResourceUsage::Sample, wgt::BindingType::StorageTexture { access, .. } => match access { wgt::StorageTextureAccess::WriteOnly => MTLResourceUsage::Write, diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index eed71226ae8..5b058f1f1ed 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -2,23 +2,33 @@ use alloc::{borrow::ToOwned as _, sync::Arc, vec::Vec}; use core::{ptr::NonNull, sync::atomic}; use std::{thread, time}; -use super::{conv, PassthroughShader}; -use crate::auxil::map_naga_stage; -use crate::metal::ShaderModuleSource; -use crate::TlasInstance; - -use metal::{ - foreign_types::ForeignType, MTLCommandBufferStatus, MTLDepthClipMode, MTLLanguageVersion, - MTLMutability, MTLPixelFormat, MTLPrimitiveTopologyClass, MTLResourceID, MTLResourceOptions, - MTLSamplerAddressMode, MTLSamplerMipFilter, MTLSize, MTLStorageMode, MTLTextureType, - MTLTriangleFillMode, MTLVertexStepFunction, NSRange, +use objc2::{ + msg_send, + rc::{autoreleasepool, Retained}, + runtime::ProtocolObject, }; +use objc2_foundation::{ns_string, NSError, NSRange, NSString, NSUInteger}; +use objc2_metal::{ + MTLBuffer, MTLCaptureManager, MTLCaptureScope, MTLCommandBuffer, MTLCommandBufferStatus, + MTLCompileOptions, MTLComputePipelineDescriptor, MTLComputePipelineState, + MTLCounterSampleBufferDescriptor, MTLCounterSet, MTLDepthClipMode, MTLDepthStencilDescriptor, + MTLDevice, MTLFunction, MTLLanguageVersion, MTLLibrary, MTLMeshRenderPipelineDescriptor, + MTLMutability, MTLPipelineBufferDescriptorArray, MTLPixelFormat, MTLPrimitiveTopologyClass, + MTLRenderPipelineColorAttachmentDescriptorArray, MTLRenderPipelineDescriptor, MTLResource, + MTLResourceID, MTLResourceOptions, MTLSamplerAddressMode, MTLSamplerDescriptor, + MTLSamplerMipFilter, MTLSamplerState, MTLSize, MTLStencilDescriptor, MTLStorageMode, + MTLTexture, MTLTextureDescriptor, MTLTextureType, MTLTriangleFillMode, MTLVertexDescriptor, + MTLVertexStepFunction, +}; + +use super::{conv, PassthroughShader, ShaderModuleSource}; +use crate::{auxil::map_naga_stage, TlasInstance}; type DeviceResult = Result; struct CompiledShader { - library: metal::Library, - function: metal::Function, + library: Retained>, + function: Retained>, wg_size: MTLSize, wg_memory_sizes: Vec, @@ -39,8 +49,8 @@ fn create_stencil_desc( face: &wgt::StencilFaceState, read_mask: u32, write_mask: u32, -) -> metal::StencilDescriptor { - let desc = metal::StencilDescriptor::new(); +) -> Retained { + let desc = MTLStencilDescriptor::new(); desc.set_stencil_compare_function(conv::map_compare_function(face.compare)); desc.set_read_mask(read_mask); desc.set_write_mask(write_mask); @@ -50,8 +60,10 @@ fn create_stencil_desc( desc } -fn create_depth_stencil_desc(state: &wgt::DepthStencilState) -> metal::DepthStencilDescriptor { - let desc = metal::DepthStencilDescriptor::new(); +fn create_depth_stencil_desc( + state: &wgt::DepthStencilState, +) -> Retained { + let desc = MTLDepthStencilDescriptor::new(); desc.set_depth_compare_function(conv::map_compare_function(state.depth_compare)); desc.set_depth_write_enabled(state.depth_write_enabled); let s = &state.stencil; @@ -149,16 +161,19 @@ impl super::Device { let options = naga::back::msl::Options { lang_version: match self.shared.private_caps.msl_version { - MTLLanguageVersion::V1_0 => (1, 0), - MTLLanguageVersion::V1_1 => (1, 1), - MTLLanguageVersion::V1_2 => (1, 2), - MTLLanguageVersion::V2_0 => (2, 0), - MTLLanguageVersion::V2_1 => (2, 1), - MTLLanguageVersion::V2_2 => (2, 2), - MTLLanguageVersion::V2_3 => (2, 3), - MTLLanguageVersion::V2_4 => (2, 4), - MTLLanguageVersion::V3_0 => (3, 0), - MTLLanguageVersion::V3_1 => (3, 1), + #[allow(deprecated)] + MTLLanguageVersion::Version1_0 => (1, 0), + MTLLanguageVersion::Version1_1 => (1, 1), + MTLLanguageVersion::Version1_2 => (1, 2), + MTLLanguageVersion::Version2_0 => (2, 0), + MTLLanguageVersion::Version2_1 => (2, 1), + MTLLanguageVersion::Version2_2 => (2, 2), + MTLLanguageVersion::Version2_3 => (2, 3), + MTLLanguageVersion::Version2_4 => (2, 4), + MTLLanguageVersion::Version3_0 => (3, 0), + MTLLanguageVersion::Version3_1 => (3, 1), + // Newer version, fall back to 3.1 + _ => (3, 1), }, inline_samplers: Default::default(), spirv_cross_compatibility: false, @@ -203,7 +218,7 @@ impl super::Device { &source ); - let options = metal::CompileOptions::new(); + let options = MTLCompileOptions::new(); options.set_language_version(self.shared.private_caps.msl_version); if self.shared.private_caps.supports_preserve_invariance { @@ -213,7 +228,10 @@ impl super::Device { let library = self .shared .device - .new_library_with_source(source.as_ref(), &options) + .new_library_with_source_options_error( + &NSString::from_str(&source), + Some(&options), + ) .map_err(|err| { log::debug!("Naga generated shader:\n{source}"); crate::PipelineError::Linkage(stage_bit, format!("Metal: {err}")) @@ -236,9 +254,9 @@ impl super::Device { }; let function = library - .get_function(translated_ep_name, None) - .map_err(|e| { - log::error!("get_function: {e:?}"); + .new_function_with_name(&NSString::from_str(translated_ep_name)) + .ok_or_else(|| { + log::error!("Function '{translated_ep_name}' does not exist"); crate::PipelineError::EntryPoint(naga_stage) })?; @@ -304,9 +322,9 @@ impl super::Device { library: shader.library.clone(), function: shader.function.clone(), wg_size: MTLSize { - width: shader.num_workgroups.0 as u64, - height: shader.num_workgroups.1 as u64, - depth: shader.num_workgroups.2 as u64, + width: shader.num_workgroups.0 as usize, + height: shader.num_workgroups.1 as usize, + depth: shader.num_workgroups.2 as usize, }, wg_memory_sizes: vec![], sized_bindings: vec![], @@ -316,21 +334,19 @@ impl super::Device { } fn set_buffers_mutability( - buffers: &metal::PipelineBufferDescriptorArrayRef, + buffers: &MTLPipelineBufferDescriptorArray, mut immutable_mask: usize, ) { while immutable_mask != 0 { let slot = immutable_mask.trailing_zeros(); immutable_mask ^= 1 << slot; - buffers - .object_at(slot as u64) - .unwrap() + unsafe { buffers.object_at_indexed_subscript(slot as usize) } .set_mutability(MTLMutability::Immutable); } } pub unsafe fn texture_from_raw( - raw: metal::Texture, + raw: Retained>, format: wgt::TextureFormat, raw_type: MTLTextureType, array_layers: u32, @@ -347,7 +363,10 @@ impl super::Device { } } - pub unsafe fn device_from_raw(raw: metal::Device, features: wgt::Features) -> super::Device { + pub unsafe fn device_from_raw( + raw: Retained>, + features: wgt::Features, + ) -> super::Device { super::Device { shared: Arc::new(super::AdapterShared::new(raw)), features, @@ -355,11 +374,14 @@ impl super::Device { } } - pub unsafe fn buffer_from_raw(raw: metal::Buffer, size: wgt::BufferAddress) -> super::Buffer { + pub unsafe fn buffer_from_raw( + raw: Retained>, + size: wgt::BufferAddress, + ) -> super::Buffer { super::Buffer { raw, size } } - pub fn raw_device(&self) -> &metal::Device { + pub fn raw_device(&self) -> &Retained> { &self.shared.device } } @@ -382,10 +404,14 @@ impl crate::Device for super::Device { //TODO: HazardTrackingModeUntracked - objc::rc::autoreleasepool(|| { - let raw = self.shared.device.new_buffer(desc.size, options); + autoreleasepool(|_| { + let raw = self + .shared + .device + .new_buffer_with_length_options(desc.size as usize, options) + .unwrap(); if let Some(label) = desc.label { - raw.set_label(label); + raw.set_label(Some(&NSString::from_str(label))); } self.counters.buffers.add(1); Ok(super::Buffer { @@ -408,9 +434,8 @@ impl crate::Device for super::Device { range: crate::MemoryRange, ) -> DeviceResult { let ptr = buffer.raw.contents().cast::(); - assert!(!ptr.is_null()); Ok(crate::BufferMapping { - ptr: NonNull::new(unsafe { ptr.offset(range.start as isize) }).unwrap(), + ptr: NonNull::new(unsafe { ptr.as_ptr().offset(range.start as isize) }).unwrap(), is_coherent: true, }) } @@ -423,29 +448,29 @@ impl crate::Device for super::Device { &self, desc: &crate::TextureDescriptor, ) -> DeviceResult { - use metal::foreign_types::ForeignType as _; - let mtl_format = self.shared.private_caps.map_format(desc.format); - objc::rc::autoreleasepool(|| { - let descriptor = metal::TextureDescriptor::new(); + autoreleasepool(|_| { + let descriptor = MTLTextureDescriptor::new(); let mtl_type = match desc.dimension { - wgt::TextureDimension::D1 => MTLTextureType::D1, + wgt::TextureDimension::D1 => MTLTextureType::Type1D, wgt::TextureDimension::D2 => { if desc.sample_count > 1 { - descriptor.set_sample_count(desc.sample_count as u64); - MTLTextureType::D2Multisample + unsafe { descriptor.set_sample_count(desc.sample_count as usize) }; + MTLTextureType::Type2DMultisample } else if desc.size.depth_or_array_layers > 1 { - descriptor.set_array_length(desc.size.depth_or_array_layers as u64); - MTLTextureType::D2Array + unsafe { + descriptor.set_array_length(desc.size.depth_or_array_layers as usize) + }; + MTLTextureType::Type2DArray } else { - MTLTextureType::D2 + MTLTextureType::Type2D } } wgt::TextureDimension::D3 => { - descriptor.set_depth(desc.size.depth_or_array_layers as u64); - MTLTextureType::D3 + unsafe { descriptor.set_depth(desc.size.depth_or_array_layers as usize) }; + MTLTextureType::Type3D } }; @@ -458,19 +483,20 @@ impl crate::Device for super::Device { }; descriptor.set_texture_type(mtl_type); - descriptor.set_width(desc.size.width as u64); - descriptor.set_height(desc.size.height as u64); - descriptor.set_mipmap_level_count(desc.mip_level_count as u64); + unsafe { descriptor.set_width(desc.size.width as usize) }; + unsafe { descriptor.set_height(desc.size.height as usize) }; + unsafe { descriptor.set_mipmap_level_count(desc.mip_level_count as usize) }; descriptor.set_pixel_format(mtl_format); descriptor.set_usage(conv::map_texture_usage(desc.format, desc.usage)); descriptor.set_storage_mode(mtl_storage_mode); - let raw = self.shared.device.new_texture(&descriptor); - if raw.as_ptr().is_null() { - return Err(crate::DeviceError::OutOfMemory); - } + let raw = self + .shared + .device + .new_texture_with_descriptor(&descriptor) + .ok_or(crate::DeviceError::OutOfMemory)?; if let Some(label) = desc.label { - raw.set_label(label); + raw.set_label(Some(&NSString::from_str(label))); } self.counters.textures.add(1); @@ -499,7 +525,7 @@ impl crate::Device for super::Device { texture: &super::Texture, desc: &crate::TextureViewDescriptor, ) -> DeviceResult { - let raw_type = if texture.raw_type == MTLTextureType::D2Multisample { + let raw_type = if texture.raw_type == MTLTextureType::Type2DMultisample { texture.raw_type } else { conv::map_texture_view_dimension(desc.dimension) @@ -532,21 +558,28 @@ impl crate::Device for super::Device { .array_layer_count .unwrap_or(texture.array_layers - desc.range.base_array_layer); - objc::rc::autoreleasepool(|| { - let raw = texture.raw.new_texture_view_from_slice( - raw_format, - raw_type, - NSRange { - location: desc.range.base_mip_level as _, - length: mip_level_count as _, - }, - NSRange { - location: desc.range.base_array_layer as _, - length: array_layer_count as _, - }, - ); + autoreleasepool(|_| { + let level_range = NSRange { + location: desc.range.base_mip_level as _, + length: mip_level_count as _, + }; + let slice_range = NSRange { + location: desc.range.base_array_layer as _, + length: array_layer_count as _, + }; + let raw = unsafe { + texture + .raw + .new_texture_view_with_pixel_format_texture_type_levels_slices( + raw_format, + raw_type, + level_range, + slice_range, + ) + .unwrap() + }; if let Some(label) = desc.label { - raw.set_label(label); + raw.set_label(Some(&NSString::from_str(label))); } raw }) @@ -565,8 +598,8 @@ impl crate::Device for super::Device { &self, desc: &crate::SamplerDescriptor, ) -> DeviceResult { - objc::rc::autoreleasepool(|| { - let descriptor = metal::SamplerDescriptor::new(); + autoreleasepool(|_| { + let descriptor = MTLSamplerDescriptor::new(); descriptor.set_min_filter(conv::map_filter_mode(desc.min_filter)); descriptor.set_mag_filter(conv::map_filter_mode(desc.mag_filter)); @@ -579,9 +612,9 @@ impl crate::Device for super::Device { }); let [s, t, r] = desc.address_modes; - descriptor.set_address_mode_s(conv::map_address_mode(s)); - descriptor.set_address_mode_t(conv::map_address_mode(t)); - descriptor.set_address_mode_r(conv::map_address_mode(r)); + descriptor.set_s_address_mode(conv::map_address_mode(s)); + descriptor.set_t_address_mode(conv::map_address_mode(t)); + descriptor.set_r_address_mode(conv::map_address_mode(r)); // Anisotropy is always supported on mac up to 16x descriptor.set_max_anisotropy(desc.anisotropy_clamp as _); @@ -596,15 +629,15 @@ impl crate::Device for super::Device { if let Some(border_color) = desc.border_color { if let wgt::SamplerBorderColor::Zero = border_color { if s == wgt::AddressMode::ClampToBorder { - descriptor.set_address_mode_s(MTLSamplerAddressMode::ClampToZero); + descriptor.set_s_address_mode(MTLSamplerAddressMode::ClampToZero); } if t == wgt::AddressMode::ClampToBorder { - descriptor.set_address_mode_t(MTLSamplerAddressMode::ClampToZero); + descriptor.set_t_address_mode(MTLSamplerAddressMode::ClampToZero); } if r == wgt::AddressMode::ClampToBorder { - descriptor.set_address_mode_r(MTLSamplerAddressMode::ClampToZero); + descriptor.set_r_address_mode(MTLSamplerAddressMode::ClampToZero); } } else { descriptor.set_border_color(conv::map_border_color(border_color)); @@ -612,12 +645,16 @@ impl crate::Device for super::Device { } if let Some(label) = desc.label { - descriptor.set_label(label); + descriptor.set_label(Some(&NSString::from_str(label))); } if self.features.contains(wgt::Features::TEXTURE_BINDING_ARRAY) { descriptor.set_support_argument_buffers(true); } - let raw = self.shared.device.new_sampler(&descriptor); + let raw = self + .shared + .device + .new_sampler_state_with_descriptor(&descriptor) + .unwrap(); self.counters.samplers.add(1); @@ -845,7 +882,7 @@ impl crate::Device for super::Device { super::AccelerationStructure, >, ) -> DeviceResult { - objc::rc::autoreleasepool(|| { + autoreleasepool(|_| { let mut bg = super::BindGroup::default(); for (&stage, counter) in super::NAGA_STAGES.iter().zip(bg.counters.iter_mut()) { let stage_bit = map_naga_stage(stage); @@ -872,15 +909,19 @@ impl crate::Device for super::Device { let uses = conv::map_resource_usage(&layout.ty); // Create argument buffer for this array - let buffer = self.shared.device.new_buffer( - 8 * count as u64, - MTLResourceOptions::HazardTrackingModeUntracked - | MTLResourceOptions::StorageModeShared, - ); + let buffer = self + .shared + .device + .new_buffer_with_length_options( + 8 * count as usize, + MTLResourceOptions::HazardTrackingModeUntracked + | MTLResourceOptions::StorageModeShared, + ) + .unwrap(); let contents: &mut [MTLResourceID] = unsafe { core::slice::from_raw_parts_mut( - buffer.contents().cast(), + buffer.contents().cast().as_ptr(), count as usize, ) }; @@ -922,7 +963,7 @@ impl crate::Device for super::Device { } bg.buffers.push(super::BufferResource { - ptr: unsafe { NonNull::new_unchecked(buffer.as_ptr()) }, + ptr: NonNull::from(&*buffer), offset: 0, dynamic_index: None, binding_size: None, @@ -1053,17 +1094,22 @@ impl crate::Device for super::Device { entry_point, num_workgroups, } => { - let options = metal::CompileOptions::new(); + let options = MTLCompileOptions::new(); // Obtain the device from shared let device = &self.shared.device; let library = device - .new_library_with_source(source, &options) + .new_library_with_source_options_error( + &NSString::from_str(source), + Some(&options), + ) .map_err(|e| crate::ShaderError::Compilation(format!("MSL: {e:?}")))?; - let function = library.get_function(&entry_point, None).map_err(|_| { - crate::ShaderError::Compilation(format!( - "Entry point '{entry_point}' not found" - )) - })?; + let function = library + .new_function_with_name(&NSString::from_str(&entry_point)) + .ok_or_else(|| { + crate::ShaderError::Compilation(format!( + "Entry point '{entry_point}' not found" + )) + })?; Ok(super::ShaderModule { source: ShaderModuleSource::Passthrough(PassthroughShader { @@ -1094,10 +1140,10 @@ impl crate::Device for super::Device { super::PipelineCache, >, ) -> Result { - objc::rc::autoreleasepool(|| { + autoreleasepool(|_| { enum MetalGenericRenderPipelineDescriptor { - Standard(metal::RenderPipelineDescriptor), - Mesh(metal::MeshRenderPipelineDescriptor), + Standard(Retained), + Mesh(Retained), } macro_rules! descriptor_fn { ($descriptor:ident . $method:ident $( ( $($args:expr),* ) )? ) => { @@ -1108,10 +1154,13 @@ impl crate::Device for super::Device { }; } impl MetalGenericRenderPipelineDescriptor { - fn set_fragment_function(&self, function: Option<&metal::FunctionRef>) { - descriptor_fn!(self.set_fragment_function(function)); + unsafe fn set_fragment_function( + &self, + function: Option<&ProtocolObject>, + ) { + unsafe { descriptor_fn!(self.set_fragment_function(function)) }; } - fn fragment_buffers(&self) -> Option<&metal::PipelineBufferDescriptorArrayRef> { + fn fragment_buffers(&self) -> Retained { descriptor_fn!(self.fragment_buffers()) } fn set_depth_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { @@ -1119,7 +1168,7 @@ impl crate::Device for super::Device { } fn color_attachments( &self, - ) -> &metal::RenderPipelineColorAttachmentDescriptorArrayRef { + ) -> Retained { descriptor_fn!(self.color_attachments()) } fn set_stencil_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { @@ -1128,11 +1177,11 @@ impl crate::Device for super::Device { fn set_alpha_to_coverage_enabled(&self, enabled: bool) { descriptor_fn!(self.set_alpha_to_coverage_enabled(enabled)); } - fn set_label(&self, label: &str) { + fn set_label(&self, label: Option<&NSString>) { descriptor_fn!(self.set_label(label)); } - fn set_max_vertex_amplification_count(&self, count: metal::NSUInteger) { - descriptor_fn!(self.set_max_vertex_amplification_count(count)) + unsafe fn set_max_vertex_amplification_count(&self, count: NSUInteger) { + unsafe { descriptor_fn!(self.set_max_vertex_amplification_count(count)) } } } @@ -1151,7 +1200,7 @@ impl crate::Device for super::Device { } => { // Vertex pipeline specific setup - let descriptor = metal::RenderPipelineDescriptor::new(); + let descriptor = MTLRenderPipelineDescriptor::new(); ts_info = None; ms_info = None; @@ -1208,7 +1257,7 @@ impl crate::Device for super::Device { descriptor.set_vertex_function(Some(&vs.function)); if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - descriptor.vertex_buffers().unwrap(), + &descriptor.vertex_buffers(), vs.immutable_buffer_mask, ); } @@ -1219,7 +1268,11 @@ impl crate::Device for super::Device { sized_bindings: vs.sized_bindings, vertex_buffer_mappings, library: Some(vs.library), - raw_wg_size: Default::default(), + raw_wg_size: MTLSize { + width: 0, + height: 0, + depth: 0, + }, work_group_memory_sizes: vec![], }); } @@ -1241,12 +1294,15 @@ impl crate::Device for super::Device { // Set the pipeline vertex buffer info if !vertex_buffers.is_empty() { - let vertex_descriptor = metal::VertexDescriptor::new(); + let vertex_descriptor = MTLVertexDescriptor::new(); for (i, vb) in vertex_buffers.iter().enumerate() { let buffer_index = - self.shared.private_caps.max_vertex_buffers as u64 - 1 - i as u64; - let buffer_desc = - vertex_descriptor.layouts().object_at(buffer_index).unwrap(); + self.shared.private_caps.max_vertex_buffers as usize - 1 - i; + let buffer_desc = unsafe { + vertex_descriptor + .layouts() + .object_at_indexed_subscript(buffer_index) + }; // Metal expects the stride to be the actual size of the attributes. // The semantics of array_stride == 0 can be achieved by setting @@ -1258,25 +1314,28 @@ impl crate::Device for super::Device { .map(|attribute| attribute.offset + attribute.format.size()) .max() .unwrap_or(0); - buffer_desc.set_stride(wgt::math::align_to(stride, 4)); + unsafe { + buffer_desc.set_stride(wgt::math::align_to(stride as _, 4)) + }; buffer_desc.set_step_function(MTLVertexStepFunction::Constant); - buffer_desc.set_step_rate(0); + unsafe { buffer_desc.set_step_rate(0) }; } else { - buffer_desc.set_stride(vb.array_stride); + unsafe { buffer_desc.set_stride(vb.array_stride as _) }; buffer_desc.set_step_function(conv::map_step_mode(vb.step_mode)); } for at in vb.attributes { - let attribute_desc = vertex_descriptor - .attributes() - .object_at(at.shader_location as u64) - .unwrap(); + let attribute_desc = unsafe { + vertex_descriptor + .attributes() + .object_at_indexed_subscript(at.shader_location as _) + }; attribute_desc.set_format(conv::map_vertex_format(at.format)); - attribute_desc.set_buffer_index(buffer_index); - attribute_desc.set_offset(at.offset); + unsafe { attribute_desc.set_buffer_index(buffer_index) }; + unsafe { attribute_desc.set_offset(at.offset as _) }; } } - descriptor.set_vertex_descriptor(Some(vertex_descriptor)); + descriptor.set_vertex_descriptor(Some(&vertex_descriptor)); } MetalGenericRenderPipelineDescriptor::Standard(descriptor) @@ -1288,7 +1347,7 @@ impl crate::Device for super::Device { // Mesh pipeline specific setup vs_info = None; - let descriptor = metal::MeshRenderPipelineDescriptor::new(); + let descriptor = MTLMeshRenderPipelineDescriptor::new(); // Setup task stage if let Some(ref task_stage) = task_stage { @@ -1299,10 +1358,10 @@ impl crate::Device for super::Device { primitive_class, naga::ShaderStage::Task, )?; - descriptor.set_object_function(Some(&ts.function)); + unsafe { descriptor.set_object_function(Some(&ts.function)) }; if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - descriptor.mesh_buffers().unwrap(), + &descriptor.mesh_buffers(), ts.immutable_buffer_mask, ); } @@ -1328,10 +1387,10 @@ impl crate::Device for super::Device { primitive_class, naga::ShaderStage::Mesh, )?; - descriptor.set_mesh_function(Some(&ms.function)); + unsafe { descriptor.set_mesh_function(Some(&ms.function)) }; if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - descriptor.mesh_buffers().unwrap(), + &descriptor.mesh_buffers(), ms.immutable_buffer_mask, ); } @@ -1370,10 +1429,10 @@ impl crate::Device for super::Device { naga::ShaderStage::Fragment, )?; - descriptor.set_fragment_function(Some(&fs.function)); + unsafe { descriptor.set_fragment_function(Some(&fs.function)) }; if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - descriptor.fragment_buffers().unwrap(), + &descriptor.fragment_buffers(), fs.immutable_buffer_mask, ); } @@ -1384,7 +1443,11 @@ impl crate::Device for super::Device { sized_bindings: fs.sized_bindings, vertex_buffer_mappings: vec![], library: Some(fs.library), - raw_wg_size: Default::default(), + raw_wg_size: MTLSize { + width: 0, + height: 0, + depth: 0, + }, work_group_memory_sizes: vec![], }) } @@ -1400,7 +1463,11 @@ impl crate::Device for super::Device { // Setup pipeline color attachments for (i, ct) in desc.color_targets.iter().enumerate() { - let at_descriptor = descriptor.color_attachments().object_at(i as u64).unwrap(); + let at_descriptor = unsafe { + descriptor + .color_attachments() + .object_at_indexed_subscript(i) + }; let ct = if let Some(color_target) = ct.as_ref() { color_target } else { @@ -1440,7 +1507,7 @@ impl crate::Device for super::Device { } let ds_descriptor = create_depth_stencil_desc(ds); - let raw = self.shared.device.new_depth_stencil_state(&ds_descriptor); + let raw = self.shared.device.new_depth_stencil_state_with_descriptor(&ds_descriptor).unwrap(); Some((raw, ds.bias)) } None => None, @@ -1451,10 +1518,11 @@ impl crate::Device for super::Device { //TODO: handle sample mask match descriptor { MetalGenericRenderPipelineDescriptor::Standard(ref inner) => { - inner.set_sample_count(desc.multisample.count as u64); + #[allow(deprecated)] + inner.set_sample_count(desc.multisample.count as _); } MetalGenericRenderPipelineDescriptor::Mesh(ref inner) => { - inner.set_raster_sample_count(desc.multisample.count as u64); + unsafe { inner.set_raster_sample_count(desc.multisample.count as _) }; } } descriptor @@ -1464,19 +1532,27 @@ impl crate::Device for super::Device { // Set debug label if let Some(name) = desc.label { - descriptor.set_label(name); + descriptor.set_label(Some(&NSString::from_str(name))); } if let Some(mv) = desc.multiview_mask { - descriptor.set_max_vertex_amplification_count(mv.get().count_ones() as u64); + unsafe { + descriptor.set_max_vertex_amplification_count(mv.get().count_ones() as usize) + }; } // Create the pipeline from descriptor let raw = match descriptor { - MetalGenericRenderPipelineDescriptor::Standard(d) => { - self.shared.device.new_render_pipeline_state(&d) - } + MetalGenericRenderPipelineDescriptor::Standard(d) => self + .shared + .device + .new_render_pipeline_state_with_descriptor_error(&d), MetalGenericRenderPipelineDescriptor::Mesh(d) => { - self.shared.device.new_mesh_render_pipeline_state(&d) + // TODO: `newRenderPipelineStateWithMeshDescriptor:error:` is not exposed on + // `MTLDevice`, is this always correct? + let device = &self.shared.device; + unsafe { + msg_send![device, newRenderPipelineStateWithMeshDescriptor: &*d, error: _] + } } } .map_err(|e| { @@ -1524,19 +1600,19 @@ impl crate::Device for super::Device { super::PipelineCache, >, ) -> Result { - objc::rc::autoreleasepool(|| { - let descriptor = metal::ComputePipelineDescriptor::new(); + autoreleasepool(|_| { + let descriptor = MTLComputePipelineDescriptor::new(); let module = desc.stage.module; let cs = if let ShaderModuleSource::Passthrough(desc) = &module.source { CompiledShader { library: desc.library.clone(), function: desc.function.clone(), - wg_size: MTLSize::new( - desc.num_workgroups.0 as u64, - desc.num_workgroups.1 as u64, - desc.num_workgroups.2 as u64, - ), + wg_size: MTLSize { + width: desc.num_workgroups.0 as usize, + height: desc.num_workgroups.1 as usize, + depth: desc.num_workgroups.2 as usize, + }, wg_memory_sizes: vec![], sized_bindings: vec![], immutable_buffer_mask: 0, @@ -1554,10 +1630,7 @@ impl crate::Device for super::Device { descriptor.set_compute_function(Some(&cs.function)); if self.shared.private_caps.supports_mutability { - Self::set_buffers_mutability( - descriptor.buffers().unwrap(), - cs.immutable_buffer_mask, - ); + Self::set_buffers_mutability(&descriptor.buffers(), cs.immutable_buffer_mask); } let cs_info = super::PipelineStageInfo { @@ -1571,14 +1644,18 @@ impl crate::Device for super::Device { }; if let Some(name) = desc.label { - descriptor.set_label(name); + descriptor.set_label(Some(&NSString::from_str(name))); } - let raw = self - .shared - .device - .new_compute_pipeline_state(&descriptor) - .map_err(|e| { + // TODO: `newComputePipelineStateWithDescriptor:error:` is not exposed on + // `MTLDevice`, is this always correct? + let device = &self.shared.device; + let raw = unsafe { + msg_send![device, newComputePipelineStateWithDescriptor: &*descriptor, error: _] + }; + + let raw: Retained> = + raw.map_err(|e: Retained| { crate::PipelineError::Linkage( wgt::ShaderStages::COMPUTE, format!("new_compute_pipeline_state: {e:?}"), @@ -1607,15 +1684,19 @@ impl crate::Device for super::Device { &self, desc: &wgt::QuerySetDescriptor, ) -> DeviceResult { - objc::rc::autoreleasepool(|| { + autoreleasepool(|_| { match desc.ty { wgt::QueryType::Occlusion => { let size = desc.count as u64 * crate::QUERY_SIZE; let options = MTLResourceOptions::empty(); //TODO: HazardTrackingModeUntracked - let raw_buffer = self.shared.device.new_buffer(size, options); + let raw_buffer = self + .shared + .device + .new_buffer_with_length_options(size as usize, options) + .unwrap(); if let Some(label) = desc.label { - raw_buffer.set_label(label); + raw_buffer.set_label(Some(&NSString::from_str(label))); } Ok(super::QuerySet { raw_buffer, @@ -1626,28 +1707,32 @@ impl crate::Device for super::Device { wgt::QueryType::Timestamp => { let size = desc.count as u64 * crate::QUERY_SIZE; let device = &self.shared.device; - let destination_buffer = device.new_buffer(size, MTLResourceOptions::empty()); + let destination_buffer = device + .new_buffer_with_length_options(size as usize, MTLResourceOptions::empty()) + .unwrap(); - let csb_desc = metal::CounterSampleBufferDescriptor::new(); + let csb_desc = MTLCounterSampleBufferDescriptor::new(); csb_desc.set_storage_mode(MTLStorageMode::Shared); - csb_desc.set_sample_count(desc.count as _); + unsafe { csb_desc.set_sample_count(desc.count as _) }; if let Some(label) = desc.label { - csb_desc.set_label(label); + csb_desc.set_label(&NSString::from_str(label)); } - let counter_sets = device.counter_sets(); - let timestamp_counter = - match counter_sets.iter().find(|cs| cs.name() == "timestamp") { - Some(counter) => counter, - None => { - log::error!("Failed to obtain timestamp counter set."); - return Err(crate::DeviceError::Unexpected); - } - }; - csb_desc.set_counter_set(timestamp_counter); + let counter_sets = device.counter_sets().unwrap(); + let timestamp_counter = match counter_sets + .iter() + .find(|cs| &*cs.name() == ns_string!("timestamp")) + { + Some(counter) => counter, + None => { + log::error!("Failed to obtain timestamp counter set."); + return Err(crate::DeviceError::Unexpected); + } + }; + csb_desc.set_counter_set(Some(×tamp_counter)); let counter_sample_buffer = - match device.new_counter_sample_buffer_with_descriptor(&csb_desc) { + match device.new_counter_sample_buffer_with_descriptor_error(&csb_desc) { Ok(buffer) => buffer, Err(err) => { log::error!("Failed to create counter sample buffer: {err:?}"); @@ -1677,7 +1762,7 @@ impl crate::Device for super::Device { unsafe fn create_fence(&self) -> DeviceResult { self.counters.fences.add(1); let shared_event = if self.shared.private_caps.supports_shared_event { - Some(self.shared.device.new_shared_event()) + Some(self.shared.device.new_shared_event().unwrap()) } else { None }; @@ -1742,16 +1827,17 @@ impl crate::Device for super::Device { return false; } let device = &self.shared.device; - let shared_capture_manager = metal::CaptureManager::shared(); + let shared_capture_manager = unsafe { MTLCaptureManager::shared_capture_manager() }; let default_capture_scope = shared_capture_manager.new_capture_scope_with_device(device); - shared_capture_manager.set_default_capture_scope(&default_capture_scope); + shared_capture_manager.set_default_capture_scope(Some(&default_capture_scope)); + #[allow(deprecated)] shared_capture_manager.start_capture_with_scope(&default_capture_scope); default_capture_scope.begin_scope(); true } unsafe fn stop_graphics_debugger_capture(&self) { - let shared_capture_manager = metal::CaptureManager::shared(); + let shared_capture_manager = unsafe { MTLCaptureManager::shared_capture_manager() }; if let Some(default_capture_scope) = shared_capture_manager.default_capture_scope() { default_capture_scope.end_scope(); } diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 9a05fa64548..a0d423769c6 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -25,20 +25,32 @@ mod device; mod surface; mod time; -use alloc::{borrow::ToOwned as _, string::String, sync::Arc, vec::Vec}; +use alloc::{ + string::{String, ToString as _}, + sync::Arc, + vec::Vec, +}; use core::{fmt, iter, ops, ptr::NonNull, sync::atomic}; use arrayvec::ArrayVec; use bitflags::bitflags; use hashbrown::HashMap; -use metal::{ - foreign_types::{ForeignType as _, ForeignTypeRef as _}, - MTLArgumentBuffersTier, MTLBuffer, MTLCommandBufferStatus, MTLCullMode, MTLDepthClipMode, - MTLIndexType, MTLLanguageVersion, MTLPrimitiveType, MTLReadWriteTextureTier, MTLRenderStages, - MTLResource, MTLResourceUsage, MTLSamplerState, MTLSize, MTLTexture, MTLTextureType, - MTLTriangleFillMode, MTLWinding, -}; use naga::FastHashMap; +use objc2::{ + rc::{autoreleasepool, Retained}, + runtime::ProtocolObject, +}; +use objc2_foundation::ns_string; +use objc2_metal::{ + MTLArgumentBuffersTier, MTLBlitCommandEncoder, MTLBuffer, MTLCommandBuffer, + MTLCommandBufferStatus, MTLCommandQueue, MTLComputeCommandEncoder, MTLComputePipelineState, + MTLCounterSampleBuffer, MTLCullMode, MTLDepthClipMode, MTLDepthStencilState, MTLDevice, + MTLDrawable, MTLFunction, MTLIndexType, MTLLanguageVersion, MTLLibrary, MTLPrimitiveType, + MTLReadWriteTextureTier, MTLRenderCommandEncoder, MTLRenderPipelineState, MTLRenderStages, + MTLResource, MTLResourceUsage, MTLSamplerState, MTLSharedEvent, MTLSize, MTLTexture, + MTLTextureType, MTLTriangleFillMode, MTLWinding, +}; +use objc2_quartz_core::CAMetalLayer; use parking_lot::{Mutex, RwLock}; #[derive(Clone, Debug)] @@ -105,7 +117,7 @@ crate::impl_dyn_resource!( pub struct Instance {} impl Instance { - pub fn create_surface_from_layer(&self, layer: &metal::MetalLayerRef) -> Surface { + pub fn create_surface_from_layer(&self, layer: &CAMetalLayer) -> Surface { Surface::from_layer(layer) } } @@ -140,8 +152,10 @@ impl crate::Instance for Instance { }; // SAFETY: The layer is an initialized instance of `CAMetalLayer`, and - // we transfer the retain count to `MetalLayer` using `into_raw`. - let layer = unsafe { metal::MetalLayer::from_ptr(layer.into_raw().cast().as_ptr()) }; + // we transfer the retain count to `Retained` using `into_raw`. + let layer = unsafe { + Retained::from_raw(layer.into_raw().cast::().as_ptr()).unwrap() + }; Ok(Surface::new(layer)) } @@ -150,11 +164,11 @@ impl crate::Instance for Instance { &self, _surface_hint: Option<&Surface>, ) -> Vec> { - let devices = metal::Device::all(); + let devices = objc2_metal::MTLCopyAllDevices(); let mut adapters: Vec> = devices .into_iter() .map(|dev| { - let name = dev.name().into(); + let name = dev.name().to_string(); let shared = AdapterShared::new(dev); crate::ExposedAdapter { info: wgt::AdapterInfo { @@ -353,7 +367,7 @@ impl Default for Settings { } struct AdapterShared { - device: metal::Device, + device: Retained>, disabilities: PrivateDisabilities, private_caps: PrivateCapabilities, settings: Settings, @@ -364,7 +378,7 @@ unsafe impl Send for AdapterShared {} unsafe impl Sync for AdapterShared {} impl AdapterShared { - fn new(device: metal::Device) -> Self { + fn new(device: Retained>) -> Self { let private_caps = PrivateCapabilities::new(&device); log::debug!("{private_caps:#?}"); @@ -383,7 +397,7 @@ pub struct Adapter { } pub struct Queue { - raw: Arc>, + raw: Arc>>>, timestamp_period: f32, } @@ -391,14 +405,17 @@ unsafe impl Send for Queue {} unsafe impl Sync for Queue {} impl Queue { - pub unsafe fn queue_from_raw(raw: metal::CommandQueue, timestamp_period: f32) -> Self { + pub unsafe fn queue_from_raw( + raw: Retained>, + timestamp_period: f32, + ) -> Self { Self { raw: Arc::new(Mutex::new(raw)), timestamp_period, } } - pub fn as_raw(&self) -> &Arc> { + pub fn as_raw(&self) -> &Arc>>> { &self.raw } } @@ -410,7 +427,7 @@ pub struct Device { } pub struct Surface { - render_layer: Mutex, + render_layer: Mutex>, swapchain_format: RwLock>, extent: RwLock, } @@ -421,9 +438,9 @@ unsafe impl Sync for Surface {} #[derive(Debug)] pub struct SurfaceTexture { texture: Texture, - drawable: metal::MetalDrawable, // Useful for UI-intensive applications that are sensitive to // window resizing. + drawable: Retained>, present_with_transaction: bool, } @@ -453,33 +470,30 @@ impl crate::Queue for Queue { _surface_textures: &[&SurfaceTexture], (signal_fence, signal_value): (&mut Fence, crate::FenceValue), ) -> Result<(), crate::DeviceError> { - objc::rc::autoreleasepool(|| { + autoreleasepool(|_| { let extra_command_buffer = { let completed_value = Arc::clone(&signal_fence.completed_value); - let block = block::ConcreteBlock::new(move |_cmd_buf| { + let block = block2::RcBlock::new(move |_cmd_buf| { completed_value.store(signal_value, atomic::Ordering::Release); - }) - .copy(); + }); let raw = match command_buffers.last() { - Some(&cmd_buf) => cmd_buf.raw.to_owned(), + Some(&cmd_buf) => cmd_buf.raw.clone(), None => { let queue = self.raw.lock(); - queue - .new_command_buffer_with_unretained_references() - .to_owned() + queue.command_buffer_with_unretained_references().unwrap() } }; - raw.set_label("(wgpu internal) Signal"); - raw.add_completed_handler(&block); + raw.set_label(Some(ns_string!("(wgpu internal) Signal"))); + unsafe { raw.add_completed_handler(block2::RcBlock::as_ptr(&block)) }; signal_fence.maintain(); signal_fence .pending_command_buffers - .push((signal_value, raw.to_owned())); + .push((signal_value, raw.clone())); - if let Some(shared_event) = signal_fence.shared_event.as_ref() { - raw.encode_signal_event(shared_event, signal_value); + if let Some(shared_event) = &signal_fence.shared_event { + raw.encode_signal_event_value(shared_event.as_ref(), signal_value); } // only return an extra one if it's extra match command_buffers.last() { @@ -504,9 +518,9 @@ impl crate::Queue for Queue { texture: SurfaceTexture, ) -> Result<(), crate::SurfaceError> { let queue = &self.raw.lock(); - objc::rc::autoreleasepool(|| { - let command_buffer = queue.new_command_buffer(); - command_buffer.set_label("(wgpu internal) Present"); + autoreleasepool(|_| { + let command_buffer = queue.command_buffer().unwrap(); + command_buffer.set_label(Some(ns_string!("(wgpu internal) Present"))); // https://developer.apple.com/documentation/quartzcore/cametallayer/1478157-presentswithtransaction?language=objc if !texture.present_with_transaction { @@ -530,7 +544,7 @@ impl crate::Queue for Queue { #[derive(Debug)] pub struct Buffer { - raw: metal::Buffer, + raw: Retained>, size: wgt::BufferAddress, } @@ -540,8 +554,8 @@ unsafe impl Sync for Buffer {} impl crate::DynBuffer for Buffer {} impl Buffer { - fn as_raw(&self) -> BufferPtr { - unsafe { NonNull::new_unchecked(self.raw.as_ptr()) } + fn as_raw(&self) -> NonNull> { + unsafe { NonNull::new_unchecked(Retained::as_ptr(&self.raw) as *mut _) } } } @@ -556,7 +570,7 @@ impl crate::BufferBinding<'_, Buffer> { #[derive(Debug)] pub struct Texture { - raw: metal::Texture, + raw: Retained>, format: wgt::TextureFormat, raw_type: MTLTextureType, array_layers: u32, @@ -565,10 +579,7 @@ pub struct Texture { } impl Texture { - /// # Safety - /// - /// - The texture handle must not be manually destroyed - pub unsafe fn raw_handle(&self) -> &metal::Texture { + pub fn raw_handle(&self) -> &ProtocolObject { &self.raw } } @@ -580,7 +591,7 @@ unsafe impl Sync for Texture {} #[derive(Debug)] pub struct TextureView { - raw: metal::Texture, + raw: Retained>, aspects: crate::FormatAspects, } @@ -590,14 +601,14 @@ unsafe impl Send for TextureView {} unsafe impl Sync for TextureView {} impl TextureView { - fn as_raw(&self) -> TexturePtr { - unsafe { NonNull::new_unchecked(self.raw.as_ptr()) } + fn as_raw(&self) -> NonNull> { + unsafe { NonNull::new_unchecked(Retained::as_ptr(&self.raw) as *mut _) } } } #[derive(Debug)] pub struct Sampler { - raw: metal::SamplerState, + raw: Retained>, } impl crate::DynSampler for Sampler {} @@ -606,8 +617,8 @@ unsafe impl Send for Sampler {} unsafe impl Sync for Sampler {} impl Sampler { - fn as_raw(&self) -> SamplerPtr { - unsafe { NonNull::new_unchecked(self.raw.as_ptr()) } + fn as_raw(&self) -> NonNull> { + unsafe { NonNull::new_unchecked(Retained::as_ptr(&self.raw) as *mut _) } } } @@ -716,68 +727,9 @@ pub struct PipelineLayout { impl crate::DynPipelineLayout for PipelineLayout {} -trait AsNative { - type Native; - fn from(native: &Self::Native) -> Self; - fn as_native(&self) -> &Self::Native; -} - -type ResourcePtr = NonNull; -type BufferPtr = NonNull; -type TexturePtr = NonNull; -type SamplerPtr = NonNull; - -impl AsNative for ResourcePtr { - type Native = metal::ResourceRef; - #[inline] - fn from(native: &Self::Native) -> Self { - unsafe { NonNull::new_unchecked(native.as_ptr()) } - } - #[inline] - fn as_native(&self) -> &Self::Native { - unsafe { Self::Native::from_ptr(self.as_ptr()) } - } -} - -impl AsNative for BufferPtr { - type Native = metal::BufferRef; - #[inline] - fn from(native: &Self::Native) -> Self { - unsafe { NonNull::new_unchecked(native.as_ptr()) } - } - #[inline] - fn as_native(&self) -> &Self::Native { - unsafe { Self::Native::from_ptr(self.as_ptr()) } - } -} - -impl AsNative for TexturePtr { - type Native = metal::TextureRef; - #[inline] - fn from(native: &Self::Native) -> Self { - unsafe { NonNull::new_unchecked(native.as_ptr()) } - } - #[inline] - fn as_native(&self) -> &Self::Native { - unsafe { Self::Native::from_ptr(self.as_ptr()) } - } -} - -impl AsNative for SamplerPtr { - type Native = metal::SamplerStateRef; - #[inline] - fn from(native: &Self::Native) -> Self { - unsafe { NonNull::new_unchecked(native.as_ptr()) } - } - #[inline] - fn as_native(&self) -> &Self::Native { - unsafe { Self::Native::from_ptr(self.as_ptr()) } - } -} - #[derive(Debug)] struct BufferResource { - ptr: BufferPtr, + ptr: NonNull>, offset: wgt::BufferAddress, dynamic_index: Option, @@ -815,11 +767,11 @@ impl Default for UseResourceInfo { pub struct BindGroup { counters: MultiStageResourceCounters, buffers: Vec, - samplers: Vec, - textures: Vec, + samplers: Vec>>, + textures: Vec>>, - argument_buffers: Vec, - resources_to_use: HashMap, + argument_buffers: Vec>>, + resources_to_use: HashMap>, UseResourceInfo>, } impl crate::DynBindGroup for BindGroup {} @@ -835,12 +787,15 @@ pub enum ShaderModuleSource { #[derive(Debug)] pub struct PassthroughShader { - pub library: metal::Library, - pub function: metal::Function, + pub library: Retained>, + pub function: Retained>, pub entry_point: String, pub num_workgroups: (u32, u32, u32), } +unsafe impl Send for PassthroughShader {} +unsafe impl Sync for PassthroughShader {} + #[derive(Debug)] pub struct ShaderModule { source: ShaderModuleSource, @@ -849,10 +804,10 @@ pub struct ShaderModule { impl crate::DynShaderModule for ShaderModule {} -#[derive(Debug, Default)] +#[derive(Debug)] struct PipelineStageInfo { #[allow(dead_code)] - library: Option, + library: Option>>, immediates: Option, /// The buffer argument table index at which we pass runtime-sized arrays' buffer sizes. @@ -875,6 +830,26 @@ struct PipelineStageInfo { work_group_memory_sizes: Vec, } +// TODO(madsmtm): Derive this when a release with +// https://github.com/madsmtm/objc2/issues/804 is available (likely 0.4). +impl Default for PipelineStageInfo { + fn default() -> Self { + Self { + library: Default::default(), + immediates: Default::default(), + sizes_slot: Default::default(), + sized_bindings: Default::default(), + vertex_buffer_mappings: Default::default(), + raw_wg_size: MTLSize { + width: 0, + height: 0, + depth: 0, + }, + work_group_memory_sizes: Default::default(), + } + } +} + impl PipelineStageInfo { fn clear(&mut self) { self.immediates = None; @@ -883,7 +858,11 @@ impl PipelineStageInfo { self.vertex_buffer_mappings.clear(); self.library = None; self.work_group_memory_sizes.clear(); - self.raw_wg_size = Default::default(); + self.raw_wg_size = MTLSize { + width: 0, + height: 0, + depth: 0, + }; } fn assign_from(&mut self, other: &Self) { @@ -904,7 +883,7 @@ impl PipelineStageInfo { #[derive(Debug)] pub struct RenderPipeline { - raw: metal::RenderPipelineState, + raw: Retained>, vs_info: Option, fs_info: Option, ts_info: Option, @@ -914,7 +893,10 @@ pub struct RenderPipeline { raw_front_winding: MTLWinding, raw_cull_mode: MTLCullMode, raw_depth_clip_mode: Option, - depth_stencil: Option<(metal::DepthStencilState, wgt::DepthBiasState)>, + depth_stencil: Option<( + Retained>, + wgt::DepthBiasState, + )>, } unsafe impl Send for RenderPipeline {} @@ -924,7 +906,7 @@ impl crate::DynRenderPipeline for RenderPipeline {} #[derive(Debug)] pub struct ComputePipeline { - raw: metal::ComputePipelineState, + raw: Retained>, cs_info: PipelineStageInfo, } @@ -935,9 +917,9 @@ impl crate::DynComputePipeline for ComputePipeline {} #[derive(Debug, Clone)] pub struct QuerySet { - raw_buffer: metal::Buffer, + raw_buffer: Retained>, //Metal has a custom buffer for counters. - counter_sample_buffer: Option, + counter_sample_buffer: Option>>, ty: wgt::QueryType, } @@ -950,8 +932,11 @@ unsafe impl Sync for QuerySet {} pub struct Fence { completed_value: Arc, /// The pending fence values have to be ascending. - pending_command_buffers: Vec<(crate::FenceValue, metal::CommandBuffer)>, - shared_event: Option, + pending_command_buffers: Vec<( + crate::FenceValue, + Retained>, + )>, + shared_event: Option>>, } impl crate::DynFence for Fence {} @@ -976,13 +961,13 @@ impl Fence { .retain(|&(value, _)| value > latest); } - pub fn raw_shared_event(&self) -> Option<&metal::SharedEvent> { - self.shared_event.as_ref() + pub fn raw_shared_event(&self) -> Option<&ProtocolObject> { + self.shared_event.as_deref() } } struct IndexState { - buffer_ptr: BufferPtr, + buffer_ptr: NonNull>, offset: wgt::BufferAddress, stride: wgt::BufferAddress, raw_type: MTLIndexType, @@ -994,9 +979,9 @@ struct Temp { } struct CommandState { - blit: Option, - render: Option, - compute: Option, + blit: Option>>, + render: Option>>, + compute: Option>>, raw_primitive_type: MTLPrimitiveType, index: Option, stage_infos: MultiStageData, @@ -1032,8 +1017,8 @@ struct CommandState { pub struct CommandEncoder { shared: Arc, - raw_queue: Arc>, - raw_cmd_buf: Option, + raw_queue: Arc>>>, + raw_cmd_buf: Option>>, state: CommandState, temp: Temp, counters: Arc, @@ -1053,7 +1038,7 @@ unsafe impl Sync for CommandEncoder {} #[derive(Debug)] pub struct CommandBuffer { - raw: metal::CommandBuffer, + raw: Retained>, } impl crate::DynCommandBuffer for CommandBuffer {} diff --git a/wgpu-hal/src/metal/surface.rs b/wgpu-hal/src/metal/surface.rs index bfdc8af24df..6d155ecab04 100644 --- a/wgpu-hal/src/metal/surface.rs +++ b/wgpu-hal/src/metal/surface.rs @@ -1,22 +1,18 @@ -#![allow(clippy::let_unit_value)] // `let () =` being used to constrain result type - use alloc::borrow::ToOwned as _; -use core_graphics_types::{ - base::CGFloat, - geometry::{CGRect, CGSize}, -}; -use metal::MTLTextureType; -use objc::{ - class, msg_send, - rc::autoreleasepool, - runtime::{BOOL, YES}, - sel, sel_impl, +use objc2::{ + rc::{autoreleasepool, Retained}, + runtime::ProtocolObject, + ClassType, Message, }; +use objc2_core_foundation::CGSize; +use objc2_foundation::NSObjectProtocol; +use objc2_metal::MTLTextureType; +use objc2_quartz_core::{CAMetalDrawable, CAMetalLayer}; use parking_lot::{Mutex, RwLock}; impl super::Surface { - pub fn new(layer: metal::MetalLayer) -> Self { + pub fn new(layer: Retained) -> Self { Self { render_layer: Mutex::new(layer), swapchain_format: RwLock::new(None), @@ -24,14 +20,12 @@ impl super::Surface { } } - pub fn from_layer(layer: &metal::MetalLayerRef) -> Self { - let class = class!(CAMetalLayer); - let proper_kind: BOOL = unsafe { msg_send![layer, isKindOfClass: class] }; - assert_eq!(proper_kind, YES); - Self::new(layer.to_owned()) + pub fn from_layer(layer: &CAMetalLayer) -> Self { + assert!(layer.isKindOfClass(CAMetalLayer::class())); + Self::new(layer.retain()) } - pub fn render_layer(&self) -> &Mutex { + pub fn render_layer(&self) -> &Mutex> { &self.render_layer } @@ -43,11 +37,10 @@ impl super::Surface { /// of sync. This is sound, as these properties are accessed atomically. /// See: pub(super) fn dimensions(&self) -> wgt::Extent3d { - let (size, scale): (CGSize, CGFloat) = unsafe { - 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: CGFloat = msg_send![render_layer, contentsScale]; + let (size, scale) = { + let render_layer = self.render_layer.lock(); + let bounds = render_layer.bounds(); + let contents_scale = render_layer.contents_scale(); (bounds.size, contents_scale) }; @@ -89,7 +82,7 @@ impl crate::Surface for super::Surface { } let device_raw = &device.shared.device; - render_layer.set_device(device_raw); + render_layer.set_device(Some(device_raw)); render_layer.set_pixel_format(caps.map_format(config.format)); render_layer.set_framebuffer_only(framebuffer_only); // opt-in to Metal EDR @@ -100,13 +93,13 @@ impl crate::Surface for super::Surface { } // this gets ignored on iOS for certain OS/device combinations (iphone5s iOS 10.3) - render_layer.set_maximum_drawable_count(config.maximum_frame_latency as u64 + 1); + render_layer.set_maximum_drawable_count(config.maximum_frame_latency as usize + 1); render_layer.set_drawable_size(drawable_size); if caps.can_set_next_drawable_timeout { - let () = msg_send![*render_layer, setAllowsNextDrawableTimeout:false]; + render_layer.set_allows_next_drawable_timeout(false); } if caps.can_set_display_sync { - let () = msg_send![*render_layer, setDisplaySyncEnabled: display_sync]; + render_layer.set_display_sync_enabled(display_sync); } Ok(()) @@ -122,7 +115,7 @@ impl crate::Surface for super::Surface { _fence: &super::Fence, ) -> Result>, crate::SurfaceError> { let render_layer = self.render_layer.lock(); - let (drawable, texture) = match autoreleasepool(|| { + let (drawable, texture) = match autoreleasepool(|_| { render_layer .next_drawable() .map(|drawable| (drawable.to_owned(), drawable.texture().to_owned())) @@ -137,7 +130,7 @@ impl crate::Surface for super::Surface { texture: super::Texture { raw: texture, format: swapchain_format, - raw_type: MTLTextureType::D2, + raw_type: MTLTextureType::Type2D, array_layers: 1, mip_levels: 1, copy_size: crate::CopyExtent { @@ -146,7 +139,7 @@ impl crate::Surface for super::Surface { depth: 1, }, }, - drawable, + drawable: ProtocolObject::from_retained(drawable), present_with_transaction: render_layer.presents_with_transaction(), }; From acda7eb3c458a721a42fe873a1b509da1f2f2373 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 25 Apr 2025 22:01:53 +0200 Subject: [PATCH 2/2] Use normal objc2 naming scheme --- Cargo.lock | 112 +++---------- Cargo.toml | 12 +- wgpu-hal/src/metal/adapter.rs | 139 ++++++++-------- wgpu-hal/src/metal/command.rs | 305 +++++++++++++++++----------------- wgpu-hal/src/metal/device.rs | 286 +++++++++++++++---------------- wgpu-hal/src/metal/mod.rs | 16 +- wgpu-hal/src/metal/surface.rs | 28 ++-- 7 files changed, 413 insertions(+), 485 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f21791b92a..69c8f3b78c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,9 +431,10 @@ dependencies = [ [[package]] name = "block2" version = "0.6.2" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3", ] [[package]] @@ -1177,16 +1178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3", ] [[package]] @@ -2684,7 +2676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ "objc-sys", - "objc2-encode 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2-encode 4.1.0", ] [[package]] @@ -2693,15 +2685,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ - "objc2-encode 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "objc2" -version = "0.6.3" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" -dependencies = [ - "objc2-encode 4.1.0 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2-encode 4.1.0", ] [[package]] @@ -2763,18 +2747,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.10.0", - "dispatch2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" -dependencies = [ - "bitflags 2.10.0", - "dispatch2 0.3.0 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "dispatch2", + "objc2 0.6.3", ] [[package]] @@ -2813,11 +2787,6 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" - [[package]] name = "objc2-foundation" version = "0.2.2" @@ -2838,17 +2807,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-core-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3", + "objc2-core-foundation", ] [[package]] @@ -2880,21 +2840,11 @@ name = "objc2-metal" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "objc2-metal" -version = "0.3.2" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" dependencies = [ "bitflags 2.10.0", "block2 0.6.2", - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] @@ -2917,22 +2867,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-core-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-metal 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.2" -source = "git+https://github.com/madsmtm/objc2?branch=metal-wgpu#363fb6f76a49db6f15c10c9f274ee7a2956483cf" -dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-core-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-metal 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", ] [[package]] @@ -3405,10 +3343,10 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" dependencies = [ - "objc2 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-core-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-foundation 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "objc2-quartz-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] @@ -4954,11 +4892,11 @@ dependencies = [ "mach-dxcompiler-rs", "naga", "ndk-sys 0.6.0+11769913", - "objc2 0.6.3 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-core-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-foundation 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-metal 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", - "objc2-quartz-core 0.3.2 (git+https://github.com/madsmtm/objc2?branch=metal-wgpu)", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", "once_cell", "ordered-float", "parking_lot", diff --git a/Cargo.toml b/Cargo.toml index 58f4eafcb34..da90a92eca4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -202,19 +202,19 @@ which = "8" xshell = "0.2.2" # Metal dependencies -block2 = { version = "0.6.2", git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } -objc2 = { version = "0.6.3", git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +block2 = "0.6.2" +objc2 = "0.6.3" objc2-core-foundation = { version = "0.3.2", default-features = false, features = [ "std", "CFCGTypes", -], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +] } objc2-foundation = { version = "0.3.2", default-features = false, features = [ "std", "NSError", "NSProcessInfo", "NSRange", "NSString", -], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +] } objc2-metal = { version = "0.3.2", default-features = false, features = [ "std", "block2", @@ -247,14 +247,14 @@ objc2-metal = { version = "0.3.2", default-features = false, features = [ "MTLTexture", "MTLTypes", "MTLVertexDescriptor", -], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +] } objc2-quartz-core = { version = "0.3.2", default-features = false, features = [ "std", "objc2-core-foundation", "CALayer", "CAMetalLayer", "objc2-metal", -], git = "https://github.com/madsmtm/objc2", branch = "metal-wgpu" } +] } raw-window-metal = "1.0" # Vulkan dependencies diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 8df3c85d903..b36169d8af9 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -51,7 +51,7 @@ impl crate::Adapter for super::Adapter { let queue = self .shared .device - .new_command_queue_with_max_command_buffer_count(MAX_COMMAND_BUFFERS) + .newCommandQueueWithMaxCommandBufferCount(MAX_COMMAND_BUFFERS) .unwrap(); // Acquiring the meaning of timestamp ticks is hard with Metal! @@ -526,7 +526,7 @@ impl super::PrivateCapabilities { features_sets .iter() .cloned() - .any(|x| raw.supports_feature_set(x)) + .any(|x| raw.supportsFeatureSet(x)) } pub fn new(device: &ProtocolObject) -> Self { @@ -534,21 +534,21 @@ impl super::PrivateCapabilities { let os_type = super::OsType::new(version, device); let family_check = version.at_least((10, 15), (13, 0), (13, 0), (1, 0), os_type); - let metal3 = family_check && device.supports_family(MTLGPUFamily::Metal3); - let metal4 = family_check && device.supports_family(MTLGPUFamily::Metal4); + let metal3 = family_check && device.supportsFamily(MTLGPUFamily::Metal3); + let metal4 = family_check && device.supportsFamily(MTLGPUFamily::Metal4); let mut sample_count_mask = crate::TextureFormatCapabilities::MULTISAMPLE_X4; // 1 and 4 samples are supported on all devices - if device.supports_texture_sample_count(2) { + if device.supportsTextureSampleCount(2) { sample_count_mask |= crate::TextureFormatCapabilities::MULTISAMPLE_X2; } - if device.supports_texture_sample_count(8) { + if device.supportsTextureSampleCount(8) { sample_count_mask |= crate::TextureFormatCapabilities::MULTISAMPLE_X8; } - if device.supports_texture_sample_count(16) { + if device.supportsTextureSampleCount(16) { sample_count_mask |= crate::TextureFormatCapabilities::MULTISAMPLE_X16; } let rw_texture_tier = if version.at_least((10, 13), (11, 0), (11, 0), (1, 0), os_type) { - device.read_write_texture_support() + device.readWriteTextureSupport() } else if version.at_least( (10, 12), OS_NOT_SUPPORT, @@ -567,18 +567,18 @@ impl super::PrivateCapabilities { let mut timestamp_query_support = TimestampQuerySupport::empty(); if version.at_least((11, 0), (14, 0), (14, 0), (1, 0), os_type) - && device.supports_counter_sampling(MTLCounterSamplingPoint::AtStageBoundary) + && device.supportsCounterSampling(MTLCounterSamplingPoint::AtStageBoundary) { // If we don't support at stage boundary, don't support anything else. timestamp_query_support.insert(TimestampQuerySupport::STAGE_BOUNDARIES); - if device.supports_counter_sampling(MTLCounterSamplingPoint::AtDrawBoundary) { + if device.supportsCounterSampling(MTLCounterSamplingPoint::AtDrawBoundary) { timestamp_query_support.insert(TimestampQuerySupport::ON_RENDER_ENCODER); } - if device.supports_counter_sampling(MTLCounterSamplingPoint::AtDispatchBoundary) { + if device.supportsCounterSampling(MTLCounterSamplingPoint::AtDispatchBoundary) { timestamp_query_support.insert(TimestampQuerySupport::ON_COMPUTE_ENCODER); } - if device.supports_counter_sampling(MTLCounterSamplingPoint::AtBlitBoundary) { + if device.supportsCounterSampling(MTLCounterSamplingPoint::AtBlitBoundary) { timestamp_query_support.insert(TimestampQuerySupport::ON_BLIT_ENCODER); } // `TimestampQuerySupport::INSIDE_WGPU_PASSES` emerges from the other flags. @@ -586,14 +586,14 @@ impl super::PrivateCapabilities { let argument_buffers = version .at_least((10, 13), (11, 0), (11, 0), (1, 0), os_type) - .then(|| device.argument_buffers_support()); + .then(|| device.argumentBuffersSupport()); let is_virtual = device.name().to_string().to_lowercase().contains("virtual"); let mesh_shaders = family_check - && (device.supports_family(MTLGPUFamily::Metal3) - || device.supports_family(MTLGPUFamily::Apple7) - || device.supports_family(MTLGPUFamily::Mac2)) + && (device.supportsFamily(MTLGPUFamily::Metal3) + || device.supportsFamily(MTLGPUFamily::Apple7) + || device.supportsFamily(MTLGPUFamily::Mac2)) // Mesh shaders don't work on virtual devices even if they should be supported. CI thing && !is_virtual; @@ -630,9 +630,9 @@ impl super::PrivateCapabilities { fragment_rw_storage: version.at_least((10, 12), (8, 0), (8, 0), (1, 0), os_type), read_write_texture_tier: rw_texture_tier, msaa_desktop: os_type == super::OsType::Macos, - msaa_apple3: (family_check && device.supports_family(MTLGPUFamily::Apple3)) - || device.supports_feature_set(MTLFeatureSet::iOS_GPUFamily3_v4), - msaa_apple7: family_check && device.supports_family(MTLGPUFamily::Apple7), + msaa_apple3: (family_check && device.supportsFamily(MTLGPUFamily::Apple3)) + || device.supportsFeatureSet(MTLFeatureSet::iOS_GPUFamily3_v4), + msaa_apple7: family_check && device.supportsFamily(MTLGPUFamily::Apple7), resource_heaps: Self::supports_any(device, RESOURCE_HEAP_SUPPORT), argument_buffers, mutable_comparison_samplers: Self::supports_any( @@ -646,17 +646,17 @@ impl super::PrivateCapabilities { BASE_VERTEX_FIRST_INSTANCE_SUPPORT, ), dual_source_blending: Self::supports_any(device, DUAL_SOURCE_BLEND_SUPPORT), - low_power: os_type != super::OsType::Macos || device.is_low_power(), - headless: os_type == super::OsType::Macos && device.is_headless(), + low_power: os_type != super::OsType::Macos || device.isLowPower(), + headless: os_type == super::OsType::Macos && device.isHeadless(), layered_rendering: Self::supports_any(device, LAYERED_RENDERING_SUPPORT), function_specialization: Self::supports_any(device, FUNCTION_SPECIALIZATION_SUPPORT), depth_clip_mode: Self::supports_any(device, DEPTH_CLIP_MODE), texture_cube_array: Self::supports_any(device, TEXTURE_CUBE_ARRAY_SUPPORT), supports_float_filtering: os_type == super::OsType::Macos || (version.at_least((11, 0), (14, 0), (16, 0), (1, 0), os_type) - && device.supports32_bit_float_filtering()), + && device.supports32BitFloatFiltering()), format_depth24_stencil8: os_type == super::OsType::Macos - && device.is_depth24_stencil8_pixel_format_supported(), + && device.isDepth24Stencil8PixelFormatSupported(), format_depth32_stencil8_filter: os_type == super::OsType::Macos, format_depth32_stencil8_none: os_type != super::OsType::Macos, format_min_srgb_channels: if os_type == super::OsType::Macos { @@ -668,14 +668,14 @@ impl super::PrivateCapabilities { format_bc: os_type == super::OsType::Macos, format_eac_etc: os_type != super::OsType::Macos // M1 in macOS supports EAC/ETC2 - || (family_check && device.supports_family(MTLGPUFamily::Apple7)), + || (family_check && device.supportsFamily(MTLGPUFamily::Apple7)), // A8(Apple2) and later always support ASTC pixel formats - format_astc: (family_check && device.supports_family(MTLGPUFamily::Apple2)) + format_astc: (family_check && device.supportsFamily(MTLGPUFamily::Apple2)) || Self::supports_any(device, ASTC_PIXEL_FORMAT_FEATURES), // A13(Apple6) M1(Apple7) and later always support HDR ASTC pixel formats - format_astc_hdr: family_check && device.supports_family(MTLGPUFamily::Apple6), + format_astc_hdr: family_check && device.supportsFamily(MTLGPUFamily::Apple6), // Apple3 and later supports compressed volume texture formats including ASTC Sliced 3D - format_astc_3d: family_check && device.supports_family(MTLGPUFamily::Apple3), + format_astc_3d: family_check && device.supportsFamily(MTLGPUFamily::Apple3), format_any8_unorm_srgb_all: Self::supports_any(device, ANY8_UNORM_SRGB_ALL), format_any8_unorm_srgb_no_write: !Self::supports_any(device, ANY8_UNORM_SRGB_ALL) && os_type != super::OsType::Macos, @@ -722,8 +722,8 @@ impl super::PrivateCapabilities { // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=12 format_depth16unorm_filter: family_check && (metal3 - || device.supports_family(MTLGPUFamily::Apple3) - || device.supports_family(MTLGPUFamily::Mac2)), + || device.supportsFamily(MTLGPUFamily::Apple3) + || device.supportsFamily(MTLGPUFamily::Mac2)), format_depth32float_filter: os_type == super::OsType::Macos, format_depth32float_none: os_type != super::OsType::Macos, format_bgr10a2_all: Self::supports_any(device, BGR10A2_ALL), @@ -731,10 +731,10 @@ impl super::PrivateCapabilities { max_buffers_per_stage: 31, max_vertex_buffers: 31.min(crate::MAX_VERTEX_BUFFERS as u32), // duplicative of `apply_hal_limits` max_textures_per_stage: if os_type == super::OsType::Macos - || (family_check && device.supports_family(MTLGPUFamily::Apple6)) + || (family_check && device.supportsFamily(MTLGPUFamily::Apple6)) { 128 - } else if family_check && device.supports_family(MTLGPUFamily::Apple4) { + } else if family_check && device.supportsFamily(MTLGPUFamily::Apple4) { 96 } else { 31 @@ -742,22 +742,22 @@ impl super::PrivateCapabilities { max_samplers_per_stage: 16, max_binding_array_elements: if argument_buffers == Some(MTLArgumentBuffersTier::Tier2) { 1_000_000 - } else if family_check && device.supports_family(MTLGPUFamily::Apple4) { + } else if family_check && device.supportsFamily(MTLGPUFamily::Apple4) { 96 } else { 31 }, // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=7 max_sampler_binding_array_elements: if family_check - && device.supports_family(MTLGPUFamily::Apple9) + && device.supportsFamily(MTLGPUFamily::Apple9) { 500_000 } else if family_check - && (device.supports_family(MTLGPUFamily::Apple7) - || device.supports_family(MTLGPUFamily::Mac2)) + && (device.supportsFamily(MTLGPUFamily::Apple7) + || device.supportsFamily(MTLGPUFamily::Mac2)) { 1024 - } else if family_check && device.supports_family(MTLGPUFamily::Apple6) { + } else if family_check && device.supportsFamily(MTLGPUFamily::Apple6) { 128 } else { 16 @@ -768,7 +768,7 @@ impl super::PrivateCapabilities { 64 }, max_buffer_size: if version.at_least((10, 14), (12, 0), (12, 0), (1, 0), os_type) { - device.max_buffer_length() as u64 + device.maxBufferLength() as u64 } else if os_type == super::OsType::Macos { 1 << 30 // 1GB on macOS 10.11 and up } else { @@ -789,7 +789,7 @@ impl super::PrivateCapabilities { max_texture_3d_size: 2048, max_texture_layers: 2048, max_fragment_input_components: if os_type == super::OsType::Macos - || device.supports_feature_set(MTLFeatureSet::iOS_GPUFamily4_v1) + || device.supportsFeatureSet(MTLFeatureSet::iOS_GPUFamily4_v1) { 124 } else { @@ -811,16 +811,15 @@ impl super::PrivateCapabilities { }, // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=7 max_color_attachment_bytes_per_sample: if family_check - && device.supports_family(MTLGPUFamily::Apple7) + && device.supportsFamily(MTLGPUFamily::Apple7) { 128 - } else if family_check && device.supports_family(MTLGPUFamily::Apple4) { + } else if family_check && device.supportsFamily(MTLGPUFamily::Apple4) { 64 } else { 32 }, - max_varying_components: if device - .supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v1) + max_varying_components: if device.supportsFeatureSet(MTLFeatureSet::macOS_GPUFamily1_v1) { 124 } else { @@ -866,8 +865,8 @@ impl super::PrivateCapabilities { // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=4 supports_binary_archives: family_check && (metal3 - || device.supports_family(MTLGPUFamily::Apple3) - || device.supports_family(MTLGPUFamily::Mac2)), + || device.supportsFamily(MTLGPUFamily::Apple3) + || device.supportsFamily(MTLGPUFamily::Mac2)), // https://developer.apple.com/documentation/metal/mtlcapturemanager supports_capture_manager: version.at_least((10, 13), (11, 0), (11, 0), (1, 0), os_type), // https://developer.apple.com/documentation/quartzcore/cametallayer/maximumdrawablecount @@ -907,13 +906,13 @@ impl super::PrivateCapabilities { // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=3 supports_arrays_of_textures_write: family_check && (metal3 - || device.supports_family(MTLGPUFamily::Apple6) - || device.supports_family(MTLGPUFamily::Mac2)), + || device.supportsFamily(MTLGPUFamily::Apple6) + || device.supportsFamily(MTLGPUFamily::Mac2)), // https://developer.apple.com/documentation/metal/mtlpipelinebufferdescriptor/mutability supports_mutability: version.at_least((10, 13), (11, 0), (11, 0), (1, 0), os_type), // Depth clipping is supported on all macOS GPU families and iOS family 4 and later supports_depth_clip_control: os_type == super::OsType::Macos - || device.supports_feature_set(MTLFeatureSet::iOS_GPUFamily4_v1), + || device.supportsFeatureSet(MTLFeatureSet::iOS_GPUFamily4_v1), // https://developer.apple.com/documentation/metal/mtlcompileoptions/preserveinvariance supports_preserve_invariance: version.at_least( (11, 0), @@ -925,11 +924,11 @@ impl super::PrivateCapabilities { // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=4 supports_shader_primitive_index: family_check && (metal3 - || device.supports_family(MTLGPUFamily::Apple7) - || device.supports_family(MTLGPUFamily::Mac2)), + || device.supportsFamily(MTLGPUFamily::Apple7) + || device.supportsFamily(MTLGPUFamily::Mac2)), // https://developer.apple.com/documentation/metal/mtldevice/hasunifiedmemory has_unified_memory: if version.at_least((10, 15), (13, 0), (13, 0), (1, 0), os_type) { - Some(device.has_unified_memory()) + Some(device.hasUnifiedMemory()) } else { None }, @@ -937,39 +936,39 @@ impl super::PrivateCapabilities { // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=4 supports_simd_scoped_operations: family_check && (metal3 - || device.supports_family(MTLGPUFamily::Mac2) - || device.supports_family(MTLGPUFamily::Apple7)), + || device.supportsFamily(MTLGPUFamily::Mac2) + || device.supportsFamily(MTLGPUFamily::Apple7)), // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=4 - int64: family_check && (metal3 || device.supports_family(MTLGPUFamily::Apple3)), + int64: family_check && (metal3 || device.supportsFamily(MTLGPUFamily::Apple3)), // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=4 // There is also a footnote that says // "Some GPU devices in the Apple8 family support 64-bit atomic minimum and maximum..." int64_atomics_min_max: family_check - && (device.supports_family(MTLGPUFamily::Apple9) - || (device.supports_family(MTLGPUFamily::Apple8) - && device.supports_family(MTLGPUFamily::Mac2))), - int64_atomics: family_check && device.supports_family(MTLGPUFamily::Apple9), + && (device.supportsFamily(MTLGPUFamily::Apple9) + || (device.supportsFamily(MTLGPUFamily::Apple8) + && device.supportsFamily(MTLGPUFamily::Mac2))), + int64_atomics: family_check && device.supportsFamily(MTLGPUFamily::Apple9), // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=4 float_atomics: family_check && (metal3 - || device.supports_family(MTLGPUFamily::Apple7) - || device.supports_family(MTLGPUFamily::Mac2)), + || device.supportsFamily(MTLGPUFamily::Apple7) + || device.supportsFamily(MTLGPUFamily::Mac2)), // https://developer.apple.com/documentation/metal/mtlsharedevent supports_shared_event: version.at_least((10, 14), (12, 0), (12, 0), (1, 0), os_type), // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=5 (footnote) // Supported on some Metal4, Apple7, Mac2, and some other platforms can be queried with device.supportsShaderBarycentricCoordinates(). shader_barycentrics: metal4 || (family_check - && (device.supports_family(MTLGPUFamily::Apple7) - || device.supports_family(MTLGPUFamily::Mac2))) + && (device.supportsFamily(MTLGPUFamily::Apple7) + || device.supportsFamily(MTLGPUFamily::Mac2))) || (version.at_least((10, 15), (14, 0), (16, 0), (1, 0), os_type) - && device.supports_shader_barycentric_coordinates()), + && device.supportsShaderBarycentricCoordinates()), // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=3 // See https://github.com/gfx-rs/wgpu/pull/8725 for more details supports_memoryless_storage: metal4 || if family_check { // Apple A7 (MTLGPUFamily::Apple1) has been tested to have support. - device.supports_family(MTLGPUFamily::Apple1) + device.supportsFamily(MTLGPUFamily::Apple1) } else { // macOS: Always rely on family check // iOS/tvOS: API added in 10.0 @@ -991,7 +990,7 @@ impl super::PrivateCapabilities { (1, 0), os_type, ) - && device.supports_vertex_amplification_count(factor * 2) + && device.supportsVertexAmplificationCount(factor * 2) { factor *= 2 } @@ -1002,8 +1001,8 @@ impl super::PrivateCapabilities { max_mesh_task_workgroup_count: if mesh_shaders { 1024 } else { 0 }, max_task_payload_size: if mesh_shaders { 16384 - 32 } else { 0 }, supports_cooperative_matrix: family_check - && (device.supports_family(MTLGPUFamily::Apple7) - || device.supports_family(MTLGPUFamily::Mac2)), + && (device.supportsFamily(MTLGPUFamily::Apple7) + || device.supportsFamily(MTLGPUFamily::Mac2)), } } @@ -1486,7 +1485,7 @@ impl super::PrivateDisabilities { let is_intel = device.name().to_string().starts_with("Intel"); Self { broken_viewport_near_depth: is_intel - && !device.supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v4), + && !device.supportsFeatureSet(MTLFeatureSet::macOS_GPUFamily1_v4), broken_layered_clear_image: is_intel, } } @@ -1498,9 +1497,9 @@ impl super::OsType { // on the Simulator, Apple only provides the Apple2 GPU capability, and the Apple2+ GPU capability covers the capabilities of Apple2. // Therefore, the following conditions can be used to determine if it is visionOS. // https://developer.apple.com/documentation/metal/developing_metal_apps_that_run_in_simulator - let os_is_vision = version.majorVersion < 8 && device.supports_family(MTLGPUFamily::Apple2); - let os_is_mac = device.supports_feature_set(MTLFeatureSet::macOS_GPUFamily1_v1); - let os_is_tvos = device.supports_feature_set(MTLFeatureSet::tvOS_GPUFamily1_v1); + let os_is_vision = version.majorVersion < 8 && device.supportsFamily(MTLGPUFamily::Apple2); + let os_is_mac = device.supportsFeatureSet(MTLFeatureSet::macOS_GPUFamily1_v1); + let os_is_tvos = device.supportsFeatureSet(MTLFeatureSet::tvOS_GPUFamily1_v1); if os_is_vision { Self::VisionOs } else if os_is_mac { diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 1318e0b54e9..b635fa1979f 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -71,11 +71,11 @@ impl Encoder<'_> { ) { unsafe { match *self { - Self::Vertex(enc) => enc.setVertexBuffer_offset_atIndex_(buffer, offset, index), - Self::Fragment(enc) => enc.setFragmentBuffer_offset_atIndex_(buffer, offset, index), - Self::Task(enc) => enc.setObjectBuffer_offset_atIndex_(buffer, offset, index), - Self::Mesh(enc) => enc.setMeshBuffer_offset_atIndex_(buffer, offset, index), - Self::Compute(enc) => enc.setBuffer_offset_atIndex_(buffer, offset, index), + Self::Vertex(enc) => enc.setVertexBuffer_offset_atIndex(buffer, offset, index), + Self::Fragment(enc) => enc.setFragmentBuffer_offset_atIndex(buffer, offset, index), + Self::Task(enc) => enc.setObjectBuffer_offset_atIndex(buffer, offset, index), + Self::Mesh(enc) => enc.setMeshBuffer_offset_atIndex(buffer, offset, index), + Self::Compute(enc) => enc.setBuffer_offset_atIndex(buffer, offset, index), } } } @@ -83,11 +83,11 @@ impl Encoder<'_> { fn set_bytes(&self, bytes: NonNull, length: NSUInteger, index: NSUInteger) { unsafe { match *self { - Self::Vertex(enc) => enc.set_vertex_bytes_length_at_index(bytes, length, index), - Self::Fragment(enc) => enc.set_fragment_bytes_length_at_index(bytes, length, index), - Self::Task(enc) => enc.set_object_bytes_length_at_index(bytes, length, index), - Self::Mesh(enc) => enc.set_mesh_bytes_length_at_index(bytes, length, index), - Self::Compute(enc) => enc.set_bytes_length_at_index(bytes, length, index), + Self::Vertex(enc) => enc.setVertexBytes_length_atIndex(bytes, length, index), + Self::Fragment(enc) => enc.setFragmentBytes_length_atIndex(bytes, length, index), + Self::Task(enc) => enc.setObjectBytes_length_atIndex(bytes, length, index), + Self::Mesh(enc) => enc.setMeshBytes_length_atIndex(bytes, length, index), + Self::Compute(enc) => enc.setBytes_length_atIndex(bytes, length, index), } } } @@ -99,11 +99,11 @@ impl Encoder<'_> { ) { unsafe { match *self { - Self::Vertex(enc) => enc.set_vertex_sampler_state_at_index(state, index), - Self::Fragment(enc) => enc.set_fragment_sampler_state_at_index(state, index), - Self::Task(enc) => enc.set_object_sampler_state_at_index(state, index), - Self::Mesh(enc) => enc.set_mesh_sampler_state_at_index(state, index), - Self::Compute(enc) => enc.set_sampler_state_at_index(state, index), + Self::Vertex(enc) => enc.setVertexSamplerState_atIndex(state, index), + Self::Fragment(enc) => enc.setFragmentSamplerState_atIndex(state, index), + Self::Task(enc) => enc.setObjectSamplerState_atIndex(state, index), + Self::Mesh(enc) => enc.setMeshSamplerState_atIndex(state, index), + Self::Compute(enc) => enc.setSamplerState_atIndex(state, index), } } } @@ -111,11 +111,11 @@ impl Encoder<'_> { fn set_texture(&self, texture: Option<&ProtocolObject>, index: NSUInteger) { unsafe { match *self { - Self::Vertex(enc) => enc.set_vertex_texture_at_index(texture, index), - Self::Fragment(enc) => enc.set_fragment_texture_at_index(texture, index), - Self::Task(enc) => enc.set_object_texture_at_index(texture, index), - Self::Mesh(enc) => enc.set_mesh_texture_at_index(texture, index), - Self::Compute(enc) => enc.set_texture_at_index(texture, index), + Self::Vertex(enc) => enc.setVertexTexture_atIndex(texture, index), + Self::Fragment(enc) => enc.setFragmentTexture_atIndex(texture, index), + Self::Task(enc) => enc.setObjectTexture_atIndex(texture, index), + Self::Mesh(enc) => enc.setMeshTexture_atIndex(texture, index), + Self::Compute(enc) => enc.setTexture_atIndex(texture, index), } } } @@ -160,23 +160,23 @@ impl super::CommandEncoder { { let sba_descriptor = unsafe { descriptor - .sample_buffer_attachments() - .object_at_indexed_subscript(i) + .sampleBufferAttachments() + .objectAtIndexedSubscript(i) }; sba_descriptor - .set_sample_buffer(Some(set.counter_sample_buffer.as_ref().unwrap())); + .setSampleBuffer(Some(set.counter_sample_buffer.as_ref().unwrap())); // Here be dragons: // As mentioned above, for some reasons using the start of the encoder won't yield any results sometimes! unsafe { - sba_descriptor.set_start_of_encoder_sample_index(MTLCounterDontSample) + sba_descriptor.setStartOfEncoderSampleIndex(MTLCounterDontSample) }; - unsafe { sba_descriptor.set_end_of_encoder_sample_index(index as _) }; + unsafe { sba_descriptor.setEndOfEncoderSampleIndex(index as _) }; last_query = Some((set, index)); } let encoder = cmd_buf - .blit_command_encoder_with_descriptor(&descriptor) + .blitCommandEncoderWithDescriptor(&descriptor) .unwrap(); // As explained above, we need to do some write: @@ -187,18 +187,18 @@ impl super::CommandEncoder { * crate::QUERY_SIZE as usize, length: 1, }; - encoder.fill_buffer_range_value( + encoder.fillBuffer_range_value( &last_query.as_ref().unwrap().0.raw_buffer, raw_range, 255, // Don't write 0, so it's easier to identify if something went wrong. ); - encoder.end_encoding(); + encoder.endEncoding(); }); } autoreleasepool(|_| { - self.state.blit = Some(cmd_buf.blit_command_encoder().unwrap()); + self.state.blit = Some(cmd_buf.blitCommandEncoder().unwrap()); }); let encoder = self.state.blit.as_ref().unwrap(); @@ -208,12 +208,12 @@ impl super::CommandEncoder { for (set, index) in self.state.pending_timer_queries.drain(..) { debug_assert!(supports_sample_counters_in_buffer); unsafe { - encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + encoder.sampleCountersInBuffer_atSampleIndex_withBarrier( set.counter_sample_buffer.as_ref().unwrap(), index as _, true, ) - } + }; } } self.state.blit.as_ref().unwrap().clone() @@ -221,7 +221,7 @@ impl super::CommandEncoder { pub(super) fn leave_blit(&mut self) { if let Some(encoder) = self.state.blit.take() { - encoder.end_encoding(); + encoder.endEncoding(); } } @@ -380,13 +380,13 @@ impl crate::CommandEncoder for super::CommandEncoder { let retain_references = self.shared.settings.retain_command_buffer_references; let raw = autoreleasepool(move |_| { let cmd_buf_ref = if retain_references { - queue.command_buffer() + queue.commandBuffer() } else { - queue.command_buffer_with_unretained_references() + queue.commandBufferWithUnretainedReferences() } .unwrap(); if let Some(label) = label { - cmd_buf_ref.set_label(Some(&NSString::from_str(label))); + cmd_buf_ref.setLabel(Some(&NSString::from_str(label))); } cmd_buf_ref.to_owned() }); @@ -401,10 +401,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // when discarding, we don't have a guarantee that // everything is in a good state, so check carefully if let Some(encoder) = self.state.render.take() { - encoder.end_encoding(); + encoder.endEncoding(); } if let Some(encoder) = self.state.compute.take() { - encoder.end_encoding(); + encoder.endEncoding(); } self.raw_cmd_buf = None; } @@ -447,7 +447,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) { let encoder = self.enter_blit(); - encoder.fill_buffer_range_value(&buffer.raw, conv::map_range(&range), 0); + encoder.fillBuffer_range_value(&buffer.raw, conv::map_range(&range), 0); } unsafe fn copy_buffer_to_buffer( @@ -461,7 +461,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.enter_blit(); for copy in regions { unsafe { - encoder.copy_from_buffer_source_offset_to_buffer_destination_offset_size( + encoder.copyFromBuffer_sourceOffset_toBuffer_destinationOffset_size( &src.raw, copy.src_offset as usize, &dst.raw, @@ -484,9 +484,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let dst_texture = if src.format != dst.format { let raw_format = self.shared.private_caps.map_format(src.format); Cow::Owned(autoreleasepool(|_| { - dst.raw - .new_texture_view_with_pixel_format(raw_format) - .unwrap() + dst.raw.newTextureViewWithPixelFormat(raw_format).unwrap() })) } else { Cow::Borrowed(&dst.raw) @@ -498,7 +496,7 @@ impl crate::CommandEncoder for super::CommandEncoder { // no clamping is done: Metal expects physical sizes here let extent = conv::map_copy_extent(©.size); unsafe { - encoder.copy_from_texture_source_slice_source_level_source_origin_source_size_to_texture_destination_slice_destination_level_destination_origin( + encoder.copyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin( &src.raw, copy.src_base.array_layer as usize, copy.src_base.mip_level as usize, @@ -541,7 +539,7 @@ impl crate::CommandEncoder for super::CommandEncoder { 0 }; unsafe { - encoder.copy_from_buffer_source_offset_source_bytes_per_row_source_bytes_per_image_source_size_to_texture_destination_slice_destination_level_destination_origin_options( + encoder.copyFromBuffer_sourceOffset_sourceBytesPerRow_sourceBytesPerImage_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin_options( &src.raw, copy.buffer_layout.offset as usize, bytes_per_row as usize, @@ -580,7 +578,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .rows_per_image .map_or(0, |v| v as u64 * bytes_per_row); unsafe { - encoder.copy_from_texture_source_slice_source_level_source_origin_source_size_to_buffer_destination_offset_destination_bytes_per_row_destination_bytes_per_image_options( + encoder.copyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toBuffer_destinationOffset_destinationBytesPerRow_destinationBytesPerImage_options( &src.raw, copy.texture_base.array_layer as usize, copy.texture_base.mip_level as usize, @@ -612,7 +610,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .render .as_ref() .unwrap() - .set_visibility_result_mode_offset( + .setVisibilityResultMode_offset( MTLVisibilityResultMode::Boolean, index as usize * crate::QUERY_SIZE as usize, ); @@ -627,7 +625,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .render .as_ref() .unwrap() - .set_visibility_result_mode_offset(MTLVisibilityResultMode::Disabled, 0); + .setVisibilityResultMode_offset(MTLVisibilityResultMode::Disabled, 0); } _ => {} } @@ -648,7 +646,7 @@ impl crate::CommandEncoder for super::CommandEncoder { self.state.blit.as_ref(), ) { unsafe { - encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + encoder.sampleCountersInBuffer_atSampleIndex_withBarrier( sample_buffer, index as _, with_barrier, @@ -659,7 +657,7 @@ impl crate::CommandEncoder for super::CommandEncoder { self.state.render.as_ref(), ) { unsafe { - encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + encoder.sampleCountersInBuffer_atSampleIndex_withBarrier( sample_buffer, index as _, with_barrier, @@ -670,7 +668,7 @@ impl crate::CommandEncoder for super::CommandEncoder { self.state.compute.as_ref(), ) { unsafe { - encoder.sample_counters_in_buffer_at_sample_index_with_barrier( + encoder.sampleCountersInBuffer_atSampleIndex_withBarrier( sample_buffer, index as _, with_barrier, @@ -695,7 +693,7 @@ impl crate::CommandEncoder for super::CommandEncoder { location: range.start as usize * crate::QUERY_SIZE as usize, length: (range.end - range.start) as usize * crate::QUERY_SIZE as usize, }; - encoder.fill_buffer_range_value(&set.raw_buffer, raw_range, 0); + encoder.fillBuffer_range_value(&set.raw_buffer, raw_range, 0); } unsafe fn copy_query_results( @@ -711,7 +709,7 @@ impl crate::CommandEncoder for super::CommandEncoder { wgt::QueryType::Occlusion => { let size = (range.end - range.start) as u64 * crate::QUERY_SIZE; unsafe { - encoder.copy_from_buffer_source_offset_to_buffer_destination_offset_size( + encoder.copyFromBuffer_sourceOffset_toBuffer_destinationOffset_size( &set.raw_buffer, range.start as usize * crate::QUERY_SIZE as usize, &buffer.raw, @@ -722,7 +720,7 @@ impl crate::CommandEncoder for super::CommandEncoder { } wgt::QueryType::Timestamp => { unsafe { - encoder.resolve_counters_in_range_destination_buffer_destination_offset( + encoder.resolveCounters_inRange_destinationBuffer_destinationOffset( set.counter_sample_buffer.as_ref().unwrap(), NSRange::new(range.start as usize, (range.end - range.start) as usize), &buffer.raw, @@ -752,25 +750,22 @@ impl crate::CommandEncoder for super::CommandEncoder { for (i, at) in desc.color_attachments.iter().enumerate() { if let Some(at) = at.as_ref() { - let at_descriptor = unsafe { - descriptor - .color_attachments() - .object_at_indexed_subscript(i) - }; - at_descriptor.set_texture(Some(&at.target.view.raw)); + let at_descriptor = + unsafe { descriptor.colorAttachments().objectAtIndexedSubscript(i) }; + at_descriptor.setTexture(Some(&at.target.view.raw)); if let Some(depth_slice) = at.depth_slice { - at_descriptor.set_depth_plane(depth_slice as usize); + at_descriptor.setDepthPlane(depth_slice as usize); } if let Some(ref resolve) = at.resolve_target { //Note: the selection of levels and slices is already handled by `TextureView` - at_descriptor.set_resolve_texture(Some(&resolve.view.raw)); + at_descriptor.setResolveTexture(Some(&resolve.view.raw)); } let load_action = if at.ops.contains(crate::AttachmentOps::LOAD) { MTLLoadAction::Load } else if at.ops.contains(crate::AttachmentOps::LOAD_DONT_CARE) { MTLLoadAction::DontCare } else if at.ops.contains(crate::AttachmentOps::LOAD_CLEAR) { - at_descriptor.set_clear_color(conv::map_clear_color(&at.clear_value)); + at_descriptor.setClearColor(conv::map_clear_color(&at.clear_value)); MTLLoadAction::Clear } else { unreachable!() @@ -779,22 +774,22 @@ impl crate::CommandEncoder for super::CommandEncoder { at.ops.contains(crate::AttachmentOps::STORE), at.resolve_target.is_some(), ); - at_descriptor.set_load_action(load_action); - at_descriptor.set_store_action(store_action); + at_descriptor.setLoadAction(load_action); + at_descriptor.setStoreAction(store_action); } } if let Some(ref at) = desc.depth_stencil_attachment { if at.target.view.aspects.contains(crate::FormatAspects::DEPTH) { - let at_descriptor = descriptor.depth_attachment(); - at_descriptor.set_texture(Some(&at.target.view.raw)); + let at_descriptor = descriptor.depthAttachment(); + at_descriptor.setTexture(Some(&at.target.view.raw)); let load_action = if at.depth_ops.contains(crate::AttachmentOps::LOAD) { MTLLoadAction::Load } else if at.depth_ops.contains(crate::AttachmentOps::LOAD_DONT_CARE) { MTLLoadAction::DontCare } else if at.depth_ops.contains(crate::AttachmentOps::LOAD_CLEAR) { - at_descriptor.set_clear_depth(at.clear_value.0 as f64); + at_descriptor.setClearDepth(at.clear_value.0 as f64); MTLLoadAction::Clear } else { unreachable!(); @@ -804,8 +799,8 @@ impl crate::CommandEncoder for super::CommandEncoder { } else { MTLStoreAction::DontCare }; - at_descriptor.set_load_action(load_action); - at_descriptor.set_store_action(store_action); + at_descriptor.setLoadAction(load_action); + at_descriptor.setStoreAction(store_action); } if at .target @@ -813,8 +808,8 @@ impl crate::CommandEncoder for super::CommandEncoder { .aspects .contains(crate::FormatAspects::STENCIL) { - let at_descriptor = descriptor.stencil_attachment(); - at_descriptor.set_texture(Some(&at.target.view.raw)); + let at_descriptor = descriptor.stencilAttachment(); + at_descriptor.setTexture(Some(&at.target.view.raw)); let load_action = if at.stencil_ops.contains(crate::AttachmentOps::LOAD) { MTLLoadAction::Load @@ -824,7 +819,7 @@ impl crate::CommandEncoder for super::CommandEncoder { { MTLLoadAction::DontCare } else if at.stencil_ops.contains(crate::AttachmentOps::LOAD_CLEAR) { - at_descriptor.set_clear_stencil(at.clear_value.1); + at_descriptor.setClearStencil(at.clear_value.1); MTLLoadAction::Clear } else { unreachable!() @@ -834,8 +829,8 @@ impl crate::CommandEncoder for super::CommandEncoder { } else { MTLStoreAction::DontCare }; - at_descriptor.set_load_action(load_action); - at_descriptor.set_store_action(store_action); + at_descriptor.setLoadAction(load_action); + at_descriptor.setStoreAction(store_action); } } @@ -843,12 +838,12 @@ impl crate::CommandEncoder for super::CommandEncoder { let mut next_sba_descriptor = || { let sba_descriptor = unsafe { descriptor - .sample_buffer_attachments() - .object_at_indexed_subscript(sba_index) + .sampleBufferAttachments() + .objectAtIndexedSubscript(sba_index) }; - unsafe { sba_descriptor.set_end_of_vertex_sample_index(MTLCounterDontSample) }; - unsafe { sba_descriptor.set_start_of_fragment_sample_index(MTLCounterDontSample) }; + unsafe { sba_descriptor.setEndOfVertexSampleIndex(MTLCounterDontSample) }; + unsafe { sba_descriptor.setStartOfFragmentSampleIndex(MTLCounterDontSample) }; sba_index += 1; sba_descriptor @@ -856,14 +851,14 @@ impl crate::CommandEncoder for super::CommandEncoder { for (set, index) in self.state.pending_timer_queries.drain(..) { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer(Some(set.counter_sample_buffer.as_ref().unwrap())); - unsafe { sba_descriptor.set_start_of_vertex_sample_index(index as _) }; - unsafe { sba_descriptor.set_end_of_fragment_sample_index(MTLCounterDontSample) }; + sba_descriptor.setSampleBuffer(Some(set.counter_sample_buffer.as_ref().unwrap())); + unsafe { sba_descriptor.setStartOfVertexSampleIndex(index as _) }; + unsafe { sba_descriptor.setEndOfFragmentSampleIndex(MTLCounterDontSample) }; } if let Some(ref timestamp_writes) = desc.timestamp_writes { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer(Some( + sba_descriptor.setSampleBuffer(Some( timestamp_writes .query_set .counter_sample_buffer @@ -872,14 +867,14 @@ impl crate::CommandEncoder for super::CommandEncoder { )); unsafe { - sba_descriptor.set_start_of_vertex_sample_index( + sba_descriptor.setStartOfVertexSampleIndex( timestamp_writes .beginning_of_pass_write_index .map_or(MTLCounterDontSample, |i| i as _), ) }; unsafe { - sba_descriptor.set_end_of_fragment_sample_index( + sba_descriptor.setEndOfFragmentSampleIndex( timestamp_writes .end_of_pass_write_index .map_or(MTLCounterDontSample, |i| i as _), @@ -888,8 +883,7 @@ impl crate::CommandEncoder for super::CommandEncoder { } if let Some(occlusion_query_set) = desc.occlusion_query_set { - descriptor - .set_visibility_result_buffer(Some(occlusion_query_set.raw_buffer.as_ref())) + descriptor.setVisibilityResultBuffer(Some(occlusion_query_set.raw_buffer.as_ref())) } // This strangely isn't mentioned in https://developer.apple.com/documentation/metal/improving-rendering-performance-with-vertex-amplification. // The docs for [`renderTargetArrayLength`](https://developer.apple.com/documentation/metal/mtlrenderpassdescriptor/rendertargetarraylength) @@ -897,12 +891,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // However, when I don't set this, I get undefined behavior in nonzero layers, and all non-apple examples of vertex amplification set it. // So this is just one of those undocumented requirements. if let Some(mv) = desc.multiview_mask { - descriptor.set_render_target_array_length(32 - mv.leading_zeros() as usize); + descriptor.setRenderTargetArrayLength(32 - mv.leading_zeros() as usize); } let raw = self.raw_cmd_buf.as_ref().unwrap(); - let encoder = raw - .render_command_encoder_with_descriptor(&descriptor) - .unwrap(); + let encoder = raw.renderCommandEncoderWithDescriptor(&descriptor).unwrap(); if let Some(mv) = desc.multiview_mask { // Most likely the API just wasn't thought about enough. It's not like they ever allow you // to use enough views to overflow a 32-bit bitmask. @@ -918,14 +910,14 @@ impl crate::CommandEncoder for super::CommandEncoder { } } unsafe { - encoder.set_vertex_amplification_count_view_mappings( + encoder.setVertexAmplificationCount_viewMappings( mv.count_ones() as usize, maps.as_ptr(), ) }; } if let Some(label) = desc.label { - encoder.set_label(Some(&NSString::from_str(label))); + encoder.setLabel(Some(&NSString::from_str(label))); } self.state.render = Some(encoder); }); @@ -934,7 +926,7 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn end_render_pass(&mut self) { - self.state.render.take().unwrap().end_encoding(); + self.state.render.take().unwrap().endEncoding(); } unsafe fn set_bind_group( @@ -994,7 +986,7 @@ impl crate::CommandEncoder for super::CommandEncoder { ); // Call useResource on all textures and buffers used indirectly so they are alive for (resource, use_info) in group.resources_to_use.iter() { - encoder.use_resource_usage_stages( + encoder.useResource_usage_stages( unsafe { resource.as_ref() }, use_info.uses, use_info.stages, @@ -1028,7 +1020,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if !use_info.visible_in_compute { continue; } - encoder.use_resource_usage(unsafe { resource.as_ref() }, use_info.uses); + encoder.useResource_usage(unsafe { resource.as_ref() }, use_info.uses); } } } @@ -1051,7 +1043,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let bytes = NonNull::new(state_pc.as_ptr().cast_mut().cast()).unwrap(); if let Some(ref compute) = self.state.compute { unsafe { - compute.set_bytes_length_at_index( + compute.setBytes_length_atIndex( bytes, layout.total_immediates as usize * WORD_SIZE, layout.immediates_infos.cs.unwrap().buffer_index as usize, @@ -1061,7 +1053,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if let Some(ref render) = self.state.render { if let Some(vs) = layout.immediates_infos.vs { unsafe { - render.set_vertex_bytes_length_at_index( + render.setVertexBytes_length_atIndex( bytes, layout.total_immediates as usize * WORD_SIZE, vs.buffer_index as _, @@ -1070,7 +1062,7 @@ impl crate::CommandEncoder for super::CommandEncoder { } if let Some(fs) = layout.immediates_infos.fs { unsafe { - render.set_fragment_bytes_length_at_index( + render.setFragmentBytes_length_atIndex( bytes, layout.total_immediates as usize * WORD_SIZE, fs.buffer_index as _, @@ -1080,7 +1072,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if let Some(ts) = layout.immediates_infos.ts { if self.shared.private_caps.mesh_shaders { unsafe { - render.set_object_bytes_length_at_index( + render.setObjectBytes_length_atIndex( bytes, layout.total_immediates as usize * WORD_SIZE, ts.buffer_index as _, @@ -1091,7 +1083,7 @@ impl crate::CommandEncoder for super::CommandEncoder { if let Some(ms) = layout.immediates_infos.ms { if self.shared.private_caps.mesh_shaders { unsafe { - render.set_object_bytes_length_at_index( + render.setObjectBytes_length_atIndex( bytes, layout.total_immediates as usize * WORD_SIZE, ms.buffer_index as _, @@ -1104,21 +1096,21 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn insert_debug_marker(&mut self, label: &str) { if let Some(encoder) = self.active_encoder() { - encoder.insert_debug_signpost(&NSString::from_str(label)); + encoder.insertDebugSignpost(&NSString::from_str(label)); } } unsafe fn begin_debug_marker(&mut self, group_label: &str) { if let Some(encoder) = self.active_encoder() { - encoder.push_debug_group(&NSString::from_str(group_label)); + encoder.pushDebugGroup(&NSString::from_str(group_label)); } else if let Some(ref buf) = self.raw_cmd_buf { - buf.push_debug_group(&NSString::from_str(group_label)); + buf.pushDebugGroup(&NSString::from_str(group_label)); } } unsafe fn end_debug_marker(&mut self) { if let Some(encoder) = self.active_encoder() { - encoder.pop_debug_group(); + encoder.popDebugGroup(); } else if let Some(ref buf) = self.raw_cmd_buf { - buf.pop_debug_group(); + buf.popDebugGroup(); } } @@ -1142,16 +1134,16 @@ impl crate::CommandEncoder for super::CommandEncoder { } let encoder = self.state.render.as_ref().unwrap(); - encoder.set_render_pipeline_state(&pipeline.raw); - encoder.set_front_facing_winding(pipeline.raw_front_winding); - encoder.set_cull_mode(pipeline.raw_cull_mode); - encoder.set_triangle_fill_mode(pipeline.raw_triangle_fill_mode); + encoder.setRenderPipelineState(&pipeline.raw); + encoder.setFrontFacingWinding(pipeline.raw_front_winding); + encoder.setCullMode(pipeline.raw_cull_mode); + encoder.setTriangleFillMode(pipeline.raw_triangle_fill_mode); if let Some(depth_clip) = pipeline.raw_depth_clip_mode { - encoder.set_depth_clip_mode(depth_clip); + encoder.setDepthClipMode(depth_clip); } if let Some((ref state, bias)) = pipeline.depth_stencil { - encoder.set_depth_stencil_state(Some(state)); - encoder.set_depth_bias_slope_scale_clamp( + encoder.setDepthStencilState(Some(state)); + encoder.setDepthBias_slopeScale_clamp( bias.constant as f32, bias.slope_scale, bias.clamp, @@ -1164,7 +1156,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .make_sizes_buffer_update(naga::ShaderStage::Vertex, &mut self.temp.binding_sizes) { unsafe { - encoder.set_vertex_bytes_length_at_index( + encoder.setVertexBytes_length_atIndex( NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), sizes.len() * WORD_SIZE, index as _, @@ -1178,7 +1170,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .make_sizes_buffer_update(naga::ShaderStage::Fragment, &mut self.temp.binding_sizes) { unsafe { - encoder.set_fragment_bytes_length_at_index( + encoder.setFragmentBytes_length_atIndex( NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), sizes.len() * WORD_SIZE, index as _, @@ -1205,9 +1197,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let size = pipeline_size.next_multiple_of(16); if *cur_size != size { *cur_size = size; - unsafe { - encoder.set_object_threadgroup_memory_length_at_index(size as _, index) - }; + unsafe { encoder.setObjectThreadgroupMemoryLength_atIndex(size as _, index) }; } } if let Some((index, sizes)) = self @@ -1215,7 +1205,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .make_sizes_buffer_update(naga::ShaderStage::Task, &mut self.temp.binding_sizes) { unsafe { - encoder.set_object_bytes_length_at_index( + encoder.setObjectBytes_length_atIndex( NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), sizes.len() * WORD_SIZE, index as _, @@ -1234,7 +1224,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .make_sizes_buffer_update(naga::ShaderStage::Mesh, &mut self.temp.binding_sizes) { unsafe { - encoder.set_mesh_bytes_length_at_index( + encoder.setMeshBytes_length_atIndex( NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), sizes.len() * WORD_SIZE, index as _, @@ -1269,7 +1259,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let buffer_index = self.shared.private_caps.max_vertex_buffers as u64 - 1 - index as u64; let encoder = self.state.render.as_ref().unwrap(); unsafe { - encoder.setVertexBuffer_offset_atIndex_( + encoder.setVertexBuffer_offset_atIndex( Some(&binding.buffer.raw), binding.offset as usize, buffer_index as usize, @@ -1291,7 +1281,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .make_sizes_buffer_update(naga::ShaderStage::Vertex, &mut self.temp.binding_sizes) { unsafe { - encoder.set_vertex_bytes_length_at_index( + encoder.setVertexBytes_length_atIndex( NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), sizes.len() * WORD_SIZE, index as _, @@ -1307,7 +1297,7 @@ impl crate::CommandEncoder for super::CommandEncoder { depth_range.end }; let encoder = self.state.render.as_ref().unwrap(); - encoder.set_viewport(MTLViewport { + encoder.setViewport(MTLViewport { originX: rect.x as _, originY: rect.y as _, width: rect.w as _, @@ -1325,15 +1315,15 @@ impl crate::CommandEncoder for super::CommandEncoder { height: rect.h as _, }; let encoder = self.state.render.as_ref().unwrap(); - encoder.set_scissor_rect(scissor); + encoder.setScissorRect(scissor); } unsafe fn set_stencil_reference(&mut self, value: u32) { let encoder = self.state.render.as_ref().unwrap(); - encoder.set_stencil_front_reference_value_back_reference_value(value, value); + encoder.setStencilFrontReferenceValue_backReferenceValue(value, value); } unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) { let encoder = self.state.render.as_ref().unwrap(); - encoder.set_blend_color_red_green_blue_alpha(color[0], color[1], color[2], color[3]); + encoder.setBlendColorRed_green_blue_alpha(color[0], color[1], color[2], color[3]); } unsafe fn draw( @@ -1346,7 +1336,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.render.as_ref().unwrap(); if first_instance != 0 { unsafe { - encoder.draw_primitives_vertex_start_vertex_count_instance_count_base_instance( + encoder.drawPrimitives_vertexStart_vertexCount_instanceCount_baseInstance( self.state.raw_primitive_type, first_vertex as _, vertex_count as _, @@ -1356,7 +1346,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } else if instance_count != 1 { unsafe { - encoder.draw_primitives_vertex_start_vertex_count_instance_count( + encoder.drawPrimitives_vertexStart_vertexCount_instanceCount( self.state.raw_primitive_type, first_vertex as _, vertex_count as _, @@ -1365,7 +1355,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } else { unsafe { - encoder.draw_primitives_vertex_start_vertex_count( + encoder.drawPrimitives_vertexStart_vertexCount( self.state.raw_primitive_type, first_vertex as _, vertex_count as _, @@ -1387,7 +1377,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let offset = (index.offset + index.stride * first_index as wgt::BufferAddress) as usize; if base_vertex != 0 || first_instance != 0 { unsafe { - encoder.draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_offset_instance_count_base_vertex_base_instance( + encoder.drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset_instanceCount_baseVertex_baseInstance( self.state.raw_primitive_type, index_count as _, index.raw_type, @@ -1400,7 +1390,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } else if instance_count != 1 { unsafe { - encoder.draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_offset_instance_count( + encoder.drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset_instanceCount( self.state.raw_primitive_type, index_count as _, index.raw_type, @@ -1411,7 +1401,7 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } else { unsafe { - encoder.draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_offset( + encoder.drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset( self.state.raw_primitive_type, index_count as _, index.raw_type, @@ -1434,7 +1424,7 @@ impl crate::CommandEncoder for super::CommandEncoder { height: group_count_y as usize, depth: group_count_z as usize, }; - encoder.draw_mesh_threadgroups_threads_per_object_threadgroup_threads_per_mesh_threadgroup( + encoder.drawMeshThreadgroups_threadsPerObjectThreadgroup_threadsPerMeshThreadgroup( size, self.state.stage_infos.ts.raw_wg_size, self.state.stage_infos.ms.raw_wg_size, @@ -1450,7 +1440,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.render.as_ref().unwrap(); for _ in 0..draw_count { unsafe { - encoder.draw_primitives_indirect_buffer_indirect_buffer_offset( + encoder.drawPrimitives_indirectBuffer_indirectBufferOffset( self.state.raw_primitive_type, &buffer.raw, offset as usize, @@ -1470,7 +1460,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let index = self.state.index.as_ref().unwrap(); for _ in 0..draw_count { unsafe { - encoder.draw_indexed_primitives_index_type_index_buffer_index_buffer_offset_indirect_buffer_indirect_buffer_offset( + encoder.drawIndexedPrimitives_indexType_indexBuffer_indexBufferOffset_indirectBuffer_indirectBufferOffset( self.state.raw_primitive_type, index.raw_type, index.buffer_ptr.as_ref(), @@ -1492,7 +1482,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.render.as_ref().unwrap(); for _ in 0..draw_count { unsafe { - encoder.draw_mesh_threadgroups_with_indirect_buffer_indirect_buffer_offset_threads_per_object_threadgroup_threads_per_mesh_threadgroup( + encoder.drawMeshThreadgroupsWithIndirectBuffer_indirectBufferOffset_threadsPerObjectThreadgroup_threadsPerMeshThreadgroup( &buffer.raw, offset as usize, self.state.stage_infos.ts.raw_wg_size, @@ -1550,7 +1540,7 @@ impl crate::CommandEncoder for super::CommandEncoder { // TimeStamp Queries and ComputePassDescriptor were both introduced in Metal 2.3 (macOS 11, iOS 14) // and we currently only need ComputePassDescriptor for timestamp queries let encoder = if self.shared.private_caps.timestamp_query_support.is_empty() { - raw.compute_command_encoder().unwrap() + raw.computeCommandEncoder().unwrap() } else { let descriptor = MTLComputePassDescriptor::new(); @@ -1558,8 +1548,8 @@ impl crate::CommandEncoder for super::CommandEncoder { let mut next_sba_descriptor = || { let sba_descriptor = unsafe { descriptor - .sample_buffer_attachments() - .object_at_indexed_subscript(sba_index) + .sampleBufferAttachments() + .objectAtIndexedSubscript(sba_index) }; sba_index += 1; sba_descriptor @@ -1568,14 +1558,14 @@ impl crate::CommandEncoder for super::CommandEncoder { for (set, index) in self.state.pending_timer_queries.drain(..) { let sba_descriptor = next_sba_descriptor(); sba_descriptor - .set_sample_buffer(Some(set.counter_sample_buffer.as_ref().unwrap())); - unsafe { sba_descriptor.set_start_of_encoder_sample_index(index as _) }; - unsafe { sba_descriptor.set_end_of_encoder_sample_index(MTLCounterDontSample) }; + .setSampleBuffer(Some(set.counter_sample_buffer.as_ref().unwrap())); + unsafe { sba_descriptor.setStartOfEncoderSampleIndex(index as _) }; + unsafe { sba_descriptor.setEndOfEncoderSampleIndex(MTLCounterDontSample) }; } if let Some(timestamp_writes) = desc.timestamp_writes.as_ref() { let sba_descriptor = next_sba_descriptor(); - sba_descriptor.set_sample_buffer(Some( + sba_descriptor.setSampleBuffer(Some( timestamp_writes .query_set .counter_sample_buffer @@ -1584,14 +1574,14 @@ impl crate::CommandEncoder for super::CommandEncoder { )); unsafe { - sba_descriptor.set_start_of_encoder_sample_index( + sba_descriptor.setStartOfEncoderSampleIndex( timestamp_writes .beginning_of_pass_write_index .map_or(MTLCounterDontSample, |i| i as _), ) }; unsafe { - sba_descriptor.set_end_of_encoder_sample_index( + sba_descriptor.setEndOfEncoderSampleIndex( timestamp_writes .end_of_pass_write_index .map_or(MTLCounterDontSample, |i| i as _), @@ -1599,19 +1589,19 @@ impl crate::CommandEncoder for super::CommandEncoder { }; } - raw.compute_command_encoder_with_descriptor(&descriptor) + raw.computeCommandEncoderWithDescriptor(&descriptor) .unwrap() }; if let Some(label) = desc.label { - encoder.set_label(Some(&NSString::from_str(label))); + encoder.setLabel(Some(&NSString::from_str(label))); } self.state.compute = Some(encoder.to_owned()); }); } unsafe fn end_compute_pass(&mut self) { - self.state.compute.take().unwrap().end_encoding(); + self.state.compute.take().unwrap().endEncoding(); } unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) { @@ -1620,14 +1610,14 @@ impl crate::CommandEncoder for super::CommandEncoder { self.state.stage_infos.cs.assign_from(&pipeline.cs_info); let encoder = self.state.compute.as_ref().unwrap(); - encoder.set_compute_pipeline_state(&pipeline.raw); + encoder.setComputePipelineState(&pipeline.raw); if let Some((index, sizes)) = self .state .make_sizes_buffer_update(naga::ShaderStage::Compute, &mut self.temp.binding_sizes) { unsafe { - encoder.set_bytes_length_at_index( + encoder.setBytes_length_atIndex( NonNull::new(sizes.as_ptr().cast_mut().cast()).unwrap(), sizes.len() * WORD_SIZE, index as _, @@ -1652,7 +1642,7 @@ impl crate::CommandEncoder for super::CommandEncoder { let size: u32 = current_size.next_multiple_of(16); *current_size = size; if size != prev_size { - unsafe { encoder.set_threadgroup_memory_length_at_index(size as _, i) }; + unsafe { encoder.setThreadgroupMemoryLength_atIndex(size as _, i) }; } } } @@ -1665,7 +1655,7 @@ impl crate::CommandEncoder for super::CommandEncoder { height: count[1] as usize, depth: count[2] as usize, }; - encoder.dispatch_threadgroups_threads_per_threadgroup( + encoder.dispatchThreadgroups_threadsPerThreadgroup( raw_count, self.state.stage_infos.cs.raw_wg_size, ); @@ -1675,11 +1665,12 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) { let encoder = self.state.compute.as_ref().unwrap(); unsafe { - encoder.dispatch_threadgroups_with_indirect_buffer_indirect_buffer_offset_threads_per_threadgroup( - &buffer.raw, - offset as usize, - self.state.stage_infos.cs.raw_wg_size, - ) + encoder + .dispatchThreadgroupsWithIndirectBuffer_indirectBufferOffset_threadsPerThreadgroup( + &buffer.raw, + offset as usize, + self.state.stage_infos.cs.raw_wg_size, + ) }; } @@ -1726,7 +1717,7 @@ impl Drop for super::CommandEncoder { // appears to be a requirement for all MTLCommandEncoder objects. Failing to call // endEncoding causes a crash with the message 'Command encoder released without // endEncoding'. To prevent this, we explicitiy call discard_encoding, which - // calls end_encoding on any still-held MTLCommandEncoders. + // calls endEncoding on any still-held MTLCommandEncoders. unsafe { self.discard_encoding(); } diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 5b058f1f1ed..ce6386f8887 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -51,12 +51,12 @@ fn create_stencil_desc( write_mask: u32, ) -> Retained { let desc = MTLStencilDescriptor::new(); - desc.set_stencil_compare_function(conv::map_compare_function(face.compare)); - desc.set_read_mask(read_mask); - desc.set_write_mask(write_mask); - desc.set_stencil_failure_operation(conv::map_stencil_op(face.fail_op)); - desc.set_depth_failure_operation(conv::map_stencil_op(face.depth_fail_op)); - desc.set_depth_stencil_pass_operation(conv::map_stencil_op(face.pass_op)); + desc.setStencilCompareFunction(conv::map_compare_function(face.compare)); + desc.setReadMask(read_mask); + desc.setWriteMask(write_mask); + desc.setStencilFailureOperation(conv::map_stencil_op(face.fail_op)); + desc.setDepthFailureOperation(conv::map_stencil_op(face.depth_fail_op)); + desc.setDepthStencilPassOperation(conv::map_stencil_op(face.pass_op)); desc } @@ -64,14 +64,14 @@ fn create_depth_stencil_desc( state: &wgt::DepthStencilState, ) -> Retained { let desc = MTLDepthStencilDescriptor::new(); - desc.set_depth_compare_function(conv::map_compare_function(state.depth_compare)); - desc.set_depth_write_enabled(state.depth_write_enabled); + desc.setDepthCompareFunction(conv::map_compare_function(state.depth_compare)); + desc.setDepthWriteEnabled(state.depth_write_enabled); let s = &state.stencil; if s.is_enabled() { let front_desc = create_stencil_desc(&s.front, s.read_mask, s.write_mask); - desc.set_front_face_stencil(Some(&front_desc)); + desc.setFrontFaceStencil(Some(&front_desc)); let back_desc = create_stencil_desc(&s.back, s.read_mask, s.write_mask); - desc.set_back_face_stencil(Some(&back_desc)); + desc.setBackFaceStencil(Some(&back_desc)); } desc } @@ -219,16 +219,16 @@ impl super::Device { ); let options = MTLCompileOptions::new(); - options.set_language_version(self.shared.private_caps.msl_version); + options.setLanguageVersion(self.shared.private_caps.msl_version); if self.shared.private_caps.supports_preserve_invariance { - options.set_preserve_invariance(true); + options.setPreserveInvariance(true); } let library = self .shared .device - .new_library_with_source_options_error( + .newLibraryWithSource_options_error( &NSString::from_str(&source), Some(&options), ) @@ -254,7 +254,7 @@ impl super::Device { }; let function = library - .new_function_with_name(&NSString::from_str(translated_ep_name)) + .newFunctionWithName(&NSString::from_str(translated_ep_name)) .ok_or_else(|| { log::error!("Function '{translated_ep_name}' does not exist"); crate::PipelineError::EntryPoint(naga_stage) @@ -340,8 +340,8 @@ impl super::Device { while immutable_mask != 0 { let slot = immutable_mask.trailing_zeros(); immutable_mask ^= 1 << slot; - unsafe { buffers.object_at_indexed_subscript(slot as usize) } - .set_mutability(MTLMutability::Immutable); + unsafe { buffers.objectAtIndexedSubscript(slot as usize) } + .setMutability(MTLMutability::Immutable); } } @@ -408,10 +408,10 @@ impl crate::Device for super::Device { let raw = self .shared .device - .new_buffer_with_length_options(desc.size as usize, options) + .newBufferWithLength_options(desc.size as usize, options) .unwrap(); if let Some(label) = desc.label { - raw.set_label(Some(&NSString::from_str(label))); + raw.setLabel(Some(&NSString::from_str(label))); } self.counters.buffers.add(1); Ok(super::Buffer { @@ -457,11 +457,11 @@ impl crate::Device for super::Device { wgt::TextureDimension::D1 => MTLTextureType::Type1D, wgt::TextureDimension::D2 => { if desc.sample_count > 1 { - unsafe { descriptor.set_sample_count(desc.sample_count as usize) }; + unsafe { descriptor.setSampleCount(desc.sample_count as usize) }; MTLTextureType::Type2DMultisample } else if desc.size.depth_or_array_layers > 1 { unsafe { - descriptor.set_array_length(desc.size.depth_or_array_layers as usize) + descriptor.setArrayLength(desc.size.depth_or_array_layers as usize) }; MTLTextureType::Type2DArray } else { @@ -469,7 +469,7 @@ impl crate::Device for super::Device { } } wgt::TextureDimension::D3 => { - unsafe { descriptor.set_depth(desc.size.depth_or_array_layers as usize) }; + unsafe { descriptor.setDepth(desc.size.depth_or_array_layers as usize) }; MTLTextureType::Type3D } }; @@ -482,21 +482,21 @@ impl crate::Device for super::Device { MTLStorageMode::Private }; - descriptor.set_texture_type(mtl_type); - unsafe { descriptor.set_width(desc.size.width as usize) }; - unsafe { descriptor.set_height(desc.size.height as usize) }; - unsafe { descriptor.set_mipmap_level_count(desc.mip_level_count as usize) }; - descriptor.set_pixel_format(mtl_format); - descriptor.set_usage(conv::map_texture_usage(desc.format, desc.usage)); - descriptor.set_storage_mode(mtl_storage_mode); + descriptor.setTextureType(mtl_type); + unsafe { descriptor.setWidth(desc.size.width as usize) }; + unsafe { descriptor.setHeight(desc.size.height as usize) }; + unsafe { descriptor.setMipmapLevelCount(desc.mip_level_count as usize) }; + descriptor.setPixelFormat(mtl_format); + descriptor.setUsage(conv::map_texture_usage(desc.format, desc.usage)); + descriptor.setStorageMode(mtl_storage_mode); let raw = self .shared .device - .new_texture_with_descriptor(&descriptor) + .newTextureWithDescriptor(&descriptor) .ok_or(crate::DeviceError::OutOfMemory)?; if let Some(label) = desc.label { - raw.set_label(Some(&NSString::from_str(label))); + raw.setLabel(Some(&NSString::from_str(label))); } self.counters.textures.add(1); @@ -570,7 +570,7 @@ impl crate::Device for super::Device { let raw = unsafe { texture .raw - .new_texture_view_with_pixel_format_texture_type_levels_slices( + .newTextureViewWithPixelFormat_textureType_levels_slices( raw_format, raw_type, level_range, @@ -579,7 +579,7 @@ impl crate::Device for super::Device { .unwrap() }; if let Some(label) = desc.label { - raw.set_label(Some(&NSString::from_str(label))); + raw.setLabel(Some(&NSString::from_str(label))); } raw }) @@ -601,9 +601,9 @@ impl crate::Device for super::Device { autoreleasepool(|_| { let descriptor = MTLSamplerDescriptor::new(); - descriptor.set_min_filter(conv::map_filter_mode(desc.min_filter)); - descriptor.set_mag_filter(conv::map_filter_mode(desc.mag_filter)); - descriptor.set_mip_filter(match desc.mipmap_filter { + descriptor.setMinFilter(conv::map_filter_mode(desc.min_filter)); + descriptor.setMagFilter(conv::map_filter_mode(desc.mag_filter)); + descriptor.setMipFilter(match desc.mipmap_filter { wgt::MipmapFilterMode::Nearest if desc.lod_clamp == (0.0..0.0) => { MTLSamplerMipFilter::NotMipmapped } @@ -612,48 +612,48 @@ impl crate::Device for super::Device { }); let [s, t, r] = desc.address_modes; - descriptor.set_s_address_mode(conv::map_address_mode(s)); - descriptor.set_t_address_mode(conv::map_address_mode(t)); - descriptor.set_r_address_mode(conv::map_address_mode(r)); + descriptor.setSAddressMode(conv::map_address_mode(s)); + descriptor.setTAddressMode(conv::map_address_mode(t)); + descriptor.setRAddressMode(conv::map_address_mode(r)); // Anisotropy is always supported on mac up to 16x - descriptor.set_max_anisotropy(desc.anisotropy_clamp as _); + descriptor.setMaxAnisotropy(desc.anisotropy_clamp as _); - descriptor.set_lod_min_clamp(desc.lod_clamp.start); - descriptor.set_lod_max_clamp(desc.lod_clamp.end); + descriptor.setLodMinClamp(desc.lod_clamp.start); + descriptor.setLodMaxClamp(desc.lod_clamp.end); if let Some(fun) = desc.compare { - descriptor.set_compare_function(conv::map_compare_function(fun)); + descriptor.setCompareFunction(conv::map_compare_function(fun)); } if let Some(border_color) = desc.border_color { if let wgt::SamplerBorderColor::Zero = border_color { if s == wgt::AddressMode::ClampToBorder { - descriptor.set_s_address_mode(MTLSamplerAddressMode::ClampToZero); + descriptor.setSAddressMode(MTLSamplerAddressMode::ClampToZero); } if t == wgt::AddressMode::ClampToBorder { - descriptor.set_t_address_mode(MTLSamplerAddressMode::ClampToZero); + descriptor.setTAddressMode(MTLSamplerAddressMode::ClampToZero); } if r == wgt::AddressMode::ClampToBorder { - descriptor.set_r_address_mode(MTLSamplerAddressMode::ClampToZero); + descriptor.setRAddressMode(MTLSamplerAddressMode::ClampToZero); } } else { - descriptor.set_border_color(conv::map_border_color(border_color)); + descriptor.setBorderColor(conv::map_border_color(border_color)); } } if let Some(label) = desc.label { - descriptor.set_label(Some(&NSString::from_str(label))); + descriptor.setLabel(Some(&NSString::from_str(label))); } if self.features.contains(wgt::Features::TEXTURE_BINDING_ARRAY) { - descriptor.set_support_argument_buffers(true); + descriptor.setSupportArgumentBuffers(true); } let raw = self .shared .device - .new_sampler_state_with_descriptor(&descriptor) + .newSamplerStateWithDescriptor(&descriptor) .unwrap(); self.counters.samplers.add(1); @@ -912,7 +912,7 @@ impl crate::Device for super::Device { let buffer = self .shared .device - .new_buffer_with_length_options( + .newBufferWithLength_options( 8 * count as usize, MTLResourceOptions::HazardTrackingModeUntracked | MTLResourceOptions::StorageModeShared, @@ -934,7 +934,7 @@ impl crate::Device for super::Device { let textures = &desc.textures[start..end]; for (idx, tex) in textures.iter().enumerate() { - contents[idx] = tex.view.raw.gpu_resource_id(); + contents[idx] = tex.view.raw.gpuResourceID(); let use_info = bg .resources_to_use @@ -952,7 +952,7 @@ impl crate::Device for super::Device { let samplers = &desc.samplers[start..end]; for (idx, &sampler) in samplers.iter().enumerate() { - contents[idx] = sampler.raw.gpu_resource_id(); + contents[idx] = sampler.raw.gpuResourceID(); // Samplers aren't resources like buffers and textures, so don't // need to be passed to useResource } @@ -1098,13 +1098,10 @@ impl crate::Device for super::Device { // Obtain the device from shared let device = &self.shared.device; let library = device - .new_library_with_source_options_error( - &NSString::from_str(source), - Some(&options), - ) + .newLibraryWithSource_options_error(&NSString::from_str(source), Some(&options)) .map_err(|e| crate::ShaderError::Compilation(format!("MSL: {e:?}")))?; let function = library - .new_function_with_name(&NSString::from_str(&entry_point)) + .newFunctionWithName(&NSString::from_str(&entry_point)) .ok_or_else(|| { crate::ShaderError::Compilation(format!( "Entry point '{entry_point}' not found" @@ -1153,35 +1150,36 @@ impl crate::Device for super::Device { } }; } + #[allow(non_snake_case)] impl MetalGenericRenderPipelineDescriptor { - unsafe fn set_fragment_function( + unsafe fn setFragmentFunction( &self, function: Option<&ProtocolObject>, ) { - unsafe { descriptor_fn!(self.set_fragment_function(function)) }; + unsafe { descriptor_fn!(self.setFragmentFunction(function)) }; } - fn fragment_buffers(&self) -> Retained { - descriptor_fn!(self.fragment_buffers()) + fn fragmentBuffers(&self) -> Retained { + descriptor_fn!(self.fragmentBuffers()) } - fn set_depth_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { - descriptor_fn!(self.set_depth_attachment_pixel_format(pixel_format)); + fn setDepthAttachmentPixelFormat(&self, pixel_format: MTLPixelFormat) { + descriptor_fn!(self.setDepthAttachmentPixelFormat(pixel_format)); } - fn color_attachments( + fn colorAttachments( &self, ) -> Retained { - descriptor_fn!(self.color_attachments()) + descriptor_fn!(self.colorAttachments()) } - fn set_stencil_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { - descriptor_fn!(self.set_stencil_attachment_pixel_format(pixel_format)); + fn setStencilAttachmentPixelFormat(&self, pixel_format: MTLPixelFormat) { + descriptor_fn!(self.setStencilAttachmentPixelFormat(pixel_format)); } - fn set_alpha_to_coverage_enabled(&self, enabled: bool) { - descriptor_fn!(self.set_alpha_to_coverage_enabled(enabled)); + fn setAlphaToCoverageEnabled(&self, enabled: bool) { + descriptor_fn!(self.setAlphaToCoverageEnabled(enabled)); } - fn set_label(&self, label: Option<&NSString>) { - descriptor_fn!(self.set_label(label)); + fn setLabel(&self, label: Option<&NSString>) { + descriptor_fn!(self.setLabel(label)); } - unsafe fn set_max_vertex_amplification_count(&self, count: NSUInteger) { - unsafe { descriptor_fn!(self.set_max_vertex_amplification_count(count)) } + unsafe fn setMaxVertexAmplificationCount(&self, count: NSUInteger) { + unsafe { descriptor_fn!(self.setMaxVertexAmplificationCount(count)) } } } @@ -1254,10 +1252,10 @@ impl crate::Device for super::Device { naga::ShaderStage::Vertex, )?; - descriptor.set_vertex_function(Some(&vs.function)); + descriptor.setVertexFunction(Some(&vs.function)); if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - &descriptor.vertex_buffers(), + &descriptor.vertexBuffers(), vs.immutable_buffer_mask, ); } @@ -1301,7 +1299,7 @@ impl crate::Device for super::Device { let buffer_desc = unsafe { vertex_descriptor .layouts() - .object_at_indexed_subscript(buffer_index) + .objectAtIndexedSubscript(buffer_index) }; // Metal expects the stride to be the actual size of the attributes. @@ -1315,27 +1313,27 @@ impl crate::Device for super::Device { .max() .unwrap_or(0); unsafe { - buffer_desc.set_stride(wgt::math::align_to(stride as _, 4)) + buffer_desc.setStride(wgt::math::align_to(stride as _, 4)) }; - buffer_desc.set_step_function(MTLVertexStepFunction::Constant); - unsafe { buffer_desc.set_step_rate(0) }; + buffer_desc.setStepFunction(MTLVertexStepFunction::Constant); + unsafe { buffer_desc.setStepRate(0) }; } else { - unsafe { buffer_desc.set_stride(vb.array_stride as _) }; - buffer_desc.set_step_function(conv::map_step_mode(vb.step_mode)); + unsafe { buffer_desc.setStride(vb.array_stride as _) }; + buffer_desc.setStepFunction(conv::map_step_mode(vb.step_mode)); } for at in vb.attributes { let attribute_desc = unsafe { vertex_descriptor .attributes() - .object_at_indexed_subscript(at.shader_location as _) + .objectAtIndexedSubscript(at.shader_location as _) }; - attribute_desc.set_format(conv::map_vertex_format(at.format)); - unsafe { attribute_desc.set_buffer_index(buffer_index) }; - unsafe { attribute_desc.set_offset(at.offset as _) }; + attribute_desc.setFormat(conv::map_vertex_format(at.format)); + unsafe { attribute_desc.setBufferIndex(buffer_index) }; + unsafe { attribute_desc.setOffset(at.offset as _) }; } } - descriptor.set_vertex_descriptor(Some(&vertex_descriptor)); + descriptor.setVertexDescriptor(Some(&vertex_descriptor)); } MetalGenericRenderPipelineDescriptor::Standard(descriptor) @@ -1358,10 +1356,10 @@ impl crate::Device for super::Device { primitive_class, naga::ShaderStage::Task, )?; - unsafe { descriptor.set_object_function(Some(&ts.function)) }; + unsafe { descriptor.setObjectFunction(Some(&ts.function)) }; if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - &descriptor.mesh_buffers(), + &descriptor.meshBuffers(), ts.immutable_buffer_mask, ); } @@ -1387,10 +1385,10 @@ impl crate::Device for super::Device { primitive_class, naga::ShaderStage::Mesh, )?; - unsafe { descriptor.set_mesh_function(Some(&ms.function)) }; + unsafe { descriptor.setMeshFunction(Some(&ms.function)) }; if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - &descriptor.mesh_buffers(), + &descriptor.meshBuffers(), ms.immutable_buffer_mask, ); } @@ -1429,10 +1427,10 @@ impl crate::Device for super::Device { naga::ShaderStage::Fragment, )?; - unsafe { descriptor.set_fragment_function(Some(&fs.function)) }; + unsafe { descriptor.setFragmentFunction(Some(&fs.function)) }; if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability( - &descriptor.fragment_buffers(), + &descriptor.fragmentBuffers(), fs.immutable_buffer_mask, ); } @@ -1455,7 +1453,7 @@ impl crate::Device for super::Device { // TODO: This is a workaround for what appears to be a Metal validation bug // A pixel format is required even though no attachments are provided if desc.color_targets.is_empty() && desc.depth_stencil.is_none() { - descriptor.set_depth_attachment_pixel_format(MTLPixelFormat::Depth32Float); + descriptor.setDepthAttachmentPixelFormat(MTLPixelFormat::Depth32Float); } None } @@ -1463,34 +1461,31 @@ impl crate::Device for super::Device { // Setup pipeline color attachments for (i, ct) in desc.color_targets.iter().enumerate() { - let at_descriptor = unsafe { - descriptor - .color_attachments() - .object_at_indexed_subscript(i) - }; + let at_descriptor = + unsafe { descriptor.colorAttachments().objectAtIndexedSubscript(i) }; let ct = if let Some(color_target) = ct.as_ref() { color_target } else { - at_descriptor.set_pixel_format(MTLPixelFormat::Invalid); + at_descriptor.setPixelFormat(MTLPixelFormat::Invalid); continue; }; let raw_format = self.shared.private_caps.map_format(ct.format); - at_descriptor.set_pixel_format(raw_format); - at_descriptor.set_write_mask(conv::map_color_write(ct.write_mask)); + at_descriptor.setPixelFormat(raw_format); + at_descriptor.setWriteMask(conv::map_color_write(ct.write_mask)); if let Some(ref blend) = ct.blend { - at_descriptor.set_blending_enabled(true); + at_descriptor.setBlendingEnabled(true); let (color_op, color_src, color_dst) = conv::map_blend_component(&blend.color); let (alpha_op, alpha_src, alpha_dst) = conv::map_blend_component(&blend.alpha); - at_descriptor.set_rgb_blend_operation(color_op); - at_descriptor.set_source_rgb_blend_factor(color_src); - at_descriptor.set_destination_rgb_blend_factor(color_dst); + at_descriptor.setRgbBlendOperation(color_op); + at_descriptor.setSourceRGBBlendFactor(color_src); + at_descriptor.setDestinationRGBBlendFactor(color_dst); - at_descriptor.set_alpha_blend_operation(alpha_op); - at_descriptor.set_source_alpha_blend_factor(alpha_src); - at_descriptor.set_destination_alpha_blend_factor(alpha_dst); + at_descriptor.setAlphaBlendOperation(alpha_op); + at_descriptor.setSourceAlphaBlendFactor(alpha_src); + at_descriptor.setDestinationAlphaBlendFactor(alpha_dst); } } @@ -1500,14 +1495,18 @@ impl crate::Device for super::Device { let raw_format = self.shared.private_caps.map_format(ds.format); let aspects = crate::FormatAspects::from(ds.format); if aspects.contains(crate::FormatAspects::DEPTH) { - descriptor.set_depth_attachment_pixel_format(raw_format); + descriptor.setDepthAttachmentPixelFormat(raw_format); } if aspects.contains(crate::FormatAspects::STENCIL) { - descriptor.set_stencil_attachment_pixel_format(raw_format); + descriptor.setStencilAttachmentPixelFormat(raw_format); } let ds_descriptor = create_depth_stencil_desc(ds); - let raw = self.shared.device.new_depth_stencil_state_with_descriptor(&ds_descriptor).unwrap(); + let raw = self + .shared + .device + .newDepthStencilStateWithDescriptor(&ds_descriptor) + .unwrap(); Some((raw, ds.bias)) } None => None, @@ -1519,24 +1518,23 @@ impl crate::Device for super::Device { match descriptor { MetalGenericRenderPipelineDescriptor::Standard(ref inner) => { #[allow(deprecated)] - inner.set_sample_count(desc.multisample.count as _); + inner.setSampleCount(desc.multisample.count as _); } MetalGenericRenderPipelineDescriptor::Mesh(ref inner) => { - unsafe { inner.set_raster_sample_count(desc.multisample.count as _) }; + unsafe { inner.setRasterSampleCount(desc.multisample.count as _) }; } } - descriptor - .set_alpha_to_coverage_enabled(desc.multisample.alpha_to_coverage_enabled); + descriptor.setAlphaToCoverageEnabled(desc.multisample.alpha_to_coverage_enabled); //descriptor.set_alpha_to_one_enabled(desc.multisample.alpha_to_one_enabled); } // Set debug label if let Some(name) = desc.label { - descriptor.set_label(Some(&NSString::from_str(name))); + descriptor.setLabel(Some(&NSString::from_str(name))); } if let Some(mv) = desc.multiview_mask { unsafe { - descriptor.set_max_vertex_amplification_count(mv.get().count_ones() as usize) + descriptor.setMaxVertexAmplificationCount(mv.get().count_ones() as usize) }; } @@ -1545,10 +1543,11 @@ impl crate::Device for super::Device { MetalGenericRenderPipelineDescriptor::Standard(d) => self .shared .device - .new_render_pipeline_state_with_descriptor_error(&d), + .newRenderPipelineStateWithDescriptor_error(&d), MetalGenericRenderPipelineDescriptor::Mesh(d) => { - // TODO: `newRenderPipelineStateWithMeshDescriptor:error:` is not exposed on - // `MTLDevice`, is this always correct? + // TODO(https://github.com/gfx-rs/wgpu/issues/8944): + // `newRenderPipelineStateWithMeshDescriptor:error:` is + // not exposed on `MTLDevice`, is this always correct? let device = &self.shared.device; unsafe { msg_send![device, newRenderPipelineStateWithMeshDescriptor: &*d, error: _] @@ -1627,7 +1626,7 @@ impl crate::Device for super::Device { )? }; - descriptor.set_compute_function(Some(&cs.function)); + descriptor.setComputeFunction(Some(&cs.function)); if self.shared.private_caps.supports_mutability { Self::set_buffers_mutability(&descriptor.buffers(), cs.immutable_buffer_mask); @@ -1644,11 +1643,12 @@ impl crate::Device for super::Device { }; if let Some(name) = desc.label { - descriptor.set_label(Some(&NSString::from_str(name))); + descriptor.setLabel(Some(&NSString::from_str(name))); } - // TODO: `newComputePipelineStateWithDescriptor:error:` is not exposed on - // `MTLDevice`, is this always correct? + // TODO(https://github.com/gfx-rs/wgpu/issues/8944): + // `newComputePipelineStateWithDescriptor:error:` is not exposed + // on `MTLDevice`, is this always correct? let device = &self.shared.device; let raw = unsafe { msg_send![device, newComputePipelineStateWithDescriptor: &*descriptor, error: _] @@ -1693,10 +1693,10 @@ impl crate::Device for super::Device { let raw_buffer = self .shared .device - .new_buffer_with_length_options(size as usize, options) + .newBufferWithLength_options(size as usize, options) .unwrap(); if let Some(label) = desc.label { - raw_buffer.set_label(Some(&NSString::from_str(label))); + raw_buffer.setLabel(Some(&NSString::from_str(label))); } Ok(super::QuerySet { raw_buffer, @@ -1708,17 +1708,17 @@ impl crate::Device for super::Device { let size = desc.count as u64 * crate::QUERY_SIZE; let device = &self.shared.device; let destination_buffer = device - .new_buffer_with_length_options(size as usize, MTLResourceOptions::empty()) + .newBufferWithLength_options(size as usize, MTLResourceOptions::empty()) .unwrap(); let csb_desc = MTLCounterSampleBufferDescriptor::new(); - csb_desc.set_storage_mode(MTLStorageMode::Shared); - unsafe { csb_desc.set_sample_count(desc.count as _) }; + csb_desc.setStorageMode(MTLStorageMode::Shared); + unsafe { csb_desc.setSampleCount(desc.count as _) }; if let Some(label) = desc.label { - csb_desc.set_label(&NSString::from_str(label)); + csb_desc.setLabel(&NSString::from_str(label)); } - let counter_sets = device.counter_sets().unwrap(); + let counter_sets = device.counterSets().unwrap(); let timestamp_counter = match counter_sets .iter() .find(|cs| &*cs.name() == ns_string!("timestamp")) @@ -1729,10 +1729,10 @@ impl crate::Device for super::Device { return Err(crate::DeviceError::Unexpected); } }; - csb_desc.set_counter_set(Some(×tamp_counter)); + csb_desc.setCounterSet(Some(×tamp_counter)); let counter_sample_buffer = - match device.new_counter_sample_buffer_with_descriptor_error(&csb_desc) { + match device.newCounterSampleBufferWithDescriptor_error(&csb_desc) { Ok(buffer) => buffer, Err(err) => { log::error!("Failed to create counter sample buffer: {err:?}"); @@ -1762,7 +1762,7 @@ impl crate::Device for super::Device { unsafe fn create_fence(&self) -> DeviceResult { self.counters.fences.add(1); let shared_event = if self.shared.private_caps.supports_shared_event { - Some(self.shared.device.new_shared_event().unwrap()) + Some(self.shared.device.newSharedEvent().unwrap()) } else { None }; @@ -1827,21 +1827,21 @@ impl crate::Device for super::Device { return false; } let device = &self.shared.device; - let shared_capture_manager = unsafe { MTLCaptureManager::shared_capture_manager() }; - let default_capture_scope = shared_capture_manager.new_capture_scope_with_device(device); - shared_capture_manager.set_default_capture_scope(Some(&default_capture_scope)); + let shared_capture_manager = unsafe { MTLCaptureManager::sharedCaptureManager() }; + let default_capture_scope = shared_capture_manager.newCaptureScopeWithDevice(device); + shared_capture_manager.setDefaultCaptureScope(Some(&default_capture_scope)); #[allow(deprecated)] - shared_capture_manager.start_capture_with_scope(&default_capture_scope); - default_capture_scope.begin_scope(); + shared_capture_manager.startCaptureWithScope(&default_capture_scope); + default_capture_scope.beginScope(); true } unsafe fn stop_graphics_debugger_capture(&self) { - let shared_capture_manager = unsafe { MTLCaptureManager::shared_capture_manager() }; - if let Some(default_capture_scope) = shared_capture_manager.default_capture_scope() { - default_capture_scope.end_scope(); + let shared_capture_manager = unsafe { MTLCaptureManager::sharedCaptureManager() }; + if let Some(default_capture_scope) = shared_capture_manager.defaultCaptureScope() { + default_capture_scope.endScope(); } - shared_capture_manager.stop_capture(); + shared_capture_manager.stopCapture(); } unsafe fn get_acceleration_structure_build_sizes( diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index a0d423769c6..5461153ff30 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -481,11 +481,11 @@ impl crate::Queue for Queue { Some(&cmd_buf) => cmd_buf.raw.clone(), None => { let queue = self.raw.lock(); - queue.command_buffer_with_unretained_references().unwrap() + queue.commandBufferWithUnretainedReferences().unwrap() } }; - raw.set_label(Some(ns_string!("(wgpu internal) Signal"))); - unsafe { raw.add_completed_handler(block2::RcBlock::as_ptr(&block)) }; + raw.setLabel(Some(ns_string!("(wgpu internal) Signal"))); + unsafe { raw.addCompletedHandler(block2::RcBlock::as_ptr(&block)) }; signal_fence.maintain(); signal_fence @@ -493,7 +493,7 @@ impl crate::Queue for Queue { .push((signal_value, raw.clone())); if let Some(shared_event) = &signal_fence.shared_event { - raw.encode_signal_event_value(shared_event.as_ref(), signal_value); + raw.encodeSignalEvent_value(shared_event.as_ref(), signal_value); } // only return an extra one if it's extra match command_buffers.last() { @@ -519,18 +519,18 @@ impl crate::Queue for Queue { ) -> Result<(), crate::SurfaceError> { let queue = &self.raw.lock(); autoreleasepool(|_| { - let command_buffer = queue.command_buffer().unwrap(); - command_buffer.set_label(Some(ns_string!("(wgpu internal) Present"))); + let command_buffer = queue.commandBuffer().unwrap(); + command_buffer.setLabel(Some(ns_string!("(wgpu internal) Present"))); // https://developer.apple.com/documentation/quartzcore/cametallayer/1478157-presentswithtransaction?language=objc if !texture.present_with_transaction { - command_buffer.present_drawable(&texture.drawable); + command_buffer.presentDrawable(&texture.drawable); } command_buffer.commit(); if texture.present_with_transaction { - command_buffer.wait_until_scheduled(); + command_buffer.waitUntilScheduled(); texture.drawable.present(); } }); diff --git a/wgpu-hal/src/metal/surface.rs b/wgpu-hal/src/metal/surface.rs index 6d155ecab04..831f50f6fdb 100644 --- a/wgpu-hal/src/metal/surface.rs +++ b/wgpu-hal/src/metal/surface.rs @@ -40,7 +40,7 @@ impl super::Surface { let (size, scale) = { let render_layer = self.render_layer.lock(); let bounds = render_layer.bounds(); - let contents_scale = render_layer.contents_scale(); + let contents_scale = render_layer.contentsScale(); (bounds.size, contents_scale) }; @@ -76,30 +76,30 @@ impl crate::Surface for super::Surface { let drawable_size = CGSize::new(config.extent.width as f64, config.extent.height as f64); match config.composite_alpha_mode { - wgt::CompositeAlphaMode::Opaque => render_layer.set_opaque(true), - wgt::CompositeAlphaMode::PostMultiplied => render_layer.set_opaque(false), + wgt::CompositeAlphaMode::Opaque => render_layer.setOpaque(true), + wgt::CompositeAlphaMode::PostMultiplied => render_layer.setOpaque(false), _ => (), } let device_raw = &device.shared.device; - render_layer.set_device(Some(device_raw)); - render_layer.set_pixel_format(caps.map_format(config.format)); - render_layer.set_framebuffer_only(framebuffer_only); + render_layer.setDevice(Some(device_raw)); + render_layer.setPixelFormat(caps.map_format(config.format)); + render_layer.setFramebufferOnly(framebuffer_only); // opt-in to Metal EDR // EDR potentially more power used in display and more bandwidth, memory footprint. let wants_edr = config.format == wgt::TextureFormat::Rgba16Float; - if wants_edr != render_layer.wants_extended_dynamic_range_content() { - render_layer.set_wants_extended_dynamic_range_content(wants_edr); + if wants_edr != render_layer.wantsExtendedDynamicRangeContent() { + render_layer.setWantsExtendedDynamicRangeContent(wants_edr); } // this gets ignored on iOS for certain OS/device combinations (iphone5s iOS 10.3) - render_layer.set_maximum_drawable_count(config.maximum_frame_latency as usize + 1); - render_layer.set_drawable_size(drawable_size); + render_layer.setMaximumDrawableCount(config.maximum_frame_latency as usize + 1); + render_layer.setDrawableSize(drawable_size); if caps.can_set_next_drawable_timeout { - render_layer.set_allows_next_drawable_timeout(false); + render_layer.setAllowsNextDrawableTimeout(false); } if caps.can_set_display_sync { - render_layer.set_display_sync_enabled(display_sync); + render_layer.setDisplaySyncEnabled(display_sync); } Ok(()) @@ -117,7 +117,7 @@ impl crate::Surface for super::Surface { let render_layer = self.render_layer.lock(); let (drawable, texture) = match autoreleasepool(|_| { render_layer - .next_drawable() + .nextDrawable() .map(|drawable| (drawable.to_owned(), drawable.texture().to_owned())) }) { Some(pair) => pair, @@ -140,7 +140,7 @@ impl crate::Surface for super::Surface { }, }, drawable: ProtocolObject::from_retained(drawable), - present_with_transaction: render_layer.presents_with_transaction(), + present_with_transaction: render_layer.presentsWithTransaction(), }; Ok(Some(crate::AcquiredSurfaceTexture {