script/dom/webgpu/
gpucomputepassencoder.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6use webgpu_traits::{WebGPU, WebGPUComputePass, WebGPURequest};
7
8use crate::dom::bindings::cell::DomRefCell;
9use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUComputePassEncoderMethods;
10use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
11use crate::dom::bindings::root::{Dom, DomRoot};
12use crate::dom::bindings::str::USVString;
13use crate::dom::globalscope::GlobalScope;
14use crate::dom::webgpu::gpubindgroup::GPUBindGroup;
15use crate::dom::webgpu::gpubuffer::GPUBuffer;
16use crate::dom::webgpu::gpucommandencoder::GPUCommandEncoder;
17use crate::dom::webgpu::gpucomputepipeline::GPUComputePipeline;
18use crate::script_runtime::CanGc;
19
20#[dom_struct]
21pub(crate) struct GPUComputePassEncoder {
22    reflector_: Reflector,
23    #[ignore_malloc_size_of = "defined in webgpu"]
24    #[no_trace]
25    channel: WebGPU,
26    label: DomRefCell<USVString>,
27    #[no_trace]
28    compute_pass: WebGPUComputePass,
29    command_encoder: Dom<GPUCommandEncoder>,
30}
31
32impl GPUComputePassEncoder {
33    fn new_inherited(
34        channel: WebGPU,
35        parent: &GPUCommandEncoder,
36        compute_pass: WebGPUComputePass,
37        label: USVString,
38    ) -> Self {
39        Self {
40            channel,
41            reflector_: Reflector::new(),
42            label: DomRefCell::new(label),
43            compute_pass,
44            command_encoder: Dom::from_ref(parent),
45        }
46    }
47
48    pub(crate) fn new(
49        global: &GlobalScope,
50        channel: WebGPU,
51        parent: &GPUCommandEncoder,
52        compute_pass: WebGPUComputePass,
53        label: USVString,
54        can_gc: CanGc,
55    ) -> DomRoot<Self> {
56        reflect_dom_object(
57            Box::new(GPUComputePassEncoder::new_inherited(
58                channel,
59                parent,
60                compute_pass,
61                label,
62            )),
63            global,
64            can_gc,
65        )
66    }
67}
68
69impl GPUComputePassEncoderMethods<crate::DomTypeHolder> for GPUComputePassEncoder {
70    /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
71    fn Label(&self) -> USVString {
72        self.label.borrow().clone()
73    }
74
75    /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
76    fn SetLabel(&self, value: USVString) {
77        *self.label.borrow_mut() = value;
78    }
79
80    /// <https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-dispatchworkgroups>
81    fn DispatchWorkgroups(&self, x: u32, y: u32, z: u32) {
82        if let Err(e) = self
83            .channel
84            .0
85            .send(WebGPURequest::ComputePassDispatchWorkgroups {
86                compute_pass_id: self.compute_pass.0,
87                x,
88                y,
89                z,
90                device_id: self.command_encoder.device_id().0,
91            })
92        {
93            warn!("Error sending WebGPURequest::ComputePassDispatchWorkgroups: {e:?}")
94        }
95    }
96
97    /// <https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-dispatchworkgroupsindirect>
98    fn DispatchWorkgroupsIndirect(&self, buffer: &GPUBuffer, offset: u64) {
99        if let Err(e) = self
100            .channel
101            .0
102            .send(WebGPURequest::ComputePassDispatchWorkgroupsIndirect {
103                compute_pass_id: self.compute_pass.0,
104                buffer_id: buffer.id().0,
105                offset,
106                device_id: self.command_encoder.device_id().0,
107            })
108        {
109            warn!("Error sending WebGPURequest::ComputePassDispatchWorkgroupsIndirect: {e:?}")
110        }
111    }
112
113    /// <https://gpuweb.github.io/gpuweb/#dom-gpurenderpassencoder-endpass>
114    fn End(&self) {
115        if let Err(e) = self.channel.0.send(WebGPURequest::EndComputePass {
116            compute_pass_id: self.compute_pass.0,
117            device_id: self.command_encoder.device_id().0,
118            command_encoder_id: self.command_encoder.id().0,
119        }) {
120            warn!("Failed to send WebGPURequest::EndComputePass: {e:?}");
121        }
122    }
123
124    /// <https://gpuweb.github.io/gpuweb/#dom-gpuprogrammablepassencoder-setbindgroup>
125    fn SetBindGroup(&self, index: u32, bind_group: &GPUBindGroup, offsets: Vec<u32>) {
126        if let Err(e) = self.channel.0.send(WebGPURequest::ComputePassSetBindGroup {
127            compute_pass_id: self.compute_pass.0,
128            index,
129            bind_group_id: bind_group.id().0,
130            offsets,
131            device_id: self.command_encoder.device_id().0,
132        }) {
133            warn!("Error sending WebGPURequest::ComputePassSetBindGroup: {e:?}")
134        }
135    }
136
137    /// <https://gpuweb.github.io/gpuweb/#dom-gpucomputepassencoder-setpipeline>
138    fn SetPipeline(&self, pipeline: &GPUComputePipeline) {
139        if let Err(e) = self.channel.0.send(WebGPURequest::ComputePassSetPipeline {
140            compute_pass_id: self.compute_pass.0,
141            pipeline_id: pipeline.id().0,
142            device_id: self.command_encoder.device_id().0,
143        }) {
144            warn!("Error sending WebGPURequest::ComputePassSetPipeline: {e:?}")
145        }
146    }
147}
148
149impl Drop for GPUComputePassEncoder {
150    fn drop(&mut self) {
151        if let Err(e) = self
152            .channel
153            .0
154            .send(WebGPURequest::DropComputePass(self.compute_pass.0))
155        {
156            warn!("Failed to send WebGPURequest::DropComputePass with {e:?}");
157        }
158    }
159}