use dom_struct::dom_struct;
use webgpu::{WebGPU, WebGPUComputePass, WebGPURequest};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUComputePassEncoderMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpucomputepipeline::GPUComputePipeline;
#[dom_struct]
pub struct GPUComputePassEncoder {
reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU,
label: DomRefCell<USVString>,
#[no_trace]
compute_pass: WebGPUComputePass,
command_encoder: Dom<GPUCommandEncoder>,
}
impl GPUComputePassEncoder {
fn new_inherited(
channel: WebGPU,
parent: &GPUCommandEncoder,
compute_pass: WebGPUComputePass,
label: USVString,
) -> Self {
Self {
channel,
reflector_: Reflector::new(),
label: DomRefCell::new(label),
compute_pass,
command_encoder: Dom::from_ref(parent),
}
}
pub fn new(
global: &GlobalScope,
channel: WebGPU,
parent: &GPUCommandEncoder,
compute_pass: WebGPUComputePass,
label: USVString,
) -> DomRoot<Self> {
reflect_dom_object(
Box::new(GPUComputePassEncoder::new_inherited(
channel,
parent,
compute_pass,
label,
)),
global,
)
}
}
impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
fn Label(&self) -> USVString {
self.label.borrow().clone()
}
fn SetLabel(&self, value: USVString) {
*self.label.borrow_mut() = value;
}
fn DispatchWorkgroups(&self, x: u32, y: u32, z: u32) {
if let Err(e) = self
.channel
.0
.send(WebGPURequest::ComputePassDispatchWorkgroups {
compute_pass_id: self.compute_pass.0,
x,
y,
z,
device_id: self.command_encoder.device_id().0,
})
{
warn!("Error sending WebGPURequest::ComputePassDispatchWorkgroups: {e:?}")
}
}
fn DispatchWorkgroupsIndirect(&self, buffer: &GPUBuffer, offset: u64) {
if let Err(e) = self
.channel
.0
.send(WebGPURequest::ComputePassDispatchWorkgroupsIndirect {
compute_pass_id: self.compute_pass.0,
buffer_id: buffer.id().0,
offset,
device_id: self.command_encoder.device_id().0,
})
{
warn!("Error sending WebGPURequest::ComputePassDispatchWorkgroupsIndirect: {e:?}")
}
}
fn End(&self) {
if let Err(e) = self.channel.0.send(WebGPURequest::EndComputePass {
compute_pass_id: self.compute_pass.0,
device_id: self.command_encoder.device_id().0,
command_encoder_id: self.command_encoder.id().0,
}) {
warn!("Failed to send WebGPURequest::EndComputePass: {e:?}");
}
}
fn SetBindGroup(&self, index: u32, bind_group: &GPUBindGroup, offsets: Vec<u32>) {
if let Err(e) = self.channel.0.send(WebGPURequest::ComputePassSetBindGroup {
compute_pass_id: self.compute_pass.0,
index,
bind_group_id: bind_group.id().0,
offsets,
device_id: self.command_encoder.device_id().0,
}) {
warn!("Error sending WebGPURequest::ComputePassSetBindGroup: {e:?}")
}
}
fn SetPipeline(&self, pipeline: &GPUComputePipeline) {
if let Err(e) = self.channel.0.send(WebGPURequest::ComputePassSetPipeline {
compute_pass_id: self.compute_pass.0,
pipeline_id: pipeline.id().0,
device_id: self.command_encoder.device_id().0,
}) {
warn!("Error sending WebGPURequest::ComputePassSetPipeline: {e:?}")
}
}
}
impl Drop for GPUComputePassEncoder {
fn drop(&mut self) {
if let Err(e) = self
.channel
.0
.send(WebGPURequest::DropComputePass(self.compute_pass.0))
{
warn!("Failed to send WebGPURequest::DropComputePass with {e:?}");
}
}
}