Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metal encoder & pass timestamp support #4008

Merged
merged 13 commits into from
Sep 16, 2023
Prev Previous commit
Next Next commit
more finegrained private cap for metal timestamp queries
  • Loading branch information
Wumpf committed Sep 16, 2023
commit 2b8e2aa611ebe2f259dd35fd979d01bbed1a29f5
39 changes: 30 additions & 9 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use wgt::{AstcBlock, AstcChannel};

use std::{sync::Arc, thread};

use super::TimestampQuerySupport;

const MAX_COMMAND_BUFFERS: u64 = 2048;

unsafe impl Send for super::Adapter {}
Expand Down Expand Up @@ -536,6 +538,26 @@ impl super::PrivateCapabilities {
MTLReadWriteTextureTier::TierNone
};

let mut timestamp_query_support = TimestampQuerySupport::empty();
if version.at_least((11, 0), (14, 0), os_is_mac)
&& device.supports_counter_sampling(metal::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(metal::MTLCounterSamplingPoint::AtDrawBoundary) {
timestamp_query_support.insert(TimestampQuerySupport::ON_RENDER_ENCODER);
}
if device.supports_counter_sampling(metal::MTLCounterSamplingPoint::AtDispatchBoundary)
{
timestamp_query_support.insert(TimestampQuerySupport::ON_COMPUTE_ENCODER);
}
if device.supports_counter_sampling(metal::MTLCounterSamplingPoint::AtBlitBoundary) {
timestamp_query_support.insert(TimestampQuerySupport::ON_BLIT_ENCODER);
}
// `TimestampQuerySupport::INSIDE_WGPU_PASSES` emerges from the other flags.
}

Self {
family_check,
msl_version: if os_is_xr || version.at_least((12, 0), (15, 0), os_is_mac) {
Expand Down Expand Up @@ -773,13 +795,7 @@ impl super::PrivateCapabilities {
} else {
None
},
support_timestamp_query: version.at_least((11, 0), (14, 0), os_is_mac)
&& device
.supports_counter_sampling(metal::MTLCounterSamplingPoint::AtStageBoundary),
support_timestamp_query_in_passes: version.at_least((11, 0), (14, 0), os_is_mac)
&& device.supports_counter_sampling(metal::MTLCounterSamplingPoint::AtDrawBoundary)
&& device
.supports_counter_sampling(metal::MTLCounterSamplingPoint::AtDispatchBoundary),
timestamp_query_support,
}
}

Expand Down Expand Up @@ -807,11 +823,16 @@ impl super::PrivateCapabilities {
| F::DEPTH32FLOAT_STENCIL8
| F::MULTI_DRAW_INDIRECT;

features.set(F::TIMESTAMP_QUERY, self.support_timestamp_query);
features.set(
F::TIMESTAMP_QUERY,
self.timestamp_query_support
.contains(TimestampQuerySupport::STAGE_BOUNDARIES),
);
// TODO: Not yet implemented.
// features.set(
// F::TIMESTAMP_QUERY_INSIDE_PASSES,
// self.support_timestamp_query_in_passes,
// self.timestamp_query_support
// .contains(TimestampQuerySupport::INSIDE_WGPU_PASSES),
// );
features.set(F::TEXTURE_COMPRESSION_ASTC, self.format_astc);
features.set(F::TEXTURE_COMPRESSION_ASTC_HDR, self.format_astc_hdr);
Expand Down
22 changes: 20 additions & 2 deletions wgpu-hal/src/metal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use std::{
};

use arrayvec::ArrayVec;
use bitflags::bitflags;
use metal::foreign_types::ForeignTypeRef as _;
use parking_lot::Mutex;

Expand Down Expand Up @@ -143,6 +144,24 @@ impl crate::Instance<Api> for Instance {
}
}

bitflags!(
/// Similar to `MTLCounterSamplingPoint`, but a bit higher abstracted for our purposes.
#[derive(Debug, Copy, Clone)]
pub struct TimestampQuerySupport: u32 {
/// On creating Metal encoders.
const STAGE_BOUNDARIES = 1 << 1;
/// Within existing draw encoders.
const ON_RENDER_ENCODER = Self::STAGE_BOUNDARIES.bits() | (1 << 2);
/// Within existing dispatch encoders.
const ON_COMPUTE_ENCODER = Self::STAGE_BOUNDARIES.bits() | (1 << 3);
/// Within existing blit encoders.
const ON_BLIT_ENCODER = Self::STAGE_BOUNDARIES.bits() | (1 << 4);

/// Within any wgpu render/compute pass.
const INSIDE_WGPU_PASSES = Self::ON_RENDER_ENCODER.bits() | Self::ON_COMPUTE_ENCODER.bits();
}
);

#[allow(dead_code)]
#[derive(Clone, Debug)]
struct PrivateCapabilities {
Expand Down Expand Up @@ -239,8 +258,7 @@ struct PrivateCapabilities {
supports_preserve_invariance: bool,
supports_shader_primitive_index: bool,
has_unified_memory: Option<bool>,
support_timestamp_query: bool,
support_timestamp_query_in_passes: bool,
timestamp_query_support: TimestampQuerySupport,
}

#[derive(Clone, Debug)]
Expand Down