Skip to content

Commit 41efabb

Browse files
Fix limits interface on web. (#4107)
1 parent 4a12ab7 commit 41efabb

File tree

3 files changed

+111
-35
lines changed

3 files changed

+111
-35
lines changed

.cargo/config.toml

Lines changed: 0 additions & 7 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ By @Valaphee in [#3402](https://github.com/gfx-rs/wgpu/pull/3402)
107107

108108
- Ensure that MTLCommandEncoder calls endEncoding before it is deallocated. By @bradwerth in [#4023](https://github.com/gfx-rs/wgpu/pull/4023)
109109

110+
#### WebGPU
111+
112+
- Ensure that limit requests and reporting is done correctly. By @OptimisticPeach in [#4107](https://github.com/gfx-rs/wgpu/pull/4107)
113+
110114
### Documentation
111115

112116
- Add an overview of `RenderPass` and how render state works. By @kpreid in [#4055](https://github.com/gfx-rs/wgpu/pull/4055)

wgpu/src/backend/web.rs

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,99 @@ fn map_wgt_features(supported_features: web_sys::GpuSupportedFeatures) -> wgt::F
687687
features
688688
}
689689

690+
fn map_wgt_limits(limits: web_sys::GpuSupportedLimits) -> wgt::Limits {
691+
wgt::Limits {
692+
max_texture_dimension_1d: limits.max_texture_dimension_1d(),
693+
max_texture_dimension_2d: limits.max_texture_dimension_2d(),
694+
max_texture_dimension_3d: limits.max_texture_dimension_3d(),
695+
max_texture_array_layers: limits.max_texture_array_layers(),
696+
max_bind_groups: limits.max_bind_groups(),
697+
max_bindings_per_bind_group: limits.max_bindings_per_bind_group(),
698+
max_dynamic_uniform_buffers_per_pipeline_layout: limits
699+
.max_dynamic_uniform_buffers_per_pipeline_layout(),
700+
max_dynamic_storage_buffers_per_pipeline_layout: limits
701+
.max_dynamic_storage_buffers_per_pipeline_layout(),
702+
max_sampled_textures_per_shader_stage: limits.max_sampled_textures_per_shader_stage(),
703+
max_samplers_per_shader_stage: limits.max_samplers_per_shader_stage(),
704+
max_storage_buffers_per_shader_stage: limits.max_storage_buffers_per_shader_stage(),
705+
max_storage_textures_per_shader_stage: limits.max_storage_textures_per_shader_stage(),
706+
max_uniform_buffers_per_shader_stage: limits.max_uniform_buffers_per_shader_stage(),
707+
max_uniform_buffer_binding_size: limits.max_uniform_buffer_binding_size() as u32,
708+
max_storage_buffer_binding_size: limits.max_storage_buffer_binding_size() as u32,
709+
max_vertex_buffers: limits.max_vertex_buffers(),
710+
max_buffer_size: limits.max_buffer_size() as u64,
711+
max_vertex_attributes: limits.max_vertex_attributes(),
712+
max_vertex_buffer_array_stride: limits.max_vertex_buffer_array_stride(),
713+
min_uniform_buffer_offset_alignment: limits.min_uniform_buffer_offset_alignment(),
714+
min_storage_buffer_offset_alignment: limits.min_storage_buffer_offset_alignment(),
715+
max_inter_stage_shader_components: limits.max_inter_stage_shader_components(),
716+
max_compute_workgroup_storage_size: limits.max_compute_workgroup_storage_size(),
717+
max_compute_invocations_per_workgroup: limits.max_compute_invocations_per_workgroup(),
718+
max_compute_workgroup_size_x: limits.max_compute_workgroup_size_x(),
719+
max_compute_workgroup_size_y: limits.max_compute_workgroup_size_y(),
720+
max_compute_workgroup_size_z: limits.max_compute_workgroup_size_z(),
721+
max_compute_workgroups_per_dimension: limits.max_compute_workgroups_per_dimension(),
722+
// The following are not part of WebGPU
723+
max_push_constant_size: wgt::Limits::default().max_push_constant_size,
724+
max_non_sampler_bindings: wgt::Limits::default().max_non_sampler_bindings,
725+
}
726+
}
727+
728+
fn map_js_sys_limits(limits: &wgt::Limits) -> js_sys::Object {
729+
let object = js_sys::Object::new();
730+
731+
macro_rules! set_properties {
732+
(($from:expr) => ($on:expr) : $(($js_ident:ident, $rs_ident:ident)),* $(,)?) => {
733+
$(
734+
::js_sys::Reflect::set(
735+
&$on,
736+
&::wasm_bindgen::JsValue::from(stringify!($js_ident)),
737+
// Numbers may be u64, however using `from` on a u64 yields
738+
// errors on the wasm side, since it uses an unsupported api.
739+
// Wasm sends us things that need to fit into u64s by sending
740+
// us f64s instead. So we just send them f64s back.
741+
&::wasm_bindgen::JsValue::from($from.$rs_ident as f64)
742+
)
743+
.expect("Setting Object properties should never fail.");
744+
)*
745+
}
746+
}
747+
748+
set_properties![
749+
(limits) => (object):
750+
(maxTextureDimension1D, max_texture_dimension_1d),
751+
(maxTextureDimension2D, max_texture_dimension_2d),
752+
(maxTextureDimension3D, max_texture_dimension_3d),
753+
(maxTextureArrayLayers, max_texture_array_layers),
754+
(maxBindGroups, max_bind_groups),
755+
(maxBindingsPerBindGroup, max_bindings_per_bind_group),
756+
(maxDynamicUniformBuffersPerPipelineLayout, max_dynamic_uniform_buffers_per_pipeline_layout),
757+
(maxDynamicStorageBuffersPerPipelineLayout, max_dynamic_storage_buffers_per_pipeline_layout),
758+
(maxSampledTexturesPerShaderStage, max_sampled_textures_per_shader_stage),
759+
(maxSamplersPerShaderStage, max_samplers_per_shader_stage),
760+
(maxStorageBuffersPerShaderStage, max_storage_buffers_per_shader_stage),
761+
(maxStorageTexturesPerShaderStage, max_storage_textures_per_shader_stage),
762+
(maxUniformBuffersPerShaderStage, max_uniform_buffers_per_shader_stage),
763+
(maxUniformBufferBindingSize, max_uniform_buffer_binding_size),
764+
(maxStorageBufferBindingSize, max_storage_buffer_binding_size),
765+
(minUniformBufferOffsetAlignment, min_uniform_buffer_offset_alignment),
766+
(minStorageBufferOffsetAlignment, min_storage_buffer_offset_alignment),
767+
(maxVertexBuffers, max_vertex_buffers),
768+
(maxBufferSize, max_buffer_size),
769+
(maxVertexAttributes, max_vertex_attributes),
770+
(maxVertexBufferArrayStride, max_vertex_buffer_array_stride),
771+
(maxInterStageShaderComponents, max_inter_stage_shader_components),
772+
(maxComputeWorkgroupStorageSize, max_compute_workgroup_storage_size),
773+
(maxComputeInvocationsPerWorkgroup, max_compute_invocations_per_workgroup),
774+
(maxComputeWorkgroupSizeX, max_compute_workgroup_size_x),
775+
(maxComputeWorkgroupSizeY, max_compute_workgroup_size_y),
776+
(maxComputeWorkgroupSizeZ, max_compute_workgroup_size_z),
777+
(maxComputeWorkgroupsPerDimension, max_compute_workgroups_per_dimension),
778+
];
779+
780+
object
781+
}
782+
690783
type JsFutureResult = Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>;
691784

692785
fn future_request_adapter(
@@ -1014,9 +1107,19 @@ impl crate::context::Context for Context {
10141107
//Error: Tracing isn't supported on the Web target
10151108
}
10161109

1017-
// TODO: non-guaranteed limits
10181110
let mut mapped_desc = web_sys::GpuDeviceDescriptor::new();
10191111

1112+
// TODO: Migrate to a web_sys api.
1113+
// See https://github.com/rustwasm/wasm-bindgen/issues/3587
1114+
let limits_object = map_js_sys_limits(&desc.limits);
1115+
1116+
js_sys::Reflect::set(
1117+
&mapped_desc,
1118+
&JsValue::from("requiredLimits"),
1119+
&limits_object,
1120+
)
1121+
.expect("Setting Object properties should never fail.");
1122+
10201123
let required_features = FEATURES_MAPPING
10211124
.iter()
10221125
.copied()
@@ -1070,30 +1173,7 @@ impl crate::context::Context for Context {
10701173
_adapter: &Self::AdapterId,
10711174
adapter_data: &Self::AdapterData,
10721175
) -> wgt::Limits {
1073-
let limits = adapter_data.0.limits();
1074-
wgt::Limits {
1075-
max_texture_dimension_1d: limits.max_texture_dimension_1d(),
1076-
max_texture_dimension_2d: limits.max_texture_dimension_2d(),
1077-
max_texture_dimension_3d: limits.max_texture_dimension_3d(),
1078-
max_texture_array_layers: limits.max_texture_array_layers(),
1079-
max_bind_groups: limits.max_bind_groups(),
1080-
max_bindings_per_bind_group: limits.max_bindings_per_bind_group(),
1081-
max_dynamic_uniform_buffers_per_pipeline_layout: limits
1082-
.max_dynamic_uniform_buffers_per_pipeline_layout(),
1083-
max_dynamic_storage_buffers_per_pipeline_layout: limits
1084-
.max_dynamic_storage_buffers_per_pipeline_layout(),
1085-
max_sampled_textures_per_shader_stage: limits.max_sampled_textures_per_shader_stage(),
1086-
max_samplers_per_shader_stage: limits.max_samplers_per_shader_stage(),
1087-
max_storage_buffers_per_shader_stage: limits.max_storage_buffers_per_shader_stage(),
1088-
max_storage_textures_per_shader_stage: limits.max_storage_textures_per_shader_stage(),
1089-
max_uniform_buffers_per_shader_stage: limits.max_uniform_buffers_per_shader_stage(),
1090-
max_uniform_buffer_binding_size: limits.max_uniform_buffer_binding_size() as u32,
1091-
max_storage_buffer_binding_size: limits.max_storage_buffer_binding_size() as u32,
1092-
max_vertex_buffers: limits.max_vertex_buffers(),
1093-
max_vertex_attributes: limits.max_vertex_attributes(),
1094-
max_vertex_buffer_array_stride: limits.max_vertex_buffer_array_stride(),
1095-
..wgt::Limits::default()
1096-
}
1176+
map_wgt_limits(adapter_data.0.limits())
10971177
}
10981178

10991179
fn adapter_downlevel_capabilities(
@@ -1256,10 +1336,9 @@ impl crate::context::Context for Context {
12561336
fn device_limits(
12571337
&self,
12581338
_device: &Self::DeviceId,
1259-
_device_data: &Self::DeviceData,
1339+
device_data: &Self::DeviceData,
12601340
) -> wgt::Limits {
1261-
// TODO
1262-
wgt::Limits::default()
1341+
map_wgt_limits(device_data.0.limits())
12631342
}
12641343

12651344
fn device_downlevel_properties(

0 commit comments

Comments
 (0)