Add support for pipeline-overridable constants in web backend (#5688)

* Add support for pipeline-overridable constants in WebGPU

* Add utility function for setting constants map

* Panic on failure to set constants map

---------

Co-authored-by: Andreas Reich <r_andreas2@web.de>
This commit is contained in:
Douglas Dwyer 2024-05-29 15:33:04 -04:00 committed by GitHub
parent 23307e1dc3
commit 071fb14e15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 0 deletions

View File

@ -111,6 +111,10 @@ By @stefnotch in [#5410](https://github.com/gfx-rs/wgpu/pull/5410)
- Replace `glClear` with `glClearBufferF` because `glDrawBuffers` requires that the ith buffer must be `COLOR_ATTACHMENTi` or `NONE` [#5666](https://github.com/gfx-rs/wgpu/pull/5666)
- Return the unmodified version in driver_info. By @Valaphee in [#5753](https://github.com/gfx-rs/wgpu/pull/5753)
#### WebGPU
- Added support for pipeline-overridable constants to the WebGPU backend by @DouglasDwyer in [#5688](https://github.com/gfx-rs/wgpu/pull/5688)
## v0.20.0 (2024-04-28)
### Major Changes

View File

@ -7,6 +7,7 @@ use js_sys::Promise;
use std::{
any::Any,
cell::RefCell,
collections::HashMap,
fmt,
future::Future,
marker::PhantomData,
@ -1876,6 +1877,10 @@ impl crate::context::Context for ContextWebGpu {
let module: &<ContextWebGpu as crate::Context>::ShaderModuleData =
downcast_ref(desc.vertex.module.data.as_ref());
let mut mapped_vertex_state = webgpu_sys::GpuVertexState::new(&module.0.module);
insert_constants_map(
&mapped_vertex_state,
desc.vertex.compilation_options.constants,
);
mapped_vertex_state.entry_point(desc.vertex.entry_point);
let buffers = desc
@ -1952,6 +1957,7 @@ impl crate::context::Context for ContextWebGpu {
downcast_ref(frag.module.data.as_ref());
let mut mapped_fragment_desc =
webgpu_sys::GpuFragmentState::new(&module.0.module, &targets);
insert_constants_map(&mapped_vertex_state, frag.compilation_options.constants);
mapped_fragment_desc.entry_point(frag.entry_point);
mapped_desc.fragment(&mapped_fragment_desc);
}
@ -1978,6 +1984,7 @@ impl crate::context::Context for ContextWebGpu {
downcast_ref(desc.module.data.as_ref());
let mut mapped_compute_stage =
webgpu_sys::GpuProgrammableStage::new(&shader_module.0.module);
insert_constants_map(&mapped_compute_stage, desc.compilation_options.constants);
mapped_compute_stage.entry_point(desc.entry_point);
let auto_layout = wasm_bindgen::JsValue::from(webgpu_sys::GpuAutoLayoutMode::Auto);
let mut mapped_desc = webgpu_sys::GpuComputePipelineDescriptor::new(
@ -1994,6 +2001,7 @@ impl crate::context::Context for ContextWebGpu {
if let Some(label) = desc.label {
mapped_desc.label(label);
}
create_identified(device_data.0.create_compute_pipeline(&mapped_desc))
}
@ -3824,3 +3832,29 @@ impl Drop for BufferMappedRange {
}
}
}
/// Adds the constants map to the given pipeline descriptor if the map is nonempty.
/// Panics if the map cannot be set.
///
/// This function is necessary because the constants array is not currently
/// exposed by `wasm-bindgen`. See the following issues for details:
/// - [gfx-rs/wgpu#5688](https://github.com/gfx-rs/wgpu/pull/5688)
/// - [rustwasm/wasm-bindgen#3587](https://github.com/rustwasm/wasm-bindgen/issues/3587)
fn insert_constants_map(target: &JsValue, map: &HashMap<String, f64>) {
if !map.is_empty() {
js_sys::Reflect::set(target, &"constants".into(), &hashmap_to_jsvalue(map))
.expect("Setting the values in a Javascript pipeline descriptor should never fail");
}
}
/// Converts a hashmap to a Javascript object.
fn hashmap_to_jsvalue(map: &HashMap<String, f64>) -> JsValue {
let obj = js_sys::Object::new();
for (k, v) in map.iter() {
js_sys::Reflect::set(&obj, &k.into(), &(*v).into())
.expect("Setting the values in a Javascript map should never fail");
}
JsValue::from(obj)
}