Skip to content

Commit 6e46ddf

Browse files
Fix device limits diverging from base limits by default (#379)
* 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]>
1 parent 1ac3a5c commit 6e46ddf

File tree

2 files changed

+138
-25
lines changed

2 files changed

+138
-25
lines changed

src/lib.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -794,10 +794,7 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice(
794794
return;
795795
}
796796
};
797-
let base_limits = get_base_device_limits_from_adapter_limits(&adapter_limits)
798-
// make sure we use the texture resolution limits from the adapter,
799-
// so we can support images the size of the surface.
800-
.using_resolution(adapter_limits);
797+
let base_limits = get_base_device_limits_from_adapter_limits(&adapter_limits);
801798

802799
let (desc, trace_str, device_lost_handler) = match descriptor {
803800
Some(descriptor) => {

src/utils.rs

+137-21
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,48 @@ pub(crate) fn make_slice<'a, T: 'a>(ptr: *const T, len: usize) -> &'a [T] {
5454
}
5555
}
5656

57-
#[inline]
58-
fn limits_gteq_default(limits: &wgt::Limits) -> bool {
59-
wgt::Limits::check_limits(&wgt::Limits::default(), limits)
60-
}
61-
#[inline]
62-
fn limits_gteq_downlevel_defaults(limits: &wgt::Limits) -> bool {
63-
wgt::Limits::check_limits(&wgt::Limits::downlevel_defaults(), limits)
64-
}
6557
#[inline]
6658
pub fn get_base_device_limits_from_adapter_limits(adapter_limits: &wgt::Limits) -> wgt::Limits {
67-
if limits_gteq_default(adapter_limits) {
68-
return wgt::Limits::default();
59+
let default_limits = wgt::Limits::default();
60+
let dim_1d = std::cmp::min(
61+
adapter_limits.max_texture_dimension_1d,
62+
default_limits.max_texture_dimension_1d,
63+
);
64+
let dim_2d = std::cmp::min(
65+
adapter_limits.max_texture_dimension_2d,
66+
default_limits.max_texture_dimension_2d,
67+
);
68+
let dim_3d = std::cmp::min(
69+
adapter_limits.max_texture_dimension_3d,
70+
default_limits.max_texture_dimension_3d,
71+
);
72+
73+
let default_limits_with_resolution = wgt::Limits {
74+
max_texture_dimension_1d: dim_1d,
75+
max_texture_dimension_2d: dim_2d,
76+
max_texture_dimension_3d: dim_3d,
77+
..default_limits
78+
};
79+
if wgt::Limits::check_limits(&default_limits_with_resolution, adapter_limits) {
80+
return default_limits_with_resolution;
6981
}
70-
if limits_gteq_downlevel_defaults(adapter_limits) {
71-
return wgt::Limits::downlevel_defaults();
82+
83+
let downlevel_defaults_limits_with_resolution = wgt::Limits {
84+
max_texture_dimension_1d: dim_1d,
85+
max_texture_dimension_2d: dim_2d,
86+
max_texture_dimension_3d: dim_3d,
87+
..wgt::Limits::downlevel_defaults()
88+
};
89+
if wgt::Limits::check_limits(&downlevel_defaults_limits_with_resolution, adapter_limits) {
90+
return downlevel_defaults_limits_with_resolution;
91+
}
92+
93+
wgt::Limits {
94+
max_texture_dimension_1d: dim_1d,
95+
max_texture_dimension_2d: dim_2d,
96+
max_texture_dimension_3d: dim_3d,
97+
..wgt::Limits::downlevel_webgl2_defaults()
7298
}
73-
wgt::Limits::downlevel_webgl2_defaults()
7499
}
75100

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

246271
#[test]
247272
pub fn test_get_base_device_limits_from_adapter_limits() {
273+
fn expected_limits_with_default_resolution(
274+
adapter_limits: wgt::Limits,
275+
expected: wgt::Limits,
276+
) -> wgt::Limits {
277+
let default_limits = wgt::Limits::default();
278+
let dim_1d = std::cmp::min(
279+
adapter_limits.max_texture_dimension_1d,
280+
default_limits.max_texture_dimension_1d,
281+
);
282+
let dim_2d = std::cmp::min(
283+
adapter_limits.max_texture_dimension_2d,
284+
default_limits.max_texture_dimension_2d,
285+
);
286+
let dim_3d = std::cmp::min(
287+
adapter_limits.max_texture_dimension_3d,
288+
default_limits.max_texture_dimension_3d,
289+
);
290+
wgt::Limits {
291+
max_texture_dimension_1d: dim_1d,
292+
max_texture_dimension_2d: dim_2d,
293+
max_texture_dimension_3d: dim_3d,
294+
..expected
295+
}
296+
}
297+
248298
// max_uniform_buffer_binding_size
249299
// default: 64 << 10
250300
// downlevel_defaults: 16 << 10
@@ -256,7 +306,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
256306
};
257307
assert_eq!(
258308
get_base_device_limits_from_adapter_limits(&adapter_limits),
259-
wgt::Limits::downlevel_webgl2_defaults(),
309+
expected_limits_with_default_resolution(
310+
adapter_limits,
311+
wgt::Limits::downlevel_webgl2_defaults()
312+
),
260313
);
261314
}
262315
{
@@ -266,7 +319,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
266319
};
267320
assert_eq!(
268321
get_base_device_limits_from_adapter_limits(&adapter_limits),
269-
wgt::Limits::downlevel_defaults(),
322+
expected_limits_with_default_resolution(
323+
adapter_limits,
324+
wgt::Limits::downlevel_defaults()
325+
),
270326
);
271327
}
272328
{
@@ -276,7 +332,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
276332
};
277333
assert_eq!(
278334
get_base_device_limits_from_adapter_limits(&adapter_limits),
279-
wgt::Limits::downlevel_defaults(),
335+
expected_limits_with_default_resolution(
336+
adapter_limits,
337+
wgt::Limits::downlevel_defaults()
338+
),
280339
);
281340
}
282341
{
@@ -286,7 +345,7 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
286345
};
287346
assert_eq!(
288347
get_base_device_limits_from_adapter_limits(&adapter_limits),
289-
wgt::Limits::default(),
348+
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
290349
);
291350
}
292351
{
@@ -296,7 +355,7 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
296355
};
297356
assert_eq!(
298357
get_base_device_limits_from_adapter_limits(&adapter_limits),
299-
wgt::Limits::default(),
358+
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
300359
);
301360
}
302361

