Skip to content

Commit

Permalink
Fix device limits diverging from base limits by default (#379)
Browse files Browse the repository at this point in the history
* Fix device limits diverging from base limits by default

* Base resolution limits sourced from adapter, but no larger than spec

* tests

* ignore texture dims for selecting limits tier

---------

Co-authored-by: rajveermalviya <[email protected]>
  • Loading branch information
radgeRayden and rajveermalviya authored Apr 11, 2024
1 parent 1ac3a5c commit 6e46ddf
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 25 deletions.
5 changes: 1 addition & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -794,10 +794,7 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice(
return;
}
};
let base_limits = get_base_device_limits_from_adapter_limits(&adapter_limits)
// make sure we use the texture resolution limits from the adapter,
// so we can support images the size of the surface.
.using_resolution(adapter_limits);
let base_limits = get_base_device_limits_from_adapter_limits(&adapter_limits);

let (desc, trace_str, device_lost_handler) = match descriptor {
Some(descriptor) => {
Expand Down
158 changes: 137 additions & 21 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,48 @@ pub(crate) fn make_slice<'a, T: 'a>(ptr: *const T, len: usize) -> &'a [T] {
}
}

#[inline]
fn limits_gteq_default(limits: &wgt::Limits) -> bool {
wgt::Limits::check_limits(&wgt::Limits::default(), limits)
}
#[inline]
fn limits_gteq_downlevel_defaults(limits: &wgt::Limits) -> bool {
wgt::Limits::check_limits(&wgt::Limits::downlevel_defaults(), limits)
}
#[inline]
pub fn get_base_device_limits_from_adapter_limits(adapter_limits: &wgt::Limits) -> wgt::Limits {
if limits_gteq_default(adapter_limits) {
return wgt::Limits::default();
let default_limits = wgt::Limits::default();
let dim_1d = std::cmp::min(
adapter_limits.max_texture_dimension_1d,
default_limits.max_texture_dimension_1d,
);
let dim_2d = std::cmp::min(
adapter_limits.max_texture_dimension_2d,
default_limits.max_texture_dimension_2d,
);
let dim_3d = std::cmp::min(
adapter_limits.max_texture_dimension_3d,
default_limits.max_texture_dimension_3d,
);

let default_limits_with_resolution = wgt::Limits {
max_texture_dimension_1d: dim_1d,
max_texture_dimension_2d: dim_2d,
max_texture_dimension_3d: dim_3d,
..default_limits
};
if wgt::Limits::check_limits(&default_limits_with_resolution, adapter_limits) {
return default_limits_with_resolution;
}
if limits_gteq_downlevel_defaults(adapter_limits) {
return wgt::Limits::downlevel_defaults();

let downlevel_defaults_limits_with_resolution = wgt::Limits {
max_texture_dimension_1d: dim_1d,
max_texture_dimension_2d: dim_2d,
max_texture_dimension_3d: dim_3d,
..wgt::Limits::downlevel_defaults()
};
if wgt::Limits::check_limits(&downlevel_defaults_limits_with_resolution, adapter_limits) {
return downlevel_defaults_limits_with_resolution;
}

wgt::Limits {
max_texture_dimension_1d: dim_1d,
max_texture_dimension_2d: dim_2d,
max_texture_dimension_3d: dim_3d,
..wgt::Limits::downlevel_webgl2_defaults()
}
wgt::Limits::downlevel_webgl2_defaults()
}

/// Follow a chain of next pointers and automatically resolve them to the underlying structs.
Expand Down Expand Up @@ -245,6 +270,31 @@ macro_rules! map_enum {

#[test]
pub fn test_get_base_device_limits_from_adapter_limits() {
fn expected_limits_with_default_resolution(
adapter_limits: wgt::Limits,
expected: wgt::Limits,
) -> wgt::Limits {
let default_limits = wgt::Limits::default();
let dim_1d = std::cmp::min(
adapter_limits.max_texture_dimension_1d,
default_limits.max_texture_dimension_1d,
);
let dim_2d = std::cmp::min(
adapter_limits.max_texture_dimension_2d,
default_limits.max_texture_dimension_2d,
);
let dim_3d = std::cmp::min(
adapter_limits.max_texture_dimension_3d,
default_limits.max_texture_dimension_3d,
);
wgt::Limits {
max_texture_dimension_1d: dim_1d,
max_texture_dimension_2d: dim_2d,
max_texture_dimension_3d: dim_3d,
..expected
}
}

// max_uniform_buffer_binding_size
// default: 64 << 10
// downlevel_defaults: 16 << 10
Expand All @@ -256,7 +306,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_webgl2_defaults(),
expected_limits_with_default_resolution(
adapter_limits,
wgt::Limits::downlevel_webgl2_defaults()
),
);
}
{
Expand All @@ -266,7 +319,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_defaults(),
expected_limits_with_default_resolution(
adapter_limits,
wgt::Limits::downlevel_defaults()
),
);
}
{
Expand All @@ -276,7 +332,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_defaults(),
expected_limits_with_default_resolution(
adapter_limits,
wgt::Limits::downlevel_defaults()
),
);
}
{
Expand All @@ -286,7 +345,7 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
);
}
{
Expand All @@ -296,7 +355,7 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
);
}

Expand All @@ -311,7 +370,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_webgl2_defaults(),
expected_limits_with_default_resolution(
adapter_limits,
wgt::Limits::downlevel_webgl2_defaults()
),
);
}
{
Expand All @@ -321,7 +383,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_webgl2_defaults(),
expected_limits_with_default_resolution(
adapter_limits,
wgt::Limits::downlevel_webgl2_defaults()
),
);
}
{
Expand All @@ -331,17 +396,68 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
);
}
{
let adapter_limits = wgt::Limits {
max_compute_workgroups_per_dimension: 65535 + 1,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
);
}

// Texture dimensions are clamped to default limits.
{
let adapter_limits = wgt::Limits {
max_texture_dimension_1d: 16 << 10,
max_texture_dimension_2d: 16 << 10,
max_texture_dimension_3d: 16 << 10,
..wgt::Limits::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
);
}
{
let adapter_limits = wgt::Limits {
max_texture_dimension_1d: 2 << 10,
max_texture_dimension_2d: 2 << 10,
max_texture_dimension_3d: 2 << 10,
..wgt::Limits::downlevel_defaults()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits {
max_texture_dimension_1d: 2 << 10,
max_texture_dimension_2d: 2 << 10,
max_texture_dimension_3d: 2 << 10,
..wgt::Limits::downlevel_defaults()
},
);
}
{
// Ensure that texture resolution limits of an adapter lower than
// the default does not lead to the selection of downlevel limits
// as the base limits.
let adapter_limits = wgt::Limits {
max_texture_dimension_1d: 16 << 10,
max_texture_dimension_2d: 16 << 10,
max_texture_dimension_3d: 2 << 10,
..wgt::Limits::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits {
max_texture_dimension_1d: 8 << 10,
max_texture_dimension_2d: 8 << 10,
max_texture_dimension_3d: 2 << 10,
..wgt::Limits::default()
},
);
}
}

0 comments on commit 6e46ddf

Please sign in to comment.