Skip to content

Commit

Permalink
better base limits for device (#312)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajveermalviya authored Nov 3, 2023
1 parent 2cc7465 commit 262436a
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 37 deletions.
32 changes: 12 additions & 20 deletions src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,30 +317,25 @@ pub fn map_instance_descriptor(
#[inline]
pub fn map_device_descriptor<'a>(
des: &native::WGPUDeviceDescriptor,
use_downlevel: bool,
base_limits: wgt::Limits,
extras: Option<&native::WGPUDeviceExtras>,
) -> (
wgt::DeviceDescriptor<wgc::Label<'a>>,
*const std::ffi::c_char,
) {
let limits = unsafe { des.requiredLimits.as_ref() }.map_or(
match use_downlevel {
true => wgt::Limits::downlevel_defaults(),
false => wgt::Limits::default(),
},
|required_limits| unsafe {
follow_chain!(
map_required_limits((required_limits, use_downlevel),
WGPUSType_RequiredLimitsExtras => native::WGPURequiredLimitsExtras)
)
},
);

(
wgt::DeviceDescriptor {
label: ptr_into_label(des.label),
features: map_features(make_slice(des.requiredFeatures, des.requiredFeatureCount)),
limits,
limits: match unsafe { des.requiredLimits.as_ref() } {
Some(required_limits) => unsafe {
follow_chain!(
map_required_limits((required_limits, base_limits),
WGPUSType_RequiredLimitsExtras => native::WGPURequiredLimitsExtras)
)
},
None => base_limits,
},
},
match extras {
Some(extras) => extras.tracePath,
Expand Down Expand Up @@ -452,14 +447,11 @@ pub fn write_limits_struct(
#[inline]
pub fn map_required_limits(
required_limits: &native::WGPURequiredLimits,
use_downlevel: bool,
base_limits: wgt::Limits,
extras: Option<&native::WGPURequiredLimitsExtras>,
) -> wgt::Limits {
let limits = required_limits.limits;
let mut wgt_limits = match use_downlevel {
true => wgt::Limits::downlevel_defaults(),
false => wgt::Limits::default(),
};
let mut wgt_limits = base_limits;
if limits.maxTextureDimension1D != native::WGPU_LIMIT_U32_UNDEFINED {
wgt_limits.max_texture_dimension_1d = limits.maxTextureDimension1D;
}
Expand Down
16 changes: 9 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use std::{
sync::Arc,
thread,
};
use utils::{make_slice, ptr_into_label, ptr_into_path, should_use_downlevel_limits};
use utils::{
get_base_device_limits_from_adapter_limits, make_slice, ptr_into_label, ptr_into_path,
};
use wgc::{
command::{self, bundle_ffi, compute_ffi, render_ffi},
gfx_select, id, resource, Label,
Expand Down Expand Up @@ -735,12 +737,15 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice(
return;
}
};
let use_downlevel = should_use_downlevel_limits(&adapter_limits);
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 (desc, trace_str, device_lost_handler) = match descriptor {
Some(descriptor) => {
let (desc, trace_str) = follow_chain!(
map_device_descriptor((descriptor, use_downlevel),
map_device_descriptor((descriptor, base_limits),
WGPUSType_DeviceExtras => native::WGPUDeviceExtras)
);
let device_lost_handler = DeviceLostCallback {
Expand All @@ -751,10 +756,7 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice(
}
None => (
wgt::DeviceDescriptor {
limits: match use_downlevel {
true => wgt::Limits::downlevel_defaults(),
false => wgt::Limits::default(),
},
limits: base_limits,
..Default::default()
},
std::ptr::null(),
Expand Down
112 changes: 102 additions & 10 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,23 @@ pub(crate) fn make_slice<'a, T: 'a>(ptr: *const T, len: usize) -> &'a [T] {
}
}

// Check if downlevel limits should be preffered over the default limits.
pub fn should_use_downlevel_limits(adapter_limits: &wgt::Limits) -> bool {
!wgt::Limits::default().check_limits(adapter_limits)
#[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();
}
if limits_gteq_downlevel_defaults(adapter_limits) {
return wgt::Limits::downlevel_defaults();
}
wgt::Limits::downlevel_webgl2_defaults()
}

/// Follow a chain of next pointers and automatically resolve them to the underlying structs.
Expand Down Expand Up @@ -230,26 +244,104 @@ macro_rules! map_enum {
}

#[test]
pub fn test_should_use_downlevel_limits() {
pub fn test_get_base_device_limits_from_adapter_limits() {
// max_uniform_buffer_binding_size
// default: 64 << 10
// downlevel_defaults: 16 << 10
// downlevel_webgl2_defaults: 16 << 10
{
let adapter_limits = wgt::Limits {
max_uniform_buffer_binding_size: (16 << 10) - 1,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_webgl2_defaults(),
);
}
{
let adapter_limits = wgt::Limits {
max_uniform_buffer_binding_size: 16 << 10,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_defaults(),
);
}
{
let adapter_limits = wgt::Limits {
max_uniform_buffer_binding_size: (16 << 10) + 1,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_defaults(),
);
}
{
let adapter_limits = wgt::Limits {
max_uniform_buffer_binding_size: 64 << 10,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
);
}
{
let adapter_limits = wgt::Limits {
max_uniform_buffer_binding_size: (64 << 10) + 1,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
);
}

// max_compute_workgroups_per_dimension
// default: 65535
// downlevel_defaults: 65535
// downlevel_webgl2_defaults: 0
{
let adapter_limits = wgt::Limits {
max_compute_workgroups_per_dimension: 0,
..Default::default()
};
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_webgl2_defaults(),
);
}
{
let adapter_limits = wgt::Limits {
max_bind_groups: 2, // default are 4
max_compute_workgroups_per_dimension: 65535 - 1,
..Default::default()
};
assert_eq!(should_use_downlevel_limits(&adapter_limits), true);
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::downlevel_webgl2_defaults(),
);
}
{
let adapter_limits = wgt::Limits {
max_bind_groups: 4, // default are 4
max_compute_workgroups_per_dimension: 65535,
..Default::default()
};
assert_eq!(should_use_downlevel_limits(&adapter_limits), false);
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
);
}
{
let adapter_limits = wgt::Limits {
max_bind_groups: 8, // default are 4
max_compute_workgroups_per_dimension: 65535 + 1,
..Default::default()
};
assert_eq!(should_use_downlevel_limits(&adapter_limits), false);
assert_eq!(
get_base_device_limits_from_adapter_limits(&adapter_limits),
wgt::Limits::default(),
);
}
}

0 comments on commit 262436a

Please sign in to comment.