script/dom/webgpu/
gpucomputepassencoder.rs1use 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#[derive(JSTraceable, MallocSizeOf)]
21struct DroppableGPUComputePassEncoder {
22 #[no_trace]
23 channel: WebGPU,
24 #[no_trace]
25 compute_pass: WebGPUComputePass,
26}
27
28impl Drop for DroppableGPUComputePassEncoder {
29 fn drop(&mut self) {
30 if let Err(e) = self
31 .channel
32 .0
33 .send(WebGPURequest::DropComputePass(self.compute_pass.0))
34 {
35 warn!("Failed to send WebGPURequest::DropComputePass with {e:?}");
36 }
37 }
38}
39
40#[dom_struct]
41pub(crate) struct GPUComputePassEncoder {
42 reflector_: Reflector,
43 label: DomRefCell<USVString>,
44 command_encoder: Dom<GPUCommandEncoder>,
45 droppable: DroppableGPUComputePassEncoder,
46}
47
48impl GPUComputePassEncoder {
49 fn new_inherited(
50 channel: WebGPU,
51 parent: &GPUCommandEncoder,
52 compute_pass: WebGPUComputePass,
53 label: USVString,
54 ) -> Self {
55 Self {
56 reflector_: Reflector::new(),
57 label: DomRefCell::new(label),
58 command_encoder: Dom::from_ref(parent),
59 droppable: DroppableGPUComputePassEncoder {
60 channel,
61 compute_pass,
62 },
63 }
64 }
65
66 pub(crate) fn new(
67 global: &GlobalScope,
68 channel: WebGPU,
69 parent: &GPUCommandEncoder,
70 compute_pass: WebGPUComputePass,
71 label: USVString,
72 can_gc: CanGc,
73 ) -> DomRoot<Self> {
74 reflect_dom_object(
75 Box::new(GPUComputePassEncoder::new_inherited(
76 channel,
77 parent,
78 compute_pass,
79 label,
80 )),
81 global,
82 can_gc,
83 )
84 }
85}
86
87impl GPUComputePassEncoderMethods<crate::DomTypeHolder> for GPUComputePassEncoder {
88 fn Label(&self) -> USVString {
90 self.label.borrow().clone()
91 }
92
93 fn SetLabel(&self, value: USVString) {
95 *self.label.borrow_mut() = value;
96 }
97
98 fn DispatchWorkgroups(&self, x: u32, y: u32, z: u32) {
100 if let Err(e) =
101 self.droppable
102 .channel
103 .0
104 .send(WebGPURequest::ComputePassDispatchWorkgroups {
105 compute_pass_id: self.droppable.compute_pass.0,
106 x,
107 y,
108 z,
109 device_id: self.command_encoder.device_id().0,
110 })
111 {
112 warn!("Error sending WebGPURequest::ComputePassDispatchWorkgroups: {e:?}")
113 }
114 }
115
116 fn DispatchWorkgroupsIndirect(&self, buffer: &GPUBuffer, offset: u64) {
118 if let Err(e) =
119 self.droppable
120 .channel
121 .0
122 .send(WebGPURequest::ComputePassDispatchWorkgroupsIndirect {
123 compute_pass_id: self.droppable.compute_pass.0,
124 buffer_id: buffer.id().0,
125 offset,
126 device_id: self.command_encoder.device_id().0,
127 })
128 {
129 warn!("Error sending WebGPURequest::ComputePassDispatchWorkgroupsIndirect: {e:?}")
130 }
131 }
132
133 fn End(&self) {
135 if let Err(e) = self
136 .droppable
137 .channel
138 .0
139 .send(WebGPURequest::EndComputePass {
140 compute_pass_id: self.droppable.compute_pass.0,
141 device_id: self.command_encoder.device_id().0,
142 command_encoder_id: self.command_encoder.id().0,
143 })
144 {
145 warn!("Failed to send WebGPURequest::EndComputePass: {e:?}");
146 }
147 }
148
149 fn SetBindGroup(&self, index: u32, bind_group: &GPUBindGroup, offsets: Vec<u32>) {
151 if let Err(e) = self
152 .droppable
153 .channel
154 .0
155 .send(WebGPURequest::ComputePassSetBindGroup {
156 compute_pass_id: self.droppable.compute_pass.0,
157 index,
158 bind_group_id: bind_group.id().0,
159 offsets,
160 device_id: self.command_encoder.device_id().0,
161 })
162 {
163 warn!("Error sending WebGPURequest::ComputePassSetBindGroup: {e:?}")
164 }
165 }
166
167 fn SetPipeline(&self, pipeline: &GPUComputePipeline) {
169 if let Err(e) = self
170 .droppable
171 .channel
172 .0
173 .send(WebGPURequest::ComputePassSetPipeline {
174 compute_pass_id: self.droppable.compute_pass.0,
175 pipeline_id: pipeline.id().0,
176 device_id: self.command_encoder.device_id().0,
177 })
178 {
179 warn!("Error sending WebGPURequest::ComputePassSetPipeline: {e:?}")
180 }
181 }
182}