@@ -311,7 +370,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
311370
};
312371
assert_eq!(
313372
get_base_device_limits_from_adapter_limits(&adapter_limits),
314-
wgt::Limits::downlevel_webgl2_defaults(),
373+
expected_limits_with_default_resolution(
374+
adapter_limits,
375+
wgt::Limits::downlevel_webgl2_defaults()
376+
),
315377
);
316378
}
317379
{
@@ -321,7 +383,10 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
321383
};
322384
assert_eq!(
323385
get_base_device_limits_from_adapter_limits(&adapter_limits),
324-
wgt::Limits::downlevel_webgl2_defaults(),
386+
expected_limits_with_default_resolution(
387+
adapter_limits,
388+
wgt::Limits::downlevel_webgl2_defaults()
389+
),
325390
);
326391
}
327392
{
@@ -331,17 +396,68 @@ pub fn test_get_base_device_limits_from_adapter_limits() {
331396
};
332397
assert_eq!(
333398
get_base_device_limits_from_adapter_limits(&adapter_limits),
334-
wgt::Limits::default(),
399+
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
335400
);
336401
}
337402
{
338403
let adapter_limits = wgt::Limits {
339404
max_compute_workgroups_per_dimension: 65535 + 1,
340405
..Default::default()
341406
};
407+
assert_eq!(
408+
get_base_device_limits_from_adapter_limits(&adapter_limits),
409+
expected_limits_with_default_resolution(adapter_limits, wgt::Limits::default()),
410+
);
411+
}
412+
413+
// Texture dimensions are clamped to default limits.
414+
{
415+
let adapter_limits = wgt::Limits {
416+
max_texture_dimension_1d: 16 << 10,
417+
max_texture_dimension_2d: 16 << 10,
418+
max_texture_dimension_3d: 16 << 10,
419+
..wgt::Limits::default()
420+
};
342421
assert_eq!(
343422
get_base_device_limits_from_adapter_limits(&adapter_limits),
344423
wgt::Limits::default(),
345424
);
346425
}
426+
{
427+
let adapter_limits = wgt::Limits {
428+
max_texture_dimension_1d: 2 << 10,
429+
max_texture_dimension_2d: 2 << 10,
430+
max_texture_dimension_3d: 2 << 10,
431+
..wgt::Limits::downlevel_defaults()
432+
};
433+
assert_eq!(
434+
get_base_device_limits_from_adapter_limits(&adapter_limits),
435+
wgt::Limits {
436+
max_texture_dimension_1d: 2 << 10,
437+
max_texture_dimension_2d: 2 << 10,
438+
max_texture_dimension_3d: 2 << 10,
439+
..wgt::Limits::downlevel_defaults()
440+
},
441+
);
442+
}
443+
{
444+
// Ensure that texture resolution limits of an adapter lower than
445+
// the default does not lead to the selection of downlevel limits
446+
// as the base limits.
447+
let adapter_limits = wgt::Limits {
448+
max_texture_dimension_1d: 16 << 10,
449+
max_texture_dimension_2d: 16 << 10,
450+
max_texture_dimension_3d: 2 << 10,
451+
..wgt::Limits::default()
452+
};
453+
assert_eq!(
454+
get_base_device_limits_from_adapter_limits(&adapter_limits),
455+
wgt::Limits {
456+
max_texture_dimension_1d: 8 << 10,
457+
max_texture_dimension_2d: 8 << 10,
458+
max_texture_dimension_3d: 2 << 10,
459+
..wgt::Limits::default()
460+
},
461+
);
462+
}
347463
}

0 commit comments

Comments
 (0)