Skip to content

Commit

Permalink
Fix limits interface on web. (gfx-rs#4107)
Browse files Browse the repository at this point in the history
  • Loading branch information
OptimisticPeach authored and bradwerth committed Sep 19, 2023
1 parent 74bbc7d commit 451dfeb
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 35 deletions.
7 changes: 0 additions & 7 deletions .cargo/config.toml

This file was deleted.

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ By @Valaphee in [#3402](https://github.com/gfx-rs/wgpu/pull/3402)

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

#### WebGPU

- Ensure that limit requests and reporting is done correctly. By @OptimisticPeach in [#4107](https://github.com/gfx-rs/wgpu/pull/4107)

### Documentation

- Add an overview of `RenderPass` and how render state works. By @kpreid in [#4055](https://github.com/gfx-rs/wgpu/pull/4055)
Expand Down
135 changes: 107 additions & 28 deletions wgpu/src/backend/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,99 @@ fn map_wgt_features(supported_features: web_sys::GpuSupportedFeatures) -> wgt::F
features
}

fn map_wgt_limits(limits: web_sys::GpuSupportedLimits) -> wgt::Limits {
wgt::Limits {
max_texture_dimension_1d: limits.max_texture_dimension_1d(),
max_texture_dimension_2d: limits.max_texture_dimension_2d(),
max_texture_dimension_3d: limits.max_texture_dimension_3d(),
max_texture_array_layers: limits.max_texture_array_layers(),
max_bind_groups: limits.max_bind_groups(),
max_bindings_per_bind_group: limits.max_bindings_per_bind_group(),
max_dynamic_uniform_buffers_per_pipeline_layout: limits
.max_dynamic_uniform_buffers_per_pipeline_layout(),
max_dynamic_storage_buffers_per_pipeline_layout: limits
.max_dynamic_storage_buffers_per_pipeline_layout(),
max_sampled_textures_per_shader_stage: limits.max_sampled_textures_per_shader_stage(),
max_samplers_per_shader_stage: limits.max_samplers_per_shader_stage(),
max_storage_buffers_per_shader_stage: limits.max_storage_buffers_per_shader_stage(),
max_storage_textures_per_shader_stage: limits.max_storage_textures_per_shader_stage(),
max_uniform_buffers_per_shader_stage: limits.max_uniform_buffers_per_shader_stage(),
max_uniform_buffer_binding_size: limits.max_uniform_buffer_binding_size() as u32,
max_storage_buffer_binding_size: limits.max_storage_buffer_binding_size() as u32,
max_vertex_buffers: limits.max_vertex_buffers(),
max_buffer_size: limits.max_buffer_size() as u64,
max_vertex_attributes: limits.max_vertex_attributes(),
max_vertex_buffer_array_stride: limits.max_vertex_buffer_array_stride(),
min_uniform_buffer_offset_alignment: limits.min_uniform_buffer_offset_alignment(),
min_storage_buffer_offset_alignment: limits.min_storage_buffer_offset_alignment(),
max_inter_stage_shader_components: limits.max_inter_stage_shader_components(),
max_compute_workgroup_storage_size: limits.max_compute_workgroup_storage_size(),
max_compute_invocations_per_workgroup: limits.max_compute_invocations_per_workgroup(),
max_compute_workgroup_size_x: limits.max_compute_workgroup_size_x(),
max_compute_workgroup_size_y: limits.max_compute_workgroup_size_y(),
max_compute_workgroup_size_z: limits.max_compute_workgroup_size_z(),
max_compute_workgroups_per_dimension: limits.max_compute_workgroups_per_dimension(),
// The following are not part of WebGPU
max_push_constant_size: wgt::Limits::default().max_push_constant_size,
max_non_sampler_bindings: wgt::Limits::default().max_non_sampler_bindings,
}
}

fn map_js_sys_limits(limits: &wgt::Limits) -> js_sys::Object {
let object = js_sys::Object::new();

macro_rules! set_properties {
(($from:expr) => ($on:expr) : $(($js_ident:ident, $rs_ident:ident)),* $(,)?) => {
$(
::js_sys::Reflect::set(
&$on,
&::wasm_bindgen::JsValue::from(stringify!($js_ident)),
// Numbers may be u64, however using `from` on a u64 yields
// errors on the wasm side, since it uses an unsupported api.
// Wasm sends us things that need to fit into u64s by sending
// us f64s instead. So we just send them f64s back.
&::wasm_bindgen::JsValue::from($from.$rs_ident as f64)
)
.expect("Setting Object properties should never fail.");
)*
}
}

set_properties![
(limits) => (object):
(maxTextureDimension1D, max_texture_dimension_1d),
(maxTextureDimension2D, max_texture_dimension_2d),
(maxTextureDimension3D, max_texture_dimension_3d),
(maxTextureArrayLayers, max_texture_array_layers),
(maxBindGroups, max_bind_groups),
(maxBindingsPerBindGroup, max_bindings_per_bind_group),
(maxDynamicUniformBuffersPerPipelineLayout, max_dynamic_uniform_buffers_per_pipeline_layout),
(maxDynamicStorageBuffersPerPipelineLayout, max_dynamic_storage_buffers_per_pipeline_layout),
(maxSampledTexturesPerShaderStage, max_sampled_textures_per_shader_stage),
(maxSamplersPerShaderStage, max_samplers_per_shader_stage),
(maxStorageBuffersPerShaderStage, max_storage_buffers_per_shader_stage),
(maxStorageTexturesPerShaderStage, max_storage_textures_per_shader_stage),
(maxUniformBuffersPerShaderStage, max_uniform_buffers_per_shader_stage),
(maxUniformBufferBindingSize, max_uniform_buffer_binding_size),
(maxStorageBufferBindingSize, max_storage_buffer_binding_size),
(minUniformBufferOffsetAlignment, min_uniform_buffer_offset_alignment),
(minStorageBufferOffsetAlignment, min_storage_buffer_offset_alignment),
(maxVertexBuffers, max_vertex_buffers),
(maxBufferSize, max_buffer_size),
(maxVertexAttributes, max_vertex_attributes),
(maxVertexBufferArrayStride, max_vertex_buffer_array_stride),
(maxInterStageShaderComponents, max_inter_stage_shader_components),
(maxComputeWorkgroupStorageSize, max_compute_workgroup_storage_size),
(maxComputeInvocationsPerWorkgroup, max_compute_invocations_per_workgroup),
(maxComputeWorkgroupSizeX, max_compute_workgroup_size_x),
(maxComputeWorkgroupSizeY, max_compute_workgroup_size_y),
(maxComputeWorkgroupSizeZ, max_compute_workgroup_size_z),
(maxComputeWorkgroupsPerDimension, max_compute_workgroups_per_dimension),
];

object
}

type JsFutureResult = Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>;

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

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

// TODO: Migrate to a web_sys api.
// See https://github.com/rustwasm/wasm-bindgen/issues/3587
let limits_object = map_js_sys_limits(&desc.limits);

js_sys::Reflect::set(
&mapped_desc,
&JsValue::from("requiredLimits"),
&limits_object,
)
.expect("Setting Object properties should never fail.");

let required_features = FEATURES_MAPPING
.iter()
.copied()
Expand Down Expand Up @@ -1070,30 +1173,7 @@ impl crate::context::Context for Context {
_adapter: &Self::AdapterId,
adapter_data: &Self::AdapterData,
) -> wgt::Limits {
let limits = adapter_data.0.limits();
wgt::Limits {
max_texture_dimension_1d: limits.max_texture_dimension_1d(),
max_texture_dimension_2d: limits.max_texture_dimension_2d(),
max_texture_dimension_3d: limits.max_texture_dimension_3d(),
max_texture_array_layers: limits.max_texture_array_layers(),
max_bind_groups: limits.max_bind_groups(),
max_bindings_per_bind_group: limits.max_bindings_per_bind_group(),
max_dynamic_uniform_buffers_per_pipeline_layout: limits
.max_dynamic_uniform_buffers_per_pipeline_layout(),
max_dynamic_storage_buffers_per_pipeline_layout: limits
.max_dynamic_storage_buffers_per_pipeline_layout(),
max_sampled_textures_per_shader_stage: limits.max_sampled_textures_per_shader_stage(),
max_samplers_per_shader_stage: limits.max_samplers_per_shader_stage(),
max_storage_buffers_per_shader_stage: limits.max_storage_buffers_per_shader_stage(),
max_storage_textures_per_shader_stage: limits.max_storage_textures_per_shader_stage(),
max_uniform_buffers_per_shader_stage: limits.max_uniform_buffers_per_shader_stage(),
max_uniform_buffer_binding_size: limits.max_uniform_buffer_binding_size() as u32,
max_storage_buffer_binding_size: limits.max_storage_buffer_binding_size() as u32,
max_vertex_buffers: limits.max_vertex_buffers(),
max_vertex_attributes: limits.max_vertex_attributes(),
max_vertex_buffer_array_stride: limits.max_vertex_buffer_array_stride(),
..wgt::Limits::default()
}
map_wgt_limits(adapter_data.0.limits())
}

fn adapter_downlevel_capabilities(
Expand Down Expand Up @@ -1256,10 +1336,9 @@ impl crate::context::Context for Context {
fn device_limits(
&self,
_device: &Self::DeviceId,
_device_data: &Self::DeviceData,
device_data: &Self::DeviceData,
) -> wgt::Limits {
// TODO
wgt::Limits::default()
map_wgt_limits(device_data.0.limits())
}

fn device_downlevel_properties(
Expand Down

0 comments on commit 451dfeb

Please sign in to comment.