script/dom/webgpu/
gpubindgrouplayout.rs1use std::borrow::Cow;
6
7use dom_struct::dom_struct;
8use webgpu_traits::{WebGPU, WebGPUBindGroupLayout, WebGPURequest};
9use wgpu_core::binding_model::BindGroupLayoutDescriptor;
10
11use crate::conversions::Convert;
12use crate::dom::bindings::cell::DomRefCell;
13use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
14 GPUBindGroupLayoutDescriptor, GPUBindGroupLayoutMethods,
15};
16use crate::dom::bindings::error::Fallible;
17use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
18use crate::dom::bindings::root::DomRoot;
19use crate::dom::bindings::str::USVString;
20use crate::dom::globalscope::GlobalScope;
21use crate::dom::webgpu::gpuconvert::convert_bind_group_layout_entry;
22use crate::dom::webgpu::gpudevice::GPUDevice;
23use crate::script_runtime::CanGc;
24
25#[dom_struct]
26pub(crate) struct GPUBindGroupLayout {
27 reflector_: Reflector,
28 #[ignore_malloc_size_of = "channels are hard"]
29 #[no_trace]
30 channel: WebGPU,
31 label: DomRefCell<USVString>,
32 #[no_trace]
33 bind_group_layout: WebGPUBindGroupLayout,
34}
35
36impl GPUBindGroupLayout {
37 fn new_inherited(
38 channel: WebGPU,
39 bind_group_layout: WebGPUBindGroupLayout,
40 label: USVString,
41 ) -> Self {
42 Self {
43 reflector_: Reflector::new(),
44 channel,
45 label: DomRefCell::new(label),
46 bind_group_layout,
47 }
48 }
49
50 pub(crate) fn new(
51 global: &GlobalScope,
52 channel: WebGPU,
53 bind_group_layout: WebGPUBindGroupLayout,
54 label: USVString,
55 can_gc: CanGc,
56 ) -> DomRoot<Self> {
57 reflect_dom_object(
58 Box::new(GPUBindGroupLayout::new_inherited(
59 channel,
60 bind_group_layout,
61 label,
62 )),
63 global,
64 can_gc,
65 )
66 }
67}
68
69impl GPUBindGroupLayout {
70 pub(crate) fn id(&self) -> WebGPUBindGroupLayout {
71 self.bind_group_layout
72 }
73
74 pub(crate) fn create(
76 device: &GPUDevice,
77 descriptor: &GPUBindGroupLayoutDescriptor,
78 can_gc: CanGc,
79 ) -> Fallible<DomRoot<GPUBindGroupLayout>> {
80 let entries = descriptor
81 .entries
82 .iter()
83 .map(|bgle| convert_bind_group_layout_entry(bgle, device))
84 .collect::<Fallible<Result<Vec<_>, _>>>()?;
85
86 let desc = match entries {
87 Ok(entries) => Some(BindGroupLayoutDescriptor {
88 label: (&descriptor.parent).convert(),
89 entries: Cow::Owned(entries),
90 }),
91 Err(error) => {
92 device.dispatch_error(error);
93 None
94 },
95 };
96
97 let bind_group_layout_id = device.global().wgpu_id_hub().create_bind_group_layout_id();
98 device
99 .channel()
100 .0
101 .send(WebGPURequest::CreateBindGroupLayout {
102 device_id: device.id().0,
103 bind_group_layout_id,
104 descriptor: desc,
105 })
106 .expect("Failed to create WebGPU BindGroupLayout");
107
108 let bgl = WebGPUBindGroupLayout(bind_group_layout_id);
109
110 Ok(GPUBindGroupLayout::new(
111 &device.global(),
112 device.channel().clone(),
113 bgl,
114 descriptor.parent.label.clone(),
115 can_gc,
116 ))
117 }
118}
119
120impl Drop for GPUBindGroupLayout {
121 fn drop(&mut self) {
122 if let Err(e) = self
123 .channel
124 .0
125 .send(WebGPURequest::DropBindGroupLayout(self.bind_group_layout.0))
126 {
127 warn!(
128 "Failed to send WebGPURequest::DropBindGroupLayout({:?}) ({})",
129 self.bind_group_layout.0, e
130 );
131 };
132 }
133}
134
135impl GPUBindGroupLayoutMethods<crate::DomTypeHolder> for GPUBindGroupLayout {
136 fn Label(&self) -> USVString {
138 self.label.borrow().clone()
139 }
140
141 fn SetLabel(&self, value: USVString) {
143 *self.label.borrow_mut() = value;
144 }
145}