Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions wgpu-hal/src/metal/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,14 @@ impl crate::Device for super::Device {
&& self.shared.private_caps.supports_memoryless_storage
{
MTLStorageMode::Memoryless
} else if cfg!(target_pointer_width = "32") {
// On arm64_32 (watchOS ILP32), the AGXMetalS4 driver (A13/S6 GPU)
// crashes in copyFromTexture:toBuffer: on Private textures — null
// deref at offset 0x50 in the driver's internal texture state. Use
// Shared storage which works correctly on Apple's unified memory
// architecture and matches what native Swift Metal code uses on
// these devices.
MTLStorageMode::Shared
Comment on lines +525 to +531
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting bug, is it documented anywhere?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I'm aware of. There's a couple of reasons this amazing capability of these Apple Watch devices are shrouded:

  • the feature/capability flags will say a feature isn't available, but the MSL will actually just work. before I ported wgpu, I tested Metal exhaustively to figure out what actually works. This was kicked off by seeing the Memoji app on my child's Apple Watch 9 and realizing the functionality it implied.
  • if you try to do some of these MSL features in the simulator, you'll get a hard abort or it just won't work. I'm guessing most people (very reasonably) give up.
  • some features, like ASTC HDR textures, work intermittently (shows magenta sometimes) on Apple Watch 6/SE2, but works fine on Apple Watch 9 and later. I haven't pinned down why, but again I'm assuming this would ward off most mildly curious app/3D developers.

This is probably a good conference/meetup talk to commoditize this hard-won knowledge, happy to apply if anyone has suggestions on a good venue!

} else {
MTLStorageMode::Private
};
Expand Down Expand Up @@ -1272,8 +1280,11 @@ impl crate::Device for super::Device {
}

// https://developer.apple.com/documentation/metal/mtlpipelinebufferdescriptor/mutability
let supports_mutability =
available!(macos = 10.13, ios = 11.0, tvos = 11.0, visionos = 1.0);
// Disabled on arm64_32 (watchOS ILP32): the AGXMetalS4 driver exhibits
// instability when mutability hints are combined with Shared storage
// mode textures. Conservative disable until broader device coverage.
let supports_mutability = !cfg!(target_pointer_width = "32")
&& available!(macos = 10.13, ios = 11.0, tvos = 11.0, visionos = 1.0);

let (primitive_class, raw_primitive_type) =
conv::map_primitive_topology(desc.primitive.topology);
Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/metal/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ impl crate::Surface for super::Surface {
wgt::PresentMode::Immediate => false,
m => unreachable!("Unsupported present mode: {m:?}"),
};
let drawable_size = CGSize::new(config.extent.width as f64, config.extent.height as f64);
// CGFloat is f64 on 64-bit, f32 on 32-bit (arm64_32/ILP32)
let drawable_size = CGSize::new(config.extent.width as _, config.extent.height as _);

match config.composite_alpha_mode {
wgt::CompositeAlphaMode::Opaque => render_layer.setOpaque(true),
Expand Down