Skip to content

Commit 81184f4

Browse files
authored
[metal] MTLDevice is thread-safe (#8168)
1 parent 8a663a5 commit 81184f4

File tree

5 files changed

+23
-31
lines changed

5 files changed

+23
-31
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ By @cwfitzgerald in [#8609](https://github.com/gfx-rs/wgpu/pull/8609).
210210

211211
- Add support for mesh shaders. By @SupaMaggie70Incorporated in [#8139](https://github.com/gfx-rs/wgpu/pull/8139)
212212
- Expose render layer. By @xiaopengli89 in [#8707](https://github.com/gfx-rs/wgpu/pull/8707)
213+
- `MTLDevice` is thread-safe. By @uael in [#8168](https://github.com/gfx-rs/wgpu/pull/8168)
213214

214215
#### Naga
215216

wgpu-hal/src/metal/adapter.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,10 @@ impl crate::Adapter for super::Adapter {
5050
let queue = self
5151
.shared
5252
.device
53-
.lock()
5453
.new_command_queue_with_max_command_buffer_count(MAX_COMMAND_BUFFERS);
5554

5655
// Acquiring the meaning of timestamp ticks is hard with Metal!
57-
// The only thing there is is a method correlating cpu & gpu timestamps (`device.sample_timestamps`).
56+
// The only thing there is a method correlating cpu & gpu timestamps (`device.sample_timestamps`).
5857
// Users are supposed to call this method twice and calculate the difference,
5958
// see "Converting GPU Timestamps into CPU Time":
6059
// https://developer.apple.com/documentation/metal/gpu_counters_and_counter_sample_buffers/converting_gpu_timestamps_into_cpu_time
@@ -72,7 +71,7 @@ impl crate::Adapter for super::Adapter {
7271
// Based on:
7372
// * https://github.com/gfx-rs/wgpu/pull/2528
7473
// * https://github.com/gpuweb/gpuweb/issues/1325#issuecomment-761041326
75-
let timestamp_period = if self.shared.device.lock().name().starts_with("Intel") {
74+
let timestamp_period = if self.shared.device.name().starts_with("Intel") {
7675
83.333
7776
} else {
7877
// Known for Apple Silicon (at least M1 & M2, iPad Pro 2018) and AMD GPUs.
@@ -121,7 +120,7 @@ impl crate::Adapter for super::Adapter {
121120
Tfc::empty()
122121
};
123122
let is_not_apple1x = super::PrivateCapabilities::supports_any(
124-
self.shared.device.lock().as_ref(),
123+
self.shared.device.as_ref(),
125124
&[
126125
MTLFeatureSet::iOS_GPUFamily2_v1,
127126
MTLFeatureSet::macOS_GPUFamily1_v1,

wgpu-hal/src/metal/device.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use alloc::{borrow::ToOwned as _, sync::Arc, vec::Vec};
22
use core::{ptr::NonNull, sync::atomic};
33
use std::{thread, time};
44

5-
use parking_lot::Mutex;
6-
75
use super::{conv, PassthroughShader};
86
use crate::auxil::map_naga_stage;
97
use crate::metal::ShaderModuleSource;
@@ -215,7 +213,6 @@ impl super::Device {
215213
let library = self
216214
.shared
217215
.device
218-
.lock()
219216
.new_library_with_source(source.as_ref(), &options)
220217
.map_err(|err| {
221218
log::debug!("Naga generated shader:\n{source}");
@@ -362,7 +359,7 @@ impl super::Device {
362359
super::Buffer { raw, size }
363360
}
364361

365-
pub fn raw_device(&self) -> &Mutex<metal::Device> {
362+
pub fn raw_device(&self) -> &metal::Device {
366363
&self.shared.device
367364
}
368365
}
@@ -386,7 +383,7 @@ impl crate::Device for super::Device {
386383
//TODO: HazardTrackingModeUntracked
387384

388385
objc::rc::autoreleasepool(|| {
389-
let raw = self.shared.device.lock().new_buffer(desc.size, options);
386+
let raw = self.shared.device.new_buffer(desc.size, options);
390387
if let Some(label) = desc.label {
391388
raw.set_label(label);
392389
}
@@ -468,7 +465,7 @@ impl crate::Device for super::Device {
468465
descriptor.set_usage(conv::map_texture_usage(desc.format, desc.usage));
469466
descriptor.set_storage_mode(mtl_storage_mode);
470467

471-
let raw = self.shared.device.lock().new_texture(&descriptor);
468+
let raw = self.shared.device.new_texture(&descriptor);
472469
if raw.as_ptr().is_null() {
473470
return Err(crate::DeviceError::OutOfMemory);
474471
}
@@ -620,7 +617,7 @@ impl crate::Device for super::Device {
620617
if self.features.contains(wgt::Features::TEXTURE_BINDING_ARRAY) {
621618
descriptor.set_support_argument_buffers(true);
622619
}
623-
let raw = self.shared.device.lock().new_sampler(&descriptor);
620+
let raw = self.shared.device.new_sampler(&descriptor);
624621

625622
self.counters.samplers.add(1);
626623

@@ -891,7 +888,7 @@ impl crate::Device for super::Device {
891888
let uses = conv::map_resource_usage(&layout.ty);
892889

893890
// Create argument buffer for this array
894-
let buffer = self.shared.device.lock().new_buffer(
891+
let buffer = self.shared.device.new_buffer(
895892
8 * count as u64,
896893
MTLResourceOptions::HazardTrackingModeUntracked
897894
| MTLResourceOptions::StorageModeShared,
@@ -1073,8 +1070,8 @@ impl crate::Device for super::Device {
10731070
num_workgroups,
10741071
} => {
10751072
let options = metal::CompileOptions::new();
1076-
// Obtain the locked device from shared
1077-
let device = self.shared.device.lock();
1073+
// Obtain the device from shared
1074+
let device = &self.shared.device;
10781075
let library = device
10791076
.new_library_with_source(source, &options)
10801077
.map_err(|e| crate::ShaderError::Compilation(format!("MSL: {e:?}")))?;
@@ -1459,11 +1456,7 @@ impl crate::Device for super::Device {
14591456
}
14601457

14611458
let ds_descriptor = create_depth_stencil_desc(ds);
1462-
let raw = self
1463-
.shared
1464-
.device
1465-
.lock()
1466-
.new_depth_stencil_state(&ds_descriptor);
1459+
let raw = self.shared.device.new_depth_stencil_state(&ds_descriptor);
14671460
Some((raw, ds.bias))
14681461
}
14691462
None => None,
@@ -1496,10 +1489,10 @@ impl crate::Device for super::Device {
14961489
// Create the pipeline from descriptor
14971490
let raw = match descriptor {
14981491
MetalGenericRenderPipelineDescriptor::Standard(d) => {
1499-
self.shared.device.lock().new_render_pipeline_state(&d)
1492+
self.shared.device.new_render_pipeline_state(&d)
15001493
}
15011494
MetalGenericRenderPipelineDescriptor::Mesh(d) => {
1502-
self.shared.device.lock().new_mesh_render_pipeline_state(&d)
1495+
self.shared.device.new_mesh_render_pipeline_state(&d)
15031496
}
15041497
}
15051498
.map_err(|e| {
@@ -1600,7 +1593,6 @@ impl crate::Device for super::Device {
16001593
let raw = self
16011594
.shared
16021595
.device
1603-
.lock()
16041596
.new_compute_pipeline_state(&descriptor)
16051597
.map_err(|e| {
16061598
crate::PipelineError::Linkage(
@@ -1637,7 +1629,7 @@ impl crate::Device for super::Device {
16371629
let size = desc.count as u64 * crate::QUERY_SIZE;
16381630
let options = MTLResourceOptions::empty();
16391631
//TODO: HazardTrackingModeUntracked
1640-
let raw_buffer = self.shared.device.lock().new_buffer(size, options);
1632+
let raw_buffer = self.shared.device.new_buffer(size, options);
16411633
if let Some(label) = desc.label {
16421634
raw_buffer.set_label(label);
16431635
}
@@ -1649,7 +1641,7 @@ impl crate::Device for super::Device {
16491641
}
16501642
wgt::QueryType::Timestamp => {
16511643
let size = desc.count as u64 * crate::QUERY_SIZE;
1652-
let device = self.shared.device.lock();
1644+
let device = &self.shared.device;
16531645
let destination_buffer = device.new_buffer(size, MTLResourceOptions::empty());
16541646

16551647
let csb_desc = metal::CounterSampleBufferDescriptor::new();
@@ -1701,7 +1693,7 @@ impl crate::Device for super::Device {
17011693
unsafe fn create_fence(&self) -> DeviceResult<super::Fence> {
17021694
self.counters.fences.add(1);
17031695
let shared_event = if self.shared.private_caps.supports_shared_event {
1704-
Some(self.shared.device.lock().new_shared_event())
1696+
Some(self.shared.device.new_shared_event())
17051697
} else {
17061698
None
17071699
};
@@ -1765,9 +1757,9 @@ impl crate::Device for super::Device {
17651757
if !self.shared.private_caps.supports_capture_manager {
17661758
return false;
17671759
}
1768-
let device = self.shared.device.lock();
1760+
let device = &self.shared.device;
17691761
let shared_capture_manager = metal::CaptureManager::shared();
1770-
let default_capture_scope = shared_capture_manager.new_capture_scope_with_device(&device);
1762+
let default_capture_scope = shared_capture_manager.new_capture_scope_with_device(device);
17711763
shared_capture_manager.set_default_capture_scope(&default_capture_scope);
17721764
shared_capture_manager.start_capture_with_scope(&default_capture_scope);
17731765
default_capture_scope.begin_scope();

wgpu-hal/src/metal/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl Default for Settings {
337337
}
338338

339339
struct AdapterShared {
340-
device: Mutex<metal::Device>,
340+
device: metal::Device,
341341
disabilities: PrivateDisabilities,
342342
private_caps: PrivateCapabilities,
343343
settings: Settings,
@@ -355,7 +355,7 @@ impl AdapterShared {
355355
Self {
356356
disabilities: PrivateDisabilities::new(&device),
357357
private_caps,
358-
device: Mutex::new(device),
358+
device,
359359
settings: Settings::default(),
360360
presentation_timer: time::PresentationTimer::new(),
361361
}

wgpu-hal/src/metal/surface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ impl crate::Surface for super::Surface {
163163
_ => (),
164164
}
165165

166-
let device_raw = device.shared.device.lock();
167-
render_layer.set_device(&device_raw);
166+
let device_raw = &device.shared.device;
167+
render_layer.set_device(device_raw);
168168
render_layer.set_pixel_format(caps.map_format(config.format));
169169
render_layer.set_framebuffer_only(framebuffer_only);
170170
// opt-in to Metal EDR

0 commit comments

Comments
 (0)