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 #[no_trace]
27 channel: WebGPU,
28 label: DomRefCell<USVString>,
29 #[no_trace]
30 pipeline_layout: WebGPUPipelineLayout,
31 #[no_trace]
32 bind_group_layouts: Vec<WebGPUBindGroupLayout>,
33}
34
35impl GPUPipelineLayout {
36 fn new_inherited(
37 channel: WebGPU,
38 pipeline_layout: WebGPUPipelineLayout,
39 label: USVString,
40 bgls: Vec<WebGPUBindGroupLayout>,
41 ) -> Self {
42 Self {
43 reflector_: Reflector::new(),
44 channel,
45 label: DomRefCell::new(label),
46 pipeline_layout,
47 bind_group_layouts: bgls,
48 }
49 }
50
51 pub(crate) fn new(
52 global: &GlobalScope,
53 channel: WebGPU,
54 pipeline_layout: WebGPUPipelineLayout,
55 label: USVString,
56 bgls: Vec<WebGPUBindGroupLayout>,
57 can_gc: CanGc,
58 ) -> DomRoot<Self> {
59 reflect_dom_object(
60 Box::new(GPUPipelineLayout::new_inherited(
61 channel,
62 pipeline_layout,
63 label,
64 bgls,
65 )),
66 global,
67 can_gc,
68 )
69 }
70}
71
72impl GPUPipelineLayout {
73 pub(crate) fn id(&self) -> WebGPUPipelineLayout {
74 self.pipeline_layout
75 }
76
77 pub(crate) fn bind_group_layouts(&self) -> Vec<WebGPUBindGroupLayout> {
78 self.bind_group_layouts.clone()
79 }
80
81 pub(crate) fn create(
83 device: &GPUDevice,
84 descriptor: &GPUPipelineLayoutDescriptor,
85 can_gc: CanGc,
86 ) -> DomRoot<GPUPipelineLayout> {
87 let bgls = descriptor
88 .bindGroupLayouts
89 .iter()
90 .map(|each| each.id())
91 .collect::<Vec<_>>();
92
93 let desc = PipelineLayoutDescriptor {
94 label: (&descriptor.parent).convert(),
95 bind_group_layouts: Cow::Owned(bgls.iter().map(|l| l.0).collect::<Vec<_>>()),
96 push_constant_ranges: Cow::Owned(vec![]),
97 };
98
99 let pipeline_layout_id = device.global().wgpu_id_hub().create_pipeline_layout_id();
100 device
101 .channel()
102 .0
103 .send(WebGPURequest::CreatePipelineLayout {
104 device_id: device.id().0,
105 pipeline_layout_id,
106 descriptor: desc,
107 })
108 .expect("Failed to create WebGPU PipelineLayout");
109
110 let pipeline_layout = WebGPUPipelineLayout(pipeline_layout_id);
111 GPUPipelineLayout::new(
112 &device.global(),
113 device.channel().clone(),
114 pipeline_layout,
115 descriptor.parent.label.clone(),
116 bgls,
117 can_gc,
118 )
119 }
120}
121
122impl GPUPipelineLayoutMethods<crate::DomTypeHolder> for GPUPipelineLayout {
123 fn Label(&self) -> USVString {
125 self.label.borrow().clone()
126 }
127
128 fn SetLabel(&self, value: USVString) {
130 *self.label.borrow_mut() = value;
131 }
132}
133
134impl Drop for GPUPipelineLayout {
135 fn drop(&mut self) {
136 if let Err(e) = self
137 .channel
138 .0
139 .send(WebGPURequest::DropPipelineLayout(self.pipeline_layout.0))
140 {
141 warn!(
142 "Failed to send DropPipelineLayout ({:?}) ({})",
143 self.pipeline_layout.0, e
144 );
145 }
146 }
147}