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