From 0f1e553c3680528f431037733d67df700cbf75cd Mon Sep 17 00:00:00 2001 From: Jinlei Li Date: Wed, 9 Mar 2022 14:33:08 +0800 Subject: [PATCH] metal: implement get_timestamp_period --- wgpu-hal/src/metal/adapter.rs | 2 ++ wgpu-hal/src/metal/mod.rs | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 82cd224236..20082b8daf 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -34,6 +34,7 @@ impl crate::Adapter for super::Adapter { }, queue: super::Queue { raw: Arc::new(Mutex::new(queue)), + shared: Arc::clone(&self.shared), }, }) } @@ -733,6 +734,7 @@ impl super::PrivateCapabilities { } else { None }, + supports_timestamp_period: version.at_least((10, 15), (14, 0)), } } diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 84c1e20929..4f756fe99a 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -228,6 +228,7 @@ struct PrivateCapabilities { supports_depth_clip_control: bool, supports_preserve_invariance: bool, has_unified_memory: Option, + supports_timestamp_period: bool, } #[derive(Clone, Debug)] @@ -274,6 +275,7 @@ pub struct Adapter { pub struct Queue { raw: Arc>, + shared: Arc, } unsafe impl Send for Queue {} @@ -388,8 +390,26 @@ impl crate::Queue for Queue { } unsafe fn get_timestamp_period(&self) -> f32 { - // TODO: This is hard, see https://github.com/gpuweb/gpuweb/issues/1325 - 1.0 + if !self.shared.private_caps.supports_timestamp_period { + return 1.0; + } + + use objc::{msg_send, sel, sel_impl}; + let (mut cpu_timestamp0, mut gpu_timestamp0) = (0_u64, 0_u64); + let device = self.shared.device.lock().as_ptr(); + let () = msg_send![device, sampleTimestamps:&mut cpu_timestamp0 gpuTimestamp:&mut gpu_timestamp0]; + if cpu_timestamp0 == 0 || gpu_timestamp0 == 0 { + return 1.0; + } + + let queue = &self.raw.lock(); + let command_buffer = queue.new_command_buffer(); + command_buffer.commit(); + command_buffer.wait_until_scheduled(); + let (mut cpu_timestamp1, mut gpu_timestamp1) = (0_u64, 0_u64); + let () = msg_send![device, sampleTimestamps:&mut cpu_timestamp1 gpuTimestamp:&mut gpu_timestamp1]; + + (cpu_timestamp1 - cpu_timestamp0) as f32 / (gpu_timestamp1 - gpu_timestamp0) as f32 } }