Skip to content

Commit

Permalink
Limits fallback (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajveermalviya authored Oct 9, 2023
1 parent 46e345b commit 24e00f4
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 17 deletions.
21 changes: 15 additions & 6 deletions src/conv.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use wgc::Label;

use crate::native;
use crate::utils::{make_slice, ptr_into_label, ptr_into_pathbuf};
use crate::{follow_chain, map_enum};
Expand Down Expand Up @@ -297,13 +295,20 @@ pub fn map_instance_descriptor(
#[inline]
pub fn map_device_descriptor<'a>(
des: &native::WGPUDeviceDescriptor,
use_downlevel: bool,
extras: Option<&native::WGPUDeviceExtras>,
) -> (wgt::DeviceDescriptor<Label<'a>>, *const std::ffi::c_char) {
) -> (
wgt::DeviceDescriptor<wgc::Label<'a>>,
*const std::ffi::c_char,
) {
let limits = unsafe { des.requiredLimits.as_ref() }.map_or(
wgt::Limits::default(),
match use_downlevel {
true => wgt::Limits::downlevel_defaults(),
false => wgt::Limits::default(),
},
|required_limits| unsafe {
follow_chain!(
map_required_limits(required_limits,
map_required_limits((required_limits, use_downlevel),
WGPUSType_RequiredLimitsExtras => native::WGPURequiredLimitsExtras)
)
},
Expand Down Expand Up @@ -422,10 +427,14 @@ pub fn write_limits_struct(
#[inline]
pub fn map_required_limits(
required_limits: &native::WGPURequiredLimits,
use_downlevel: bool,
extras: Option<&native::WGPURequiredLimitsExtras>,
) -> wgt::Limits {
let limits = required_limits.limits;
let mut wgt_limits = wgt::Limits::default();
let mut wgt_limits = match use_downlevel {
true => wgt::Limits::downlevel_defaults(),
false => wgt::Limits::default(),
};
if limits.maxTextureDimension1D != native::WGPU_LIMIT_U32_UNDEFINED {
wgt_limits.max_texture_dimension_1d = limits.maxTextureDimension1D;
}
Expand Down
41 changes: 31 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::{
sync::Arc,
thread,
};
use utils::{make_slice, ptr_into_label, ptr_into_path};
use utils::{make_slice, ptr_into_label, ptr_into_path, should_use_downlevel_limits};
use wgc::{
command::{self, bundle_ffi, compute_ffi, render_ffi},
gfx_select, id, resource, Label,
Expand Down Expand Up @@ -576,7 +576,7 @@ pub unsafe extern "C" fn wgpuCreateInstance(
) -> native::WGPUInstance {
let instance_desc = match descriptor {
Some(descriptor) => follow_chain!(map_instance_descriptor(
descriptor,
(descriptor),
WGPUSType_InstanceExtras => native::WGPUInstanceExtras
)),
None => wgt::InstanceDescriptor::default(),
Expand Down Expand Up @@ -721,10 +721,25 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice(
};
let callback = callback.expect("invalid callback");

let adapter_limits = match gfx_select!(adapter_id => context.adapter_limits(adapter_id)) {
Ok(adapter_limits) => adapter_limits,
Err(cause) => {
let msg = CString::new(format_error(context, &cause)).unwrap();
callback(
native::WGPURequestDeviceStatus_Error,
std::ptr::null(),
msg.as_ptr(),
userdata,
);
return;
}
};
let use_downlevel = should_use_downlevel_limits(&adapter_limits);

let (desc, trace_str, device_lost_handler) = match descriptor {
Some(descriptor) => {
let (desc, trace_str) = follow_chain!(
map_device_descriptor(descriptor,
map_device_descriptor((descriptor, use_downlevel),
WGPUSType_DeviceExtras => native::WGPUDeviceExtras)
);
let device_lost_handler = DeviceLostCallback {
Expand All @@ -734,7 +749,13 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice(
(desc, trace_str, device_lost_handler)
}
None => (
wgt::DeviceDescriptor::default(),
wgt::DeviceDescriptor {
limits: match use_downlevel {
true => wgt::Limits::downlevel_defaults(),
false => wgt::Limits::default(),
},
..Default::default()
},
std::ptr::null(),
DEFAULT_DEVICE_LOST_HANDLER,
),
Expand Down Expand Up @@ -1728,7 +1749,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateBindGroup(
let entries = make_slice(descriptor.entries, descriptor.entryCount)
.iter()
.map(|entry| {
follow_chain!(map_bind_group_entry(entry,
follow_chain!(map_bind_group_entry((entry),
WGPUSType_BindGroupEntryExtras => native::WGPUBindGroupEntryExtras)
)
})
Expand Down Expand Up @@ -1772,7 +1793,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateBindGroupLayout(
let entries = make_slice(descriptor.entries, descriptor.entryCount)
.iter()
.map(|entry| {
follow_chain!(map_bind_group_layout_entry(entry,
follow_chain!(map_bind_group_layout_entry((entry),
WGPUSType_BindGroupLayoutEntryExtras => native::WGPUBindGroupLayoutEntryExtras)
)
})
Expand Down Expand Up @@ -1955,7 +1976,7 @@ pub unsafe extern "C" fn wgpuDeviceCreatePipelineLayout(

let desc = follow_chain!(
map_pipeline_layout_descriptor(
descriptor,
(descriptor),
WGPUSType_PipelineLayoutExtras => native::WGPUPipelineLayoutExtras)
);
let (pipeline_layout_id, error) =
Expand Down Expand Up @@ -2113,7 +2134,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline(
},
unclipped_depth: follow_chain!(
map_primitive_state(
&descriptor.primitive,
(&descriptor.primitive),
WGPUSType_PrimitiveDepthClipControl => native::WGPUPrimitiveDepthClipControl
)
),
Expand Down Expand Up @@ -2292,7 +2313,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModule(
let descriptor = descriptor.expect("invalid descriptor");

let source = follow_chain!(
map_shader_module(descriptor,
map_shader_module((descriptor),
WGPUSType_ShaderModuleSPIRVDescriptor => native::WGPUShaderModuleSPIRVDescriptor,
WGPUSType_ShaderModuleWGSLDescriptor => native::WGPUShaderModuleWGSLDescriptor,
WGPUSType_ShaderModuleGLSLDescriptor => native::WGPUShaderModuleGLSLDescriptor)
Expand Down Expand Up @@ -2548,7 +2569,7 @@ pub unsafe extern "C" fn wgpuInstanceCreateSurface(
let descriptor = descriptor.expect("invalid descriptor");

let create_surface_params = follow_chain!(
map_surface(descriptor,
map_surface((descriptor),
WGPUSType_SurfaceDescriptorFromWindowsHWND => native::WGPUSurfaceDescriptorFromWindowsHWND,
WGPUSType_SurfaceDescriptorFromXcbWindow => native::WGPUSurfaceDescriptorFromXcbWindow,
WGPUSType_SurfaceDescriptorFromXlibWindow => native::WGPUSurfaceDescriptorFromXlibWindow,
Expand Down
60 changes: 59 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ 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)
}

/// Follow a chain of next pointers and automatically resolve them to the underlying structs.
///
/// # Syntax:
Expand Down Expand Up @@ -86,7 +91,7 @@ pub(crate) fn make_slice<'a, T: 'a>(ptr: *const T, len: usize) -> &'a [T] {

#[macro_export]
macro_rules! follow_chain {
($func:ident($base:expr $(, $stype:ident => $ty:ty)*)) => {{
($func:ident(($base:expr) $(, $stype:ident => $ty:ty)*)) => {{
#[allow(non_snake_case)] // We use the type name as an easily usable temporary name
{
$(
Expand Down Expand Up @@ -114,6 +119,34 @@ macro_rules! follow_chain {
}
$func($base, $($stype),*)
}}};
($func:ident(($base1:expr, $base2:expr) $(, $stype:ident => $ty:ty)*)) => {{
#[allow(non_snake_case)] // We use the type name as an easily usable temporary name
{
$(
let mut $stype: Option<&$ty> = None;
)*
let mut chain_opt: Option<&$crate::native::WGPUChainedStruct> = $base1.nextInChain.as_ref();
while let Some(next_in_chain) = chain_opt {
match next_in_chain.sType {
$(
$crate::native::$stype => {
let next_in_chain_ptr = next_in_chain as *const $crate::native::WGPUChainedStruct;
assert_eq!(
0,
next_in_chain_ptr.align_offset(::std::mem::align_of::<$ty>()),
concat!("Chain structure pointer is not aligned correctly to dereference as ", stringify!($ty), ". Correct alignment: {}"),
::std::mem::align_of::<$ty>()
);
let type_ptr: *const $ty = next_in_chain_ptr as _;
$stype = Some(&*type_ptr);
}
)*
_ => {}
}
chain_opt = next_in_chain.next.as_ref();
}
$func($base1, $base2, $($stype),*)
}}};
}

/// Creates a function which maps native constants to wgpu enums.
Expand Down Expand Up @@ -195,3 +228,28 @@ macro_rules! map_enum {
}
};
}

#[test]
pub fn test_should_use_downlevel_limits() {
{
let adapter_limits = wgt::Limits {
max_bind_groups: 2, // default are 4
..Default::default()
};
assert_eq!(should_use_downlevel_limits(&adapter_limits), true);
}
{
let adapter_limits = wgt::Limits {
max_bind_groups: 4, // default are 4
..Default::default()
};
assert_eq!(should_use_downlevel_limits(&adapter_limits), false);
}
{
let adapter_limits = wgt::Limits {
max_bind_groups: 8, // default are 4
..Default::default()
};
assert_eq!(should_use_downlevel_limits(&adapter_limits), false);
}
}

0 comments on commit 24e00f4

Please sign in to comment.