mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Merge #1592
1592: Detailed limits check and error r=cwfitzgerald a=kvark **Connections** Related to #1590 **Description** The old comparison "A < B" was simply wrong, because it would do every field in order and could bail out mid-way without reaching for all limits. **Testing** Untested Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
@@ -8,7 +8,7 @@ use crate::{
|
||||
track::{BufferState, TextureSelector, TextureState, TrackerSet, UsageConflict},
|
||||
validation::{self, check_buffer_usage, check_texture_usage},
|
||||
FastHashMap, Label, LabelHelpers as _, LifeGuard, MultiRefCount, Stored, SubmissionIndex,
|
||||
DOWNLEVEL_ERROR_WARNING_MESSAGE,
|
||||
DOWNLEVEL_ERROR_MESSAGE,
|
||||
};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
@@ -2426,7 +2426,7 @@ pub struct MissingFeatures(pub wgt::Features);
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error(
|
||||
"Downlevel flags {0:?} are required but not supported on the device.\n{}",
|
||||
DOWNLEVEL_ERROR_WARNING_MESSAGE
|
||||
DOWNLEVEL_ERROR_MESSAGE
|
||||
)]
|
||||
pub struct MissingDownlevelFlags(pub wgt::DownlevelFlags);
|
||||
|
||||
|
||||
@@ -14,6 +14,52 @@ pub type RequestAdapterOptions = wgt::RequestAdapterOptions<SurfaceId>;
|
||||
type HalInstance<A> = <A as hal::Api>::Instance;
|
||||
type HalSurface<A> = <A as hal::Api>::Surface;
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("Limit '{name}' value {requested} is better than allowed {allowed}")]
|
||||
pub struct FailedLimit {
|
||||
name: &'static str,
|
||||
requested: u32,
|
||||
allowed: u32,
|
||||
}
|
||||
|
||||
fn check_limits(requested: &wgt::Limits, allowed: &wgt::Limits) -> Vec<FailedLimit> {
|
||||
use std::cmp::Ordering;
|
||||
let mut failed = Vec::new();
|
||||
|
||||
macro_rules! compare {
|
||||
($name:ident, $ordering:ident) => {
|
||||
match requested.$name.cmp(&allowed.$name) {
|
||||
Ordering::$ordering | Ordering::Equal => (),
|
||||
_ => failed.push(FailedLimit {
|
||||
name: stringify!($name),
|
||||
requested: requested.$name,
|
||||
allowed: allowed.$name,
|
||||
}),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
compare!(max_texture_dimension_1d, Less);
|
||||
compare!(max_texture_dimension_2d, Less);
|
||||
compare!(max_texture_dimension_3d, Less);
|
||||
compare!(max_texture_array_layers, Less);
|
||||
compare!(max_bind_groups, Less);
|
||||
compare!(max_dynamic_uniform_buffers_per_pipeline_layout, Less);
|
||||
compare!(max_dynamic_storage_buffers_per_pipeline_layout, Less);
|
||||
compare!(max_sampled_textures_per_shader_stage, Less);
|
||||
compare!(max_samplers_per_shader_stage, Less);
|
||||
compare!(max_storage_buffers_per_shader_stage, Less);
|
||||
compare!(max_storage_textures_per_shader_stage, Less);
|
||||
compare!(max_uniform_buffers_per_shader_stage, Less);
|
||||
compare!(max_uniform_buffer_binding_size, Less);
|
||||
compare!(max_storage_buffer_binding_size, Less);
|
||||
compare!(max_vertex_buffers, Less);
|
||||
compare!(max_vertex_attributes, Less);
|
||||
compare!(max_vertex_buffer_array_stride, Less);
|
||||
compare!(max_push_constant_size, Less);
|
||||
failed
|
||||
}
|
||||
|
||||
pub struct Instance {
|
||||
#[allow(dead_code)]
|
||||
name: String,
|
||||
@@ -247,8 +293,8 @@ impl<A: HalApi> Adapter<A> {
|
||||
BIND_BUFFER_ALIGNMENT % caps.alignments.uniform_buffer_offset,
|
||||
"Adapter uniform buffer offset alignment not compatible with WGPU"
|
||||
);
|
||||
if caps.limits < desc.limits {
|
||||
return Err(RequestDeviceError::LimitsExceeded);
|
||||
if let Some(failed) = check_limits(&desc.limits, &caps.limits).pop() {
|
||||
return Err(RequestDeviceError::LimitsExceeded(failed));
|
||||
}
|
||||
|
||||
Device::new(
|
||||
@@ -295,8 +341,8 @@ pub enum RequestDeviceError {
|
||||
DeviceLost,
|
||||
#[error("device initialization failed due to implementation specific errors")]
|
||||
Internal,
|
||||
#[error("some of the requested device limits are not supported")]
|
||||
LimitsExceeded,
|
||||
#[error(transparent)]
|
||||
LimitsExceeded(#[from] FailedLimit),
|
||||
#[error("device has no queue supporting graphics")]
|
||||
NoGraphicsQueue,
|
||||
#[error("not enough memory left")]
|
||||
|
||||
@@ -81,15 +81,6 @@ impl RefCount {
|
||||
unsafe { self.0.as_ref() }.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
/// This works like `std::mem::drop`, except that it returns a boolean which is true if and only
|
||||
/// if we deallocated the underlying memory, i.e. if this was the last clone of this `RefCount`
|
||||
/// to be dropped. This is useful for loom testing because it allows us to verify that we
|
||||
/// deallocated the underlying memory exactly once.
|
||||
#[cfg(test)]
|
||||
fn rich_drop_outer(self) -> bool {
|
||||
unsafe { std::mem::ManuallyDrop::new(self).rich_drop_inner() }
|
||||
}
|
||||
|
||||
/// This function exists to allow `Self::rich_drop_outer` and `Drop::drop` to share the same
|
||||
/// logic. To use this safely from outside of `Drop::drop`, the calling function must move
|
||||
/// `Self` into a `ManuallyDrop`.
|
||||
@@ -191,7 +182,7 @@ support enough features to be a fully compliant implementation of WebGPU. A subs
|
||||
If you are running this program on native and not in a browser and wish to limit the features you use to the supported subset, \
|
||||
call Adapter::downlevel_properties or Device::downlevel_properties to get a listing of the features the current \
|
||||
platform supports.";
|
||||
const DOWNLEVEL_ERROR_WARNING_MESSAGE: &str = "This is not an invalid use of WebGPU: the underlying API or device does not \
|
||||
const DOWNLEVEL_ERROR_MESSAGE: &str = "This is not an invalid use of WebGPU: the underlying API or device does not \
|
||||
support enough features to be a fully compliant implementation. A subset of the features can still be used. \
|
||||
If you are running this program on native and not in a browser and wish to work around this issue, call \
|
||||
Adapter::downlevel_properties or Device::downlevel_properties to get a listing of the features the current \
|
||||
|
||||
Reference in New Issue
Block a user