479: Split framework limit situation into requested/required r=kvark a=cwfitzgerald

Requiring individual examples be responsible for panicing if their features aren't supported is a bit bug-prone, so this encodes requirements in the framework and enforces it in the framework.

Additionally made the verbs consistent.

Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
This commit is contained in:
bors[bot]
2020-07-24 21:39:46 +00:00
committed by GitHub
4 changed files with 23 additions and 17 deletions

View File

@@ -30,10 +30,13 @@ pub enum ShaderStage {
}
pub trait Example: 'static + Sized {
fn needed_features() -> wgpu::Features {
fn optional_features() -> wgpu::Features {
wgpu::Features::empty()
}
fn needed_limits() -> wgpu::Limits {
fn required_features() -> wgpu::Features {
wgpu::Features::empty()
}
fn required_limits() -> wgpu::Limits {
wgpu::Limits::default()
}
fn init(
@@ -94,8 +97,6 @@ async fn setup<E: Example>(title: &str) -> Setup {
(size, surface)
};
let needed_features = E::needed_features();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
@@ -104,15 +105,22 @@ async fn setup<E: Example>(title: &str) -> Setup {
.await
.unwrap();
let optional_features = E::optional_features();
let required_features = E::required_features();
let adapter_features = adapter.features();
assert!(
adapter_features.contains(required_features),
"Adapter does not support required features for this example: {:?}",
required_features - adapter_features
);
let needed_limits = E::needed_limits();
let needed_limits = E::required_limits();
let trace_dir = std::env::var("WGPU_TRACE");
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
features: adapter_features & needed_features,
features: (optional_features & adapter_features) | required_features,
limits: needed_limits,
shader_validation: true,
},

View File

@@ -203,7 +203,7 @@ impl Example {
}
impl framework::Example for Example {
fn needed_features() -> wgpu::Features {
fn optional_features() -> wgpu::Features {
wgpu::Features::DEPTH_CLAMPING
}

View File

@@ -80,14 +80,16 @@ struct Example {
}
impl framework::Example for Example {
fn needed_features() -> wgpu::Features {
fn optional_features() -> wgpu::Features {
wgpu::Features::UNSIZED_BINDING_ARRAY
| wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| wgpu::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING
| wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY
| wgpu::Features::PUSH_CONSTANTS
}
fn needed_limits() -> wgpu::Limits {
fn required_features() -> wgpu::Features {
wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY
}
fn required_limits() -> wgpu::Limits {
wgpu::Limits {
max_push_constant_size: 4,
..wgpu::Limits::default()
@@ -114,11 +116,7 @@ impl framework::Example for Example {
f if f.contains(wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY) => {
include_bytes!("constant.frag.spv").to_vec()
}
_ => {
panic!(
"Graphics adapter does not support any of the features needed for this example"
);
}
_ => unreachable!(),
};
let fs_module = device.create_shader_module(wgpu::util::make_spirv(&fs_bytes));

View File

@@ -35,8 +35,8 @@ pub fn make_spirv<'a>(data: &'a [u8]) -> super::ShaderModuleSource<'a> {
// otherwise copy the byte array in an owned vector and use that instead.
let words = if data.as_ptr().align_offset(align_of::<u32>()) == 0 {
let (pre, words, post) = unsafe { data.align_to::<u32>() };
debug_assert_eq!(pre, &[]);
debug_assert_eq!(post, &[]);
debug_assert!(pre.is_empty());
debug_assert!(post.is_empty());
Cow::from(words)
} else {
let mut words = vec![0u32; data.len() / size_of::<u32>()];