Remove UnsafeFeatures as we decided the top level guard is not useful

This commit is contained in:
Dzmitry Malyshau 2020-07-06 23:46:46 -04:00
parent 8a51f4bc7f
commit 46230720b5
3 changed files with 5 additions and 58 deletions

View File

@ -491,7 +491,6 @@ fn main() {
#[cfg(not(feature = "winit"))] #[cfg(not(feature = "winit"))]
compatible_surface: None, compatible_surface: None,
}, },
unsafe { wgt::UnsafeFeatures::allow() },
wgc::instance::AdapterInputs::IdSet( wgc::instance::AdapterInputs::IdSet(
&[wgc::id::TypedId::zip(0, 0, backend)], &[wgc::id::TypedId::zip(0, 0, backend)],
|id| id.backend(), |id| id.backend(),

View File

@ -125,12 +125,11 @@ pub struct Adapter<B: hal::Backend> {
pub(crate) raw: hal::adapter::Adapter<B>, pub(crate) raw: hal::adapter::Adapter<B>,
features: wgt::Features, features: wgt::Features,
limits: wgt::Limits, limits: wgt::Limits,
unsafe_features: wgt::UnsafeFeatures,
life_guard: LifeGuard, life_guard: LifeGuard,
} }
impl<B: hal::Backend> Adapter<B> { impl<B: hal::Backend> Adapter<B> {
fn new(raw: hal::adapter::Adapter<B>, unsafe_features: wgt::UnsafeFeatures) -> Self { fn new(raw: hal::adapter::Adapter<B>) -> Self {
span!(_guard, INFO, "Adapter::new"); span!(_guard, INFO, "Adapter::new");
let adapter_features = raw.physical_device.features(); let adapter_features = raw.physical_device.features();
@ -160,9 +159,6 @@ impl<B: hal::Backend> Adapter<B> {
wgt::Features::MULTI_DRAW_INDIRECT_COUNT, wgt::Features::MULTI_DRAW_INDIRECT_COUNT,
adapter_features.contains(hal::Features::DRAW_INDIRECT_COUNT), adapter_features.contains(hal::Features::DRAW_INDIRECT_COUNT),
); );
if unsafe_features.allowed() {
// Unsafe features go here
}
let adapter_limits = raw.physical_device.limits(); let adapter_limits = raw.physical_device.limits();
@ -176,7 +172,6 @@ impl<B: hal::Backend> Adapter<B> {
raw, raw,
features, features,
limits, limits,
unsafe_features,
life_guard: LifeGuard::new(), life_guard: LifeGuard::new(),
} }
} }
@ -325,11 +320,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
self.surfaces.register_identity(id_in, surface, &mut token) self.surfaces.register_identity(id_in, surface, &mut token)
} }
pub fn enumerate_adapters( pub fn enumerate_adapters(&self, inputs: AdapterInputs<Input<G, AdapterId>>) -> Vec<AdapterId> {
&self,
unsafe_features: wgt::UnsafeFeatures,
inputs: AdapterInputs<Input<G, AdapterId>>,
) -> Vec<AdapterId> {
span!(_guard, INFO, "Instance::enumerate_adapters"); span!(_guard, INFO, "Instance::enumerate_adapters");
let instance = &self.instance; let instance = &self.instance;
@ -341,7 +332,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
if let Some(inst) = instance_field { if let Some(inst) = instance_field {
if let Some(id_backend) = inputs.find(backend) { if let Some(id_backend) = inputs.find(backend) {
for raw in inst.enumerate_adapters() { for raw in inst.enumerate_adapters() {
let adapter = Adapter::new(raw, unsafe_features); let adapter = Adapter::new(raw);
log::info!("Adapter {} {:?}", backend_info, adapter.raw.info); log::info!("Adapter {} {:?}", backend_info, adapter.raw.info);
adapters.push(backend_hub(self).adapters.register_identity( adapters.push(backend_hub(self).adapters.register_identity(
id_backend.clone(), id_backend.clone(),
@ -369,7 +360,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn pick_adapter( pub fn pick_adapter(
&self, &self,
desc: &RequestAdapterOptions, desc: &RequestAdapterOptions,
unsafe_features: wgt::UnsafeFeatures,
inputs: AdapterInputs<Input<G, AdapterId>>, inputs: AdapterInputs<Input<G, AdapterId>>,
) -> Option<AdapterId> { ) -> Option<AdapterId> {
span!(_guard, INFO, "Instance::pick_adapter"); span!(_guard, INFO, "Instance::pick_adapter");
@ -482,7 +472,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
backends_map! { backends_map! {
let map = |(info_adapter, id_backend, mut adapters_backend, backend_hub)| { let map = |(info_adapter, id_backend, mut adapters_backend, backend_hub)| {
if selected < adapters_backend.len() { if selected < adapters_backend.len() {
let adapter = Adapter::new(adapters_backend.swap_remove(selected), unsafe_features); let adapter = Adapter::new(adapters_backend.swap_remove(selected));
log::info!("Adapter {} {:?}", info_adapter, adapter.raw.info); log::info!("Adapter {} {:?}", info_adapter, adapter.raw.info);
let id = backend_hub(self).adapters.register_identity( let id = backend_hub(self).adapters.register_identity(
id_backend.take().unwrap(), id_backend.take().unwrap(),
@ -585,14 +575,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let adapter = &adapter_guard[adapter_id]; let adapter = &adapter_guard[adapter_id];
let phd = &adapter.raw.physical_device; let phd = &adapter.raw.physical_device;
// Verify all features were exposed by the adapter // Verify all features were exposed by the adapter
if !adapter.unsafe_features.allowed() {
assert!(
!desc.features.intersects(wgt::Features::ALL_UNSAFE),
"Cannot enable unsafe features without passing UnsafeFeatures::allow() when getting an adapter. Enabled unsafe extensions: {:?}",
desc.features & wgt::Features::ALL_UNSAFE
)
}
if !adapter.features.contains(desc.features) { if !adapter.features.contains(desc.features) {
return Err(RequestDeviceError::UnsupportedFeature( return Err(RequestDeviceError::UnsupportedFeature(
desc.features - adapter.features, desc.features - adapter.features,

View File

@ -234,46 +234,11 @@ bitflags::bitflags! {
const MULTI_DRAW_INDIRECT_COUNT = 0x0000_0000_0040_0000; const MULTI_DRAW_INDIRECT_COUNT = 0x0000_0000_0040_0000;
/// Features which are part of the upstream webgpu standard /// Features which are part of the upstream webgpu standard
const ALL_WEBGPU = 0x0000_0000_0000_FFFF; const ALL_WEBGPU = 0x0000_0000_0000_FFFF;
/// Features that require activating the unsafe feature flag
const ALL_UNSAFE = 0xFFFF_0000_0000_0000;
/// Features that are only available when targeting native (not web) /// Features that are only available when targeting native (not web)
const ALL_NATIVE = 0xFFFF_FFFF_FFFF_0000; const ALL_NATIVE = 0xFFFF_FFFF_FFFF_0000;
} }
} }
/// Marker type signalling if unsafe features are allowed to be enabled.
///
/// This doesn't enable any unsafe features, but must be set to `allow` if
/// an unsafe features is enabled.
///
/// The safety contract of safe Rust is that it is impossible to cause Undefined Behavior (UB)
/// from safe Rust. If a feature would allow UB to happen, it must preset an unsafe interface.
/// Enabling unsafe features is therefore an inherently unsafe operation.
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct UnsafeFeatures {
allow_unsafe: bool,
}
impl UnsafeFeatures {
/// Allow unsafe features to be enabled. This is an unsafe function and by calling this
/// function, you assert that even with these features on, it is impossible to cause UB
/// from within safe Rust.
pub unsafe fn allow() -> Self {
Self { allow_unsafe: true }
}
/// Disallow unsafe features.
pub fn disallow() -> Self {
Self {
allow_unsafe: false,
}
}
/// Does this marker allow unsafe features.
pub fn allowed(self) -> bool {
self.allow_unsafe
}
}
/// Represents the sets of limits an adapter/device supports. /// Represents the sets of limits an adapter/device supports.
/// ///
/// Limits "better" than the default must be supported by the adapter and requested when requesting /// Limits "better" than the default must be supported by the adapter and requested when requesting