From 02cc0b9afa8eb6162b9e65d1801633cb6f38154e Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 27 Dec 2024 13:29:03 -0800 Subject: [PATCH] Update Blade with acquire fixes, multisampling (#22409) Fixes #22406 Picks up: - https://github.com/kvark/blade/pull/234 and https://github.com/kvark/blade/pull/237 (`OutOfDate` workaround) - https://github.com/kvark/blade/pull/229 ("metal-rs" to "objc2" migration) Release Notes: - Improved handling of resizing and multiple monitors in Linux/Windows --- Cargo.lock | 241 +++++++++++++++++- Cargo.toml | 13 +- crates/gpui/Cargo.toml | 7 +- crates/gpui/src/platform/blade/blade_atlas.rs | 1 + .../gpui/src/platform/blade/blade_renderer.rs | 109 ++++---- 5 files changed, 305 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fec983b26..9a06b71f70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1805,16 +1805,14 @@ dependencies = [ [[package]] name = "blade-graphics" -version = "0.5.0" -source = "git+https://github.com/kvark/blade?rev=099555282605c7c4cca9e66a8f40148298347f80#099555282605c7c4cca9e66a8f40148298347f80" +version = "0.6.0" +source = "git+https://github.com/kvark/blade?rev=091a8401033847bb9b6ace3fcf70448d069621c5#091a8401033847bb9b6ace3fcf70448d069621c5" dependencies = [ "ash", "ash-window", "bitflags 2.6.0", - "block", "bytemuck", "codespan-reporting", - "core-graphics-types 0.1.3", "glow", "gpu-alloc", "gpu-alloc-ash", @@ -1823,10 +1821,14 @@ dependencies = [ "khronos-egl", "libloading", "log", - "metal", "mint", "naga", - "objc", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-metal", + "objc2-quartz-core", + "objc2-ui-kit", "raw-window-handle", "slab", "wasm-bindgen", @@ -1836,7 +1838,7 @@ dependencies = [ [[package]] name = "blade-macros" version = "0.3.0" -source = "git+https://github.com/kvark/blade?rev=099555282605c7c4cca9e66a8f40148298347f80#099555282605c7c4cca9e66a8f40148298347f80" +source = "git+https://github.com/kvark/blade?rev=091a8401033847bb9b6ace3fcf70448d069621c5#091a8401033847bb9b6ace3fcf70448d069621c5" dependencies = [ "proc-macro2", "quote", @@ -1845,8 +1847,8 @@ dependencies = [ [[package]] name = "blade-util" -version = "0.1.0" -source = "git+https://github.com/kvark/blade?rev=099555282605c7c4cca9e66a8f40148298347f80#099555282605c7c4cca9e66a8f40148298347f80" +version = "0.2.0" +source = "git+https://github.com/kvark/blade?rev=091a8401033847bb9b6ace3fcf70448d069621c5#091a8401033847bb9b6ace3fcf70448d069621c5" dependencies = [ "blade-graphics", "bytemuck", @@ -1891,6 +1893,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + [[package]] name = "blocking" version = "1.6.1" @@ -5342,6 +5353,8 @@ dependencies = [ "metal", "num_cpus", "objc", + "objc2", + "objc2-metal", "oo7", "open", "parking", @@ -7578,7 +7591,8 @@ dependencies = [ [[package]] name = "metal" version = "0.30.0" -source = "git+https://github.com/gfx-rs/metal-rs?rev=ef768ff9d742ae6a0f4e83ddc8031264e7d460c4#ef768ff9d742ae6a0f4e83ddc8031264e7d460c4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3572083504c43e14aec05447f8a3d57cce0f66d7a3c1b9058572eca4d70ab9" dependencies = [ "bitflags 2.6.0", "block", @@ -7718,8 +7732,9 @@ checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "naga" -version = "23.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=1a643291c2e8854ba7e4f5445a4388202731bfa1#1a643291c2e8854ba7e4f5445a4388202731bfa1" +version = "23.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f" dependencies = [ "arrayvec", "bit-set 0.8.0", @@ -8149,6 +8164,208 @@ dependencies = [ "malloc_buf", ] +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + [[package]] name = "object" version = "0.36.5" diff --git a/Cargo.toml b/Cargo.toml index 779ebb1b35..a672387b11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -355,9 +355,9 @@ async-watch = "0.3.1" async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] } base64 = "0.22" bitflags = "2.6.0" -blade-graphics = { git = "https://github.com/kvark/blade", rev = "099555282605c7c4cca9e66a8f40148298347f80" } -blade-macros = { git = "https://github.com/kvark/blade", rev = "099555282605c7c4cca9e66a8f40148298347f80" } -blade-util = { git = "https://github.com/kvark/blade", rev = "099555282605c7c4cca9e66a8f40148298347f80" } +blade-graphics = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" } +blade-macros = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" } +blade-util = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" } blake3 = "1.5.3" bytes = "1.0" cargo_metadata = "0.19" @@ -524,12 +524,7 @@ wasmtime-wasi = "24" which = "6.0.0" wit-component = "0.201" zstd = "0.11" -# Custom metal-rs is only needed for "macos-blade" feature of GPUI -#TODO: switch to crates once these are published: -# - https://github.com/gfx-rs/metal-rs/pull/335 -# - https://github.com/gfx-rs/metal-rs/pull/336 -# - https://github.com/gfx-rs/metal-rs/pull/337 -metal = { git = "https://github.com/gfx-rs/metal-rs", rev = "ef768ff9d742ae6a0f4e83ddc8031264e7d460c4" } +metal = "0.30" [workspace.dependencies.async-stripe] git = "https://github.com/zed-industries/async-stripe" diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index aed1c25168..63aac122a8 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -22,7 +22,7 @@ test-support = [ "x11", ] runtime_shaders = [] -macos-blade = ["blade-graphics", "blade-macros", "blade-util", "bytemuck"] +macos-blade = ["blade-graphics", "blade-macros", "blade-util", "bytemuck", "objc2", "objc2-metal"] wayland = [ "blade-graphics", "blade-macros", @@ -132,11 +132,14 @@ core-foundation.workspace = true core-foundation-sys = "0.8" core-graphics = "0.23" core-text = "20.1" -font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "40391b7", optional = true} +font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "40391b7", optional = true } foreign-types = "0.5" log.workspace = true media.workspace = true objc = "0.2" +objc2 = { version = "0.5", optional = true } +objc2-metal = { version = "0.2", optional = true } +#TODO: replace with "objc2" metal.workspace = true [target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))'.dependencies] diff --git a/crates/gpui/src/platform/blade/blade_atlas.rs b/crates/gpui/src/platform/blade/blade_atlas.rs index 9e666d71bf..fb703f2a41 100644 --- a/crates/gpui/src/platform/blade/blade_atlas.rs +++ b/crates/gpui/src/platform/blade/blade_atlas.rs @@ -214,6 +214,7 @@ impl BladeAtlasState { }, array_layer_count: 1, mip_level_count: 1, + sample_count: 1, dimension: gpu::TextureDimension::D2, usage, }); diff --git a/crates/gpui/src/platform/blade/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs index 55a53e8e9f..ee8ffdfda7 100644 --- a/crates/gpui/src/platform/blade/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -174,8 +174,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_quad"), + fragment: Some(shader.at("fs_quad")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), shadows: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "shadows", @@ -187,8 +188,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_shadow"), + fragment: Some(shader.at("fs_shadow")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), path_rasterization: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "path_rasterization", @@ -200,12 +202,13 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_path_rasterization"), + fragment: Some(shader.at("fs_path_rasterization")), color_targets: &[gpu::ColorTargetState { format: PATH_TEXTURE_FORMAT, blend: Some(gpu::BlendState::ADDITIVE), write_mask: gpu::ColorWrites::default(), }], + multisample_state: gpu::MultisampleState::default(), }), paths: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "paths", @@ -217,8 +220,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_path"), + fragment: Some(shader.at("fs_path")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), underlines: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "underlines", @@ -230,8 +234,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_underline"), + fragment: Some(shader.at("fs_underline")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), mono_sprites: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "mono-sprites", @@ -243,8 +248,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_mono_sprite"), + fragment: Some(shader.at("fs_mono_sprite")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), poly_sprites: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "poly-sprites", @@ -256,8 +262,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_poly_sprite"), + fragment: Some(shader.at("fs_poly_sprite")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), surfaces: gpu.create_render_pipeline(gpu::RenderPipelineDesc { name: "surfaces", @@ -269,8 +276,9 @@ impl BladePipelines { ..Default::default() }, depth_stencil: None, - fragment: shader.at("fs_surface"), + fragment: Some(shader.at("fs_surface")), color_targets, + multisample_state: gpu::MultisampleState::default(), }), } } @@ -350,8 +358,10 @@ impl BladeRenderer { #[cfg(target_os = "macos")] let core_video_texture_cache = unsafe { - use foreign_types::ForeignType as _; - CVMetalTextureCache::new(context.gpu.metal_device().as_ptr()).unwrap() + CVMetalTextureCache::new( + objc2::rc::Retained::as_ptr(&context.gpu.metal_device()) as *mut _ + ) + .unwrap() }; Ok(Self { @@ -440,13 +450,12 @@ impl BladeRenderer { #[cfg(target_os = "macos")] pub fn layer(&self) -> metal::MetalLayer { - self.surface.metal_layer() + unsafe { foreign_types::ForeignType::from_ptr(self.layer_ptr()) } } #[cfg(target_os = "macos")] pub fn layer_ptr(&self) -> *mut metal::CAMetalLayer { - use metal::foreign_types::ForeignType as _; - self.surface.metal_layer().as_ptr() + objc2::rc::Retained::as_ptr(&self.surface.metal_layer()) as *mut _ } #[profiling::function] @@ -678,45 +687,59 @@ impl BladeRenderer { #[cfg(target_os = "macos")] { - let (t_y, t_cb_cr) = { + let (t_y, t_cb_cr) = unsafe { use core_foundation::base::TCFType as _; use std::ptr; assert_eq!( - surface.image_buffer.pixel_format_type(), - media::core_video::kCVPixelFormatType_420YpCbCr8BiPlanarFullRange - ); + surface.image_buffer.pixel_format_type(), + media::core_video::kCVPixelFormatType_420YpCbCr8BiPlanarFullRange + ); - let y_texture = unsafe { - self.core_video_texture_cache - .create_texture_from_image( - surface.image_buffer.as_concrete_TypeRef(), - ptr::null(), - metal::MTLPixelFormat::R8Unorm, - surface.image_buffer.plane_width(0), - surface.image_buffer.plane_height(0), - 0, - ) - .unwrap() - }; - let cb_cr_texture = unsafe { - self.core_video_texture_cache - .create_texture_from_image( - surface.image_buffer.as_concrete_TypeRef(), - ptr::null(), - metal::MTLPixelFormat::RG8Unorm, - surface.image_buffer.plane_width(1), - surface.image_buffer.plane_height(1), - 1, - ) - .unwrap() - }; + let y_texture = self + .core_video_texture_cache + .create_texture_from_image( + surface.image_buffer.as_concrete_TypeRef(), + ptr::null(), + metal::MTLPixelFormat::R8Unorm, + surface.image_buffer.plane_width(0), + surface.image_buffer.plane_height(0), + 0, + ) + .unwrap(); + let cb_cr_texture = self + .core_video_texture_cache + .create_texture_from_image( + surface.image_buffer.as_concrete_TypeRef(), + ptr::null(), + metal::MTLPixelFormat::RG8Unorm, + surface.image_buffer.plane_width(1), + surface.image_buffer.plane_height(1), + 1, + ) + .unwrap(); ( gpu::TextureView::from_metal_texture( - y_texture.as_texture_ref(), + &objc2::rc::Retained::retain( + foreign_types::ForeignTypeRef::as_ptr( + y_texture.as_texture_ref(), + ) + as *mut objc2::runtime::ProtocolObject< + dyn objc2_metal::MTLTexture, + >, + ) + .unwrap(), ), gpu::TextureView::from_metal_texture( - cb_cr_texture.as_texture_ref(), + &objc2::rc::Retained::retain( + foreign_types::ForeignTypeRef::as_ptr( + cb_cr_texture.as_texture_ref(), + ) + as *mut objc2::runtime::ProtocolObject< + dyn objc2_metal::MTLTexture, + >, + ) + .unwrap(), ), ) };