Skip to content

Commit 071fb14

Browse files
DouglasDwyerWumpf
andauthored
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 <[email protected]>
1 parent 23307e1 commit 071fb14

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ By @stefnotch in [#5410](https://github.com/gfx-rs/wgpu/pull/5410)
111111
- 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)
112112
- Return the unmodified version in driver_info. By @Valaphee in [#5753](https://github.com/gfx-rs/wgpu/pull/5753)
113113

114+
#### WebGPU
115+
116+
- Added support for pipeline-overridable constants to the WebGPU backend by @DouglasDwyer in [#5688](https://github.com/gfx-rs/wgpu/pull/5688)
117+
114118
## v0.20.0 (2024-04-28)
115119

116120
### Major Changes

wgpu/src/backend/webgpu.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use js_sys::Promise;
77
use std::{
88
any::Any,
99
cell::RefCell,
10+
collections::HashMap,
1011
fmt,
1112
future::Future,
1213
marker::PhantomData,
@@ -1876,6 +1877,10 @@ impl crate::context::Context for ContextWebGpu {
18761877
let module: &<ContextWebGpu as crate::Context>::ShaderModuleData =
18771878
downcast_ref(desc.vertex.module.data.as_ref());
18781879
let mut mapped_vertex_state = webgpu_sys::GpuVertexState::new(&module.0.module);
1880+
insert_constants_map(
1881+
&mapped_vertex_state,
1882+
desc.vertex.compilation_options.constants,
1883+
);
18791884
mapped_vertex_state.entry_point(desc.vertex.entry_point);
18801885

18811886
let buffers = desc
@@ -1952,6 +1957,7 @@ impl crate::context::Context for ContextWebGpu {
19521957
downcast_ref(frag.module.data.as_ref());
19531958
let mut mapped_fragment_desc =
19541959
webgpu_sys::GpuFragmentState::new(&module.0.module, &targets);
1960+
insert_constants_map(&mapped_vertex_state, frag.compilation_options.constants);
19551961
mapped_fragment_desc.entry_point(frag.entry_point);
19561962
mapped_desc.fragment(&mapped_fragment_desc);
19571963
}
@@ -1978,6 +1984,7 @@ impl crate::context::Context for ContextWebGpu {
19781984
downcast_ref(desc.module.data.as_ref());
19791985
let mut mapped_compute_stage =
19801986
webgpu_sys::GpuProgrammableStage::new(&shader_module.0.module);
1987+
insert_constants_map(&mapped_compute_stage, desc.compilation_options.constants);
19811988
mapped_compute_stage.entry_point(desc.entry_point);
19821989
let auto_layout = wasm_bindgen::JsValue::from(webgpu_sys::GpuAutoLayoutMode::Auto);
19831990
let mut mapped_desc = webgpu_sys::GpuComputePipelineDescriptor::new(
@@ -1994,6 +2001,7 @@ impl crate::context::Context for ContextWebGpu {
19942001
if let Some(label) = desc.label {
19952002
mapped_desc.label(label);
19962003
}
2004+
19972005
create_identified(device_data.0.create_compute_pipeline(&mapped_desc))
19982006
}
19992007

@@ -3824,3 +3832,29 @@ impl Drop for BufferMappedRange {
38243832
}
38253833
}
38263834
}
3835+
3836+
/// Adds the constants map to the given pipeline descriptor if the map is nonempty.
3837+
/// Panics if the map cannot be set.
3838+
///
3839+
/// This function is necessary because the constants array is not currently
3840+
/// exposed by `wasm-bindgen`. See the following issues for details:
3841+
/// - [gfx-rs/wgpu#5688](https://github.com/gfx-rs/wgpu/pull/5688)
3842+
/// - [rustwasm/wasm-bindgen#3587](https://github.com/rustwasm/wasm-bindgen/issues/3587)
3843+
fn insert_constants_map(target: &JsValue, map: &HashMap<String, f64>) {
3844+
if !map.is_empty() {
3845+
js_sys::Reflect::set(target, &"constants".into(), &hashmap_to_jsvalue(map))
3846+
.expect("Setting the values in a Javascript pipeline descriptor should never fail");
3847+
}
3848+
}
3849+
3850+
/// Converts a hashmap to a Javascript object.
3851+
fn hashmap_to_jsvalue(map: &HashMap<String, f64>) -> JsValue {
3852+
let obj = js_sys::Object::new();
3853+
3854+
for (k, v) in map.iter() {
3855+
js_sys::Reflect::set(&obj, &k.into(), &(*v).into())
3856+
.expect("Setting the values in a Javascript map should never fail");
3857+
}
3858+
3859+
JsValue::from(obj)
3860+
}

0 commit comments

Comments
 (0)