Skip to main content

dawn_rs/generated/
structs.rs

1#![allow(dead_code, unused_imports)]
2use crate::ffi;
3use super::*;
4use std::any::Any;
5use std::ffi::CStr;
6fn string_view_to_string(view: ffi::WGPUStringView) -> String {
7    if view.data.is_null() || view.length == 0 {
8        return String::new();
9    }
10    let data = view.data.cast::<u8>();
11    let slice = unsafe { std::slice::from_raw_parts(data, view.length) };
12    String::from_utf8_lossy(slice).into_owned()
13}
14pub struct InternalHaveEmdawnwebgpuHeader {
15    pub unused: Option<bool>,
16}
17impl Default for InternalHaveEmdawnwebgpuHeader {
18    fn default() -> Self {
19        Self { unused: None }
20    }
21}
22impl InternalHaveEmdawnwebgpuHeader {
23    pub fn new() -> Self {
24        Self::default()
25    }
26    pub(crate) fn to_ffi(
27        &self,
28    ) -> (ffi::WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER, ChainedStructStorage) {
29        let mut storage = ChainedStructStorage::new();
30        let mut raw: ffi::WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER = unsafe {
31            std::mem::zeroed()
32        };
33        raw.unused = if self.unused.unwrap_or(false) { 1 } else { 0 };
34        (raw, storage)
35    }
36    pub(crate) fn from_ffi(value: ffi::WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER) -> Self {
37        Self {
38            unused: Some(value.unused != 0),
39        }
40    }
41}
42pub struct AHardwareBufferProperties {
43    pub y_cb_cr_info: Option<YCbCrVkDescriptor>,
44}
45impl Default for AHardwareBufferProperties {
46    fn default() -> Self {
47        Self { y_cb_cr_info: None }
48    }
49}
50impl AHardwareBufferProperties {
51    pub fn new() -> Self {
52        Self::default()
53    }
54    pub(crate) fn to_ffi(
55        &self,
56    ) -> (ffi::WGPUAHardwareBufferProperties, ChainedStructStorage) {
57        let mut storage = ChainedStructStorage::new();
58        let mut raw: ffi::WGPUAHardwareBufferProperties = unsafe { std::mem::zeroed() };
59        if let Some(value) = &self.y_cb_cr_info {
60            let (raw_value, storage_value) = value.to_ffi();
61            raw.yCbCrInfo = raw_value;
62            storage.push_storage(storage_value);
63        }
64        (raw, storage)
65    }
66    pub(crate) fn from_ffi(value: ffi::WGPUAHardwareBufferProperties) -> Self {
67        Self {
68            y_cb_cr_info: Some(YCbCrVkDescriptor::from_ffi(value.yCbCrInfo)),
69        }
70    }
71}
72pub struct AdapterInfo {
73    pub(crate) extensions: Vec<AdapterInfoExtension>,
74    pub vendor: Option<String>,
75    pub architecture: Option<String>,
76    pub device: Option<String>,
77    pub description: Option<String>,
78    pub backend_type: Option<BackendType>,
79    pub adapter_type: Option<AdapterType>,
80    pub vendor_id: Option<u32>,
81    pub device_id: Option<u32>,
82    pub subgroup_min_size: Option<u32>,
83    pub subgroup_max_size: Option<u32>,
84    #[doc(hidden)]
85    pub(crate) _free_members: Option<ffi::WGPUAdapterInfo>,
86}
87impl Default for AdapterInfo {
88    fn default() -> Self {
89        Self {
90            extensions: Vec::new(),
91            vendor: None,
92            architecture: None,
93            device: None,
94            description: None,
95            backend_type: None,
96            adapter_type: None,
97            vendor_id: None,
98            device_id: None,
99            subgroup_min_size: None,
100            subgroup_max_size: None,
101            _free_members: None,
102        }
103    }
104}
105impl AdapterInfo {
106    pub fn new() -> Self {
107        Self::default()
108    }
109    pub(crate) fn to_ffi(&self) -> (ffi::WGPUAdapterInfo, ChainedStructStorage) {
110        let mut storage = ChainedStructStorage::new();
111        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
112        for ext in self.extensions.iter().rev() {
113            next = ext.push_chain(&mut storage, next);
114        }
115        let mut raw: ffi::WGPUAdapterInfo = unsafe { std::mem::zeroed() };
116        raw.nextInChain = next;
117        if let Some(value) = &self.vendor {
118            raw.vendor = ffi::WGPUStringView {
119                data: value.as_ptr().cast(),
120                length: value.len(),
121            };
122        } else {
123            raw.vendor = ffi::WGPUStringView {
124                data: std::ptr::null(),
125                length: 0,
126            };
127        }
128        if let Some(value) = &self.architecture {
129            raw.architecture = ffi::WGPUStringView {
130                data: value.as_ptr().cast(),
131                length: value.len(),
132            };
133        } else {
134            raw.architecture = ffi::WGPUStringView {
135                data: std::ptr::null(),
136                length: 0,
137            };
138        }
139        if let Some(value) = &self.device {
140            raw.device = ffi::WGPUStringView {
141                data: value.as_ptr().cast(),
142                length: value.len(),
143            };
144        } else {
145            raw.device = ffi::WGPUStringView {
146                data: std::ptr::null(),
147                length: 0,
148            };
149        }
150        if let Some(value) = &self.description {
151            raw.description = ffi::WGPUStringView {
152                data: value.as_ptr().cast(),
153                length: value.len(),
154            };
155        } else {
156            raw.description = ffi::WGPUStringView {
157                data: std::ptr::null(),
158                length: 0,
159            };
160        }
161        if let Some(value) = self.backend_type {
162            raw.backendType = value.into();
163        } else {
164            raw.backendType = 0 as ffi::WGPUBackendType;
165        }
166        if let Some(value) = self.adapter_type {
167            raw.adapterType = value.into();
168        } else {
169            raw.adapterType = 0 as ffi::WGPUAdapterType;
170        }
171        if let Some(value) = self.vendor_id {
172            raw.vendorID = value;
173        }
174        if let Some(value) = self.device_id {
175            raw.deviceID = value;
176        }
177        if let Some(value) = self.subgroup_min_size {
178            raw.subgroupMinSize = value;
179        }
180        if let Some(value) = self.subgroup_max_size {
181            raw.subgroupMaxSize = value;
182        }
183        (raw, storage)
184    }
185    pub fn with_extension(mut self, extension: AdapterInfoExtension) -> Self {
186        self.extensions.push(extension);
187        self
188    }
189    pub(crate) fn from_ffi(value: ffi::WGPUAdapterInfo) -> Self {
190        Self {
191            extensions: Vec::new(),
192            vendor: Some(string_view_to_string(value.vendor)),
193            architecture: Some(string_view_to_string(value.architecture)),
194            device: Some(string_view_to_string(value.device)),
195            description: Some(string_view_to_string(value.description)),
196            backend_type: Some(value.backendType.into()),
197            adapter_type: Some(value.adapterType.into()),
198            vendor_id: Some(value.vendorID),
199            device_id: Some(value.deviceID),
200            subgroup_min_size: Some(value.subgroupMinSize),
201            subgroup_max_size: Some(value.subgroupMaxSize),
202            _free_members: Some(value),
203        }
204    }
205    pub(crate) fn free_members(value: ffi::WGPUAdapterInfo) {
206        unsafe { ffi::wgpuAdapterInfoFreeMembers(value) };
207    }
208}
209impl Drop for AdapterInfo {
210    fn drop(&mut self) {
211        if let Some(value) = self._free_members.take() {
212            unsafe { ffi::wgpuAdapterInfoFreeMembers(value) };
213        }
214    }
215}
216pub struct AdapterPropertiesD3D {
217    pub shader_model: Option<u32>,
218}
219impl Default for AdapterPropertiesD3D {
220    fn default() -> Self {
221        Self { shader_model: None }
222    }
223}
224impl AdapterPropertiesD3D {
225    pub fn new() -> Self {
226        Self::default()
227    }
228    pub(crate) fn to_ffi(
229        &self,
230    ) -> (ffi::WGPUAdapterPropertiesD3D, ChainedStructStorage) {
231        let mut storage = ChainedStructStorage::new();
232        let mut raw: ffi::WGPUAdapterPropertiesD3D = unsafe { std::mem::zeroed() };
233        if let Some(value) = self.shader_model {
234            raw.shaderModel = value;
235        }
236        (raw, storage)
237    }
238    pub(crate) fn from_ffi(value: ffi::WGPUAdapterPropertiesD3D) -> Self {
239        Self {
240            shader_model: Some(value.shaderModel),
241        }
242    }
243}
244pub struct AdapterPropertiesWGPU {
245    pub backend_type: Option<BackendType>,
246}
247impl Default for AdapterPropertiesWGPU {
248    fn default() -> Self {
249        Self { backend_type: None }
250    }
251}
252impl AdapterPropertiesWGPU {
253    pub fn new() -> Self {
254        Self::default()
255    }
256    pub(crate) fn to_ffi(
257        &self,
258    ) -> (ffi::WGPUAdapterPropertiesWGPU, ChainedStructStorage) {
259        let mut storage = ChainedStructStorage::new();
260        let mut raw: ffi::WGPUAdapterPropertiesWGPU = unsafe { std::mem::zeroed() };
261        if let Some(value) = self.backend_type {
262            raw.backendType = value.into();
263        } else {
264            raw.backendType = 0 as ffi::WGPUBackendType;
265        }
266        (raw, storage)
267    }
268    pub(crate) fn from_ffi(value: ffi::WGPUAdapterPropertiesWGPU) -> Self {
269        Self {
270            backend_type: Some(value.backendType.into()),
271        }
272    }
273}
274pub struct AdapterPropertiesExplicitComputeSubgroupSizeConfigs {
275    pub min_explicit_compute_subgroup_size: Option<u32>,
276    pub max_explicit_compute_subgroup_size: Option<u32>,
277    pub max_compute_workgroup_subgroups: Option<u32>,
278}
279impl Default for AdapterPropertiesExplicitComputeSubgroupSizeConfigs {
280    fn default() -> Self {
281        Self {
282            min_explicit_compute_subgroup_size: None,
283            max_explicit_compute_subgroup_size: None,
284            max_compute_workgroup_subgroups: None,
285        }
286    }
287}
288impl AdapterPropertiesExplicitComputeSubgroupSizeConfigs {
289    pub fn new() -> Self {
290        Self::default()
291    }
292    pub(crate) fn to_ffi(
293        &self,
294    ) -> (
295        ffi::WGPUAdapterPropertiesExplicitComputeSubgroupSizeConfigs,
296        ChainedStructStorage,
297    ) {
298        let mut storage = ChainedStructStorage::new();
299        let mut raw: ffi::WGPUAdapterPropertiesExplicitComputeSubgroupSizeConfigs = unsafe {
300            std::mem::zeroed()
301        };
302        if let Some(value) = self.min_explicit_compute_subgroup_size {
303            raw.minExplicitComputeSubgroupSize = value;
304        }
305        if let Some(value) = self.max_explicit_compute_subgroup_size {
306            raw.maxExplicitComputeSubgroupSize = value;
307        }
308        if let Some(value) = self.max_compute_workgroup_subgroups {
309            raw.maxComputeWorkgroupSubgroups = value;
310        }
311        (raw, storage)
312    }
313    pub(crate) fn from_ffi(
314        value: ffi::WGPUAdapterPropertiesExplicitComputeSubgroupSizeConfigs,
315    ) -> Self {
316        Self {
317            min_explicit_compute_subgroup_size: Some(
318                value.minExplicitComputeSubgroupSize,
319            ),
320            max_explicit_compute_subgroup_size: Some(
321                value.maxExplicitComputeSubgroupSize,
322            ),
323            max_compute_workgroup_subgroups: Some(value.maxComputeWorkgroupSubgroups),
324        }
325    }
326}
327pub struct AdapterPropertiesMemoryHeaps {
328    pub heap_info: Option<Vec<MemoryHeapInfo>>,
329    #[doc(hidden)]
330    pub(crate) _free_members: Option<ffi::WGPUAdapterPropertiesMemoryHeaps>,
331}
332impl Default for AdapterPropertiesMemoryHeaps {
333    fn default() -> Self {
334        Self {
335            heap_info: None,
336            _free_members: None,
337        }
338    }
339}
340impl AdapterPropertiesMemoryHeaps {
341    pub fn new() -> Self {
342        Self::default()
343    }
344    pub(crate) fn to_ffi(
345        &self,
346    ) -> (ffi::WGPUAdapterPropertiesMemoryHeaps, ChainedStructStorage) {
347        let mut storage = ChainedStructStorage::new();
348        let mut raw: ffi::WGPUAdapterPropertiesMemoryHeaps = unsafe {
349            std::mem::zeroed()
350        };
351        raw.heapCount = self.heap_info.as_ref().map(|v| v.len()).unwrap_or(0);
352        if let Some(values) = &self.heap_info {
353            let len_value = values.len();
354            let mut raw_vec: Vec<ffi::WGPUMemoryHeapInfo> = Vec::with_capacity(
355                values.len(),
356            );
357            for item in values.iter() {
358                let (raw_item, storage_item) = item.to_ffi();
359                raw_vec.push(raw_item);
360                storage.push_storage(storage_item);
361            }
362            let ptr = storage.push_vec(raw_vec);
363            raw.heapInfo = ptr;
364            raw.heapCount = len_value;
365        } else {
366            raw.heapInfo = std::ptr::null();
367            raw.heapCount = 0;
368        }
369        (raw, storage)
370    }
371    pub(crate) fn from_ffi(value: ffi::WGPUAdapterPropertiesMemoryHeaps) -> Self {
372        Self {
373            heap_info: if value.heapInfo.is_null() {
374                None
375            } else {
376                Some(
377                    unsafe {
378                        std::slice::from_raw_parts(
379                            value.heapInfo,
380                            value.heapCount as usize,
381                        )
382                    }
383                        .iter()
384                        .map(|raw| MemoryHeapInfo::from_ffi(*raw))
385                        .collect(),
386                )
387            },
388            _free_members: Some(value),
389        }
390    }
391    pub(crate) fn free_members(value: ffi::WGPUAdapterPropertiesMemoryHeaps) {
392        unsafe { ffi::wgpuAdapterPropertiesMemoryHeapsFreeMembers(value) };
393    }
394}
395impl Drop for AdapterPropertiesMemoryHeaps {
396    fn drop(&mut self) {
397        if let Some(value) = self._free_members.take() {
398            unsafe { ffi::wgpuAdapterPropertiesMemoryHeapsFreeMembers(value) };
399        }
400    }
401}
402pub struct AdapterPropertiesSubgroupMatrixConfigs {
403    pub configs: Option<Vec<SubgroupMatrixConfig>>,
404    #[doc(hidden)]
405    pub(crate) _free_members: Option<ffi::WGPUAdapterPropertiesSubgroupMatrixConfigs>,
406}
407impl Default for AdapterPropertiesSubgroupMatrixConfigs {
408    fn default() -> Self {
409        Self {
410            configs: None,
411            _free_members: None,
412        }
413    }
414}
415impl AdapterPropertiesSubgroupMatrixConfigs {
416    pub fn new() -> Self {
417        Self::default()
418    }
419    pub(crate) fn to_ffi(
420        &self,
421    ) -> (ffi::WGPUAdapterPropertiesSubgroupMatrixConfigs, ChainedStructStorage) {
422        let mut storage = ChainedStructStorage::new();
423        let mut raw: ffi::WGPUAdapterPropertiesSubgroupMatrixConfigs = unsafe {
424            std::mem::zeroed()
425        };
426        raw.configCount = self.configs.as_ref().map(|v| v.len()).unwrap_or(0);
427        if let Some(values) = &self.configs {
428            let len_value = values.len();
429            let mut raw_vec: Vec<ffi::WGPUSubgroupMatrixConfig> = Vec::with_capacity(
430                values.len(),
431            );
432            for item in values.iter() {
433                let (raw_item, storage_item) = item.to_ffi();
434                raw_vec.push(raw_item);
435                storage.push_storage(storage_item);
436            }
437            let ptr = storage.push_vec(raw_vec);
438            raw.configs = ptr;
439            raw.configCount = len_value;
440        } else {
441            raw.configs = std::ptr::null();
442            raw.configCount = 0;
443        }
444        (raw, storage)
445    }
446    pub(crate) fn from_ffi(
447        value: ffi::WGPUAdapterPropertiesSubgroupMatrixConfigs,
448    ) -> Self {
449        Self {
450            configs: if value.configs.is_null() {
451                None
452            } else {
453                Some(
454                    unsafe {
455                        std::slice::from_raw_parts(
456                            value.configs,
457                            value.configCount as usize,
458                        )
459                    }
460                        .iter()
461                        .map(|raw| SubgroupMatrixConfig::from_ffi(*raw))
462                        .collect(),
463                )
464            },
465            _free_members: Some(value),
466        }
467    }
468    pub(crate) fn free_members(value: ffi::WGPUAdapterPropertiesSubgroupMatrixConfigs) {
469        unsafe { ffi::wgpuAdapterPropertiesSubgroupMatrixConfigsFreeMembers(value) };
470    }
471}
472impl Drop for AdapterPropertiesSubgroupMatrixConfigs {
473    fn drop(&mut self) {
474        if let Some(value) = self._free_members.take() {
475            unsafe { ffi::wgpuAdapterPropertiesSubgroupMatrixConfigsFreeMembers(value) };
476        }
477    }
478}
479pub struct AdapterPropertiesVk {
480    pub driver_version: Option<u32>,
481}
482impl Default for AdapterPropertiesVk {
483    fn default() -> Self {
484        Self { driver_version: None }
485    }
486}
487impl AdapterPropertiesVk {
488    pub fn new() -> Self {
489        Self::default()
490    }
491    pub(crate) fn to_ffi(&self) -> (ffi::WGPUAdapterPropertiesVk, ChainedStructStorage) {
492        let mut storage = ChainedStructStorage::new();
493        let mut raw: ffi::WGPUAdapterPropertiesVk = unsafe { std::mem::zeroed() };
494        if let Some(value) = self.driver_version {
495            raw.driverVersion = value;
496        }
497        (raw, storage)
498    }
499    pub(crate) fn from_ffi(value: ffi::WGPUAdapterPropertiesVk) -> Self {
500        Self {
501            driver_version: Some(value.driverVersion),
502        }
503    }
504}
505pub struct BindGroupDescriptor {
506    pub(crate) extensions: Vec<BindGroupDescriptorExtension>,
507    pub label: Option<String>,
508    pub layout: Option<BindGroupLayout>,
509    pub entries: Option<Vec<BindGroupEntry>>,
510}
511impl Default for BindGroupDescriptor {
512    fn default() -> Self {
513        Self {
514            extensions: Vec::new(),
515            label: None,
516            layout: None,
517            entries: None,
518        }
519    }
520}
521impl BindGroupDescriptor {
522    pub fn new() -> Self {
523        Self::default()
524    }
525    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBindGroupDescriptor, ChainedStructStorage) {
526        let mut storage = ChainedStructStorage::new();
527        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
528        for ext in self.extensions.iter().rev() {
529            next = ext.push_chain(&mut storage, next);
530        }
531        let mut raw: ffi::WGPUBindGroupDescriptor = unsafe { std::mem::zeroed() };
532        raw.nextInChain = next;
533        if let Some(value) = &self.label {
534            raw.label = ffi::WGPUStringView {
535                data: value.as_ptr().cast(),
536                length: value.len(),
537            };
538        } else {
539            raw.label = ffi::WGPUStringView {
540                data: std::ptr::null(),
541                length: 0,
542            };
543        }
544        raw.layout = self
545            .layout
546            .as_ref()
547            .map(|v| v.as_raw())
548            .unwrap_or(std::ptr::null_mut());
549        raw.entryCount = self.entries.as_ref().map(|v| v.len()).unwrap_or(0);
550        if let Some(values) = &self.entries {
551            let len_value = values.len();
552            let mut raw_vec: Vec<ffi::WGPUBindGroupEntry> = Vec::with_capacity(
553                values.len(),
554            );
555            for item in values.iter() {
556                let (raw_item, storage_item) = item.to_ffi();
557                raw_vec.push(raw_item);
558                storage.push_storage(storage_item);
559            }
560            let ptr = storage.push_vec(raw_vec);
561            raw.entries = ptr;
562            raw.entryCount = len_value;
563        } else {
564            raw.entries = std::ptr::null();
565            raw.entryCount = 0;
566        }
567        (raw, storage)
568    }
569    pub fn with_extension(mut self, extension: BindGroupDescriptorExtension) -> Self {
570        self.extensions.push(extension);
571        self
572    }
573    pub(crate) fn from_ffi(value: ffi::WGPUBindGroupDescriptor) -> Self {
574        Self {
575            extensions: Vec::new(),
576            label: if value.label.data.is_null() || value.label.length == 0 {
577                None
578            } else {
579                Some(string_view_to_string(value.label))
580            },
581            layout: Some(unsafe { BindGroupLayout::from_raw(value.layout) }),
582            entries: if value.entries.is_null() {
583                None
584            } else {
585                Some(
586                    unsafe {
587                        std::slice::from_raw_parts(
588                            value.entries,
589                            value.entryCount as usize,
590                        )
591                    }
592                        .iter()
593                        .map(|raw| BindGroupEntry::from_ffi(*raw))
594                        .collect(),
595                )
596            },
597        }
598    }
599}
600pub struct BindGroupEntry {
601    pub(crate) extensions: Vec<BindGroupEntryExtension>,
602    pub binding: Option<u32>,
603    pub buffer: Option<Buffer>,
604    pub offset: Option<u64>,
605    pub size: Option<u64>,
606    pub sampler: Option<Sampler>,
607    pub texture_view: Option<TextureView>,
608}
609impl Default for BindGroupEntry {
610    fn default() -> Self {
611        Self {
612            extensions: Vec::new(),
613            binding: None,
614            buffer: None,
615            offset: Some(0),
616            size: Some(WHOLE_SIZE),
617            sampler: None,
618            texture_view: None,
619        }
620    }
621}
622impl BindGroupEntry {
623    pub fn new() -> Self {
624        Self::default()
625    }
626    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBindGroupEntry, ChainedStructStorage) {
627        let mut storage = ChainedStructStorage::new();
628        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
629        for ext in self.extensions.iter().rev() {
630            next = ext.push_chain(&mut storage, next);
631        }
632        let mut raw: ffi::WGPUBindGroupEntry = unsafe { std::mem::zeroed() };
633        raw.nextInChain = next;
634        if let Some(value) = self.binding {
635            raw.binding = value;
636        }
637        raw.buffer = self
638            .buffer
639            .as_ref()
640            .map(|v| v.as_raw())
641            .unwrap_or(std::ptr::null_mut());
642        if let Some(value) = self.offset {
643            raw.offset = value;
644        }
645        if let Some(value) = self.size {
646            raw.size = value;
647        }
648        raw.sampler = self
649            .sampler
650            .as_ref()
651            .map(|v| v.as_raw())
652            .unwrap_or(std::ptr::null_mut());
653        raw.textureView = self
654            .texture_view
655            .as_ref()
656            .map(|v| v.as_raw())
657            .unwrap_or(std::ptr::null_mut());
658        (raw, storage)
659    }
660    pub fn with_extension(mut self, extension: BindGroupEntryExtension) -> Self {
661        self.extensions.push(extension);
662        self
663    }
664    pub(crate) fn from_ffi(value: ffi::WGPUBindGroupEntry) -> Self {
665        Self {
666            extensions: Vec::new(),
667            binding: Some(value.binding),
668            buffer: if value.buffer.is_null() {
669                None
670            } else {
671                Some(unsafe { Buffer::from_raw(value.buffer) })
672            },
673            offset: Some(value.offset),
674            size: Some(value.size),
675            sampler: if value.sampler.is_null() {
676                None
677            } else {
678                Some(unsafe { Sampler::from_raw(value.sampler) })
679            },
680            texture_view: if value.textureView.is_null() {
681                None
682            } else {
683                Some(unsafe { TextureView::from_raw(value.textureView) })
684            },
685        }
686    }
687}
688pub struct BindGroupLayoutDescriptor {
689    pub(crate) extensions: Vec<BindGroupLayoutDescriptorExtension>,
690    pub label: Option<String>,
691    pub entries: Option<Vec<BindGroupLayoutEntry>>,
692}
693impl Default for BindGroupLayoutDescriptor {
694    fn default() -> Self {
695        Self {
696            extensions: Vec::new(),
697            label: None,
698            entries: None,
699        }
700    }
701}
702impl BindGroupLayoutDescriptor {
703    pub fn new() -> Self {
704        Self::default()
705    }
706    pub(crate) fn to_ffi(
707        &self,
708    ) -> (ffi::WGPUBindGroupLayoutDescriptor, ChainedStructStorage) {
709        let mut storage = ChainedStructStorage::new();
710        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
711        for ext in self.extensions.iter().rev() {
712            next = ext.push_chain(&mut storage, next);
713        }
714        let mut raw: ffi::WGPUBindGroupLayoutDescriptor = unsafe { std::mem::zeroed() };
715        raw.nextInChain = next;
716        if let Some(value) = &self.label {
717            raw.label = ffi::WGPUStringView {
718                data: value.as_ptr().cast(),
719                length: value.len(),
720            };
721        } else {
722            raw.label = ffi::WGPUStringView {
723                data: std::ptr::null(),
724                length: 0,
725            };
726        }
727        raw.entryCount = self.entries.as_ref().map(|v| v.len()).unwrap_or(0);
728        if let Some(values) = &self.entries {
729            let len_value = values.len();
730            let mut raw_vec: Vec<ffi::WGPUBindGroupLayoutEntry> = Vec::with_capacity(
731                values.len(),
732            );
733            for item in values.iter() {
734                let (raw_item, storage_item) = item.to_ffi();
735                raw_vec.push(raw_item);
736                storage.push_storage(storage_item);
737            }
738            let ptr = storage.push_vec(raw_vec);
739            raw.entries = ptr;
740            raw.entryCount = len_value;
741        } else {
742            raw.entries = std::ptr::null();
743            raw.entryCount = 0;
744        }
745        (raw, storage)
746    }
747    pub fn with_extension(
748        mut self,
749        extension: BindGroupLayoutDescriptorExtension,
750    ) -> Self {
751        self.extensions.push(extension);
752        self
753    }
754    pub(crate) fn from_ffi(value: ffi::WGPUBindGroupLayoutDescriptor) -> Self {
755        Self {
756            extensions: Vec::new(),
757            label: if value.label.data.is_null() || value.label.length == 0 {
758                None
759            } else {
760                Some(string_view_to_string(value.label))
761            },
762            entries: if value.entries.is_null() {
763                None
764            } else {
765                Some(
766                    unsafe {
767                        std::slice::from_raw_parts(
768                            value.entries,
769                            value.entryCount as usize,
770                        )
771                    }
772                        .iter()
773                        .map(|raw| BindGroupLayoutEntry::from_ffi(*raw))
774                        .collect(),
775                )
776            },
777        }
778    }
779}
780pub struct BindGroupLayoutEntry {
781    pub(crate) extensions: Vec<BindGroupLayoutEntryExtension>,
782    pub binding: Option<u32>,
783    pub visibility: Option<ShaderStage>,
784    pub binding_array_size: Option<u32>,
785    pub buffer: Option<BufferBindingLayout>,
786    pub sampler: Option<SamplerBindingLayout>,
787    pub texture: Option<TextureBindingLayout>,
788    pub storage_texture: Option<StorageTextureBindingLayout>,
789}
790impl Default for BindGroupLayoutEntry {
791    fn default() -> Self {
792        Self {
793            extensions: Vec::new(),
794            binding: None,
795            visibility: None,
796            binding_array_size: Some(0),
797            buffer: None,
798            sampler: None,
799            texture: None,
800            storage_texture: None,
801        }
802    }
803}
804impl BindGroupLayoutEntry {
805    pub fn new() -> Self {
806        Self::default()
807    }
808    pub(crate) fn to_ffi(
809        &self,
810    ) -> (ffi::WGPUBindGroupLayoutEntry, ChainedStructStorage) {
811        let mut storage = ChainedStructStorage::new();
812        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
813        for ext in self.extensions.iter().rev() {
814            next = ext.push_chain(&mut storage, next);
815        }
816        let mut raw: ffi::WGPUBindGroupLayoutEntry = unsafe { std::mem::zeroed() };
817        raw.nextInChain = next;
818        if let Some(value) = self.binding {
819            raw.binding = value;
820        }
821        if let Some(value) = self.visibility {
822            raw.visibility = value.into();
823        } else {
824            raw.visibility = 0 as ffi::WGPUShaderStage;
825        }
826        if let Some(value) = self.binding_array_size {
827            raw.bindingArraySize = value;
828        }
829        if let Some(value) = &self.buffer {
830            let (raw_value, storage_value) = value.to_ffi();
831            raw.buffer = raw_value;
832            storage.push_storage(storage_value);
833        }
834        if let Some(value) = &self.sampler {
835            let (raw_value, storage_value) = value.to_ffi();
836            raw.sampler = raw_value;
837            storage.push_storage(storage_value);
838        }
839        if let Some(value) = &self.texture {
840            let (raw_value, storage_value) = value.to_ffi();
841            raw.texture = raw_value;
842            storage.push_storage(storage_value);
843        }
844        if let Some(value) = &self.storage_texture {
845            let (raw_value, storage_value) = value.to_ffi();
846            raw.storageTexture = raw_value;
847            storage.push_storage(storage_value);
848        }
849        (raw, storage)
850    }
851    pub fn with_extension(mut self, extension: BindGroupLayoutEntryExtension) -> Self {
852        self.extensions.push(extension);
853        self
854    }
855    pub(crate) fn from_ffi(value: ffi::WGPUBindGroupLayoutEntry) -> Self {
856        Self {
857            extensions: Vec::new(),
858            binding: Some(value.binding),
859            visibility: Some(value.visibility.into()),
860            binding_array_size: Some(value.bindingArraySize),
861            buffer: Some(BufferBindingLayout::from_ffi(value.buffer)),
862            sampler: Some(SamplerBindingLayout::from_ffi(value.sampler)),
863            texture: Some(TextureBindingLayout::from_ffi(value.texture)),
864            storage_texture: Some(
865                StorageTextureBindingLayout::from_ffi(value.storageTexture),
866            ),
867        }
868    }
869}
870pub struct BindingResource {
871    pub(crate) extensions: Vec<BindingResourceExtension>,
872    pub buffer: Option<Buffer>,
873    pub offset: Option<u64>,
874    pub size: Option<u64>,
875    pub sampler: Option<Sampler>,
876    pub texture_view: Option<TextureView>,
877}
878impl Default for BindingResource {
879    fn default() -> Self {
880        Self {
881            extensions: Vec::new(),
882            buffer: None,
883            offset: Some(0),
884            size: Some(WHOLE_SIZE),
885            sampler: None,
886            texture_view: None,
887        }
888    }
889}
890impl BindingResource {
891    pub fn new() -> Self {
892        Self::default()
893    }
894    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBindingResource, ChainedStructStorage) {
895        let mut storage = ChainedStructStorage::new();
896        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
897        for ext in self.extensions.iter().rev() {
898            next = ext.push_chain(&mut storage, next);
899        }
900        let mut raw: ffi::WGPUBindingResource = unsafe { std::mem::zeroed() };
901        raw.nextInChain = next;
902        raw.buffer = self
903            .buffer
904            .as_ref()
905            .map(|v| v.as_raw())
906            .unwrap_or(std::ptr::null_mut());
907        if let Some(value) = self.offset {
908            raw.offset = value;
909        }
910        if let Some(value) = self.size {
911            raw.size = value;
912        }
913        raw.sampler = self
914            .sampler
915            .as_ref()
916            .map(|v| v.as_raw())
917            .unwrap_or(std::ptr::null_mut());
918        raw.textureView = self
919            .texture_view
920            .as_ref()
921            .map(|v| v.as_raw())
922            .unwrap_or(std::ptr::null_mut());
923        (raw, storage)
924    }
925    pub fn with_extension(mut self, extension: BindingResourceExtension) -> Self {
926        self.extensions.push(extension);
927        self
928    }
929    pub(crate) fn from_ffi(value: ffi::WGPUBindingResource) -> Self {
930        Self {
931            extensions: Vec::new(),
932            buffer: if value.buffer.is_null() {
933                None
934            } else {
935                Some(unsafe { Buffer::from_raw(value.buffer) })
936            },
937            offset: Some(value.offset),
938            size: Some(value.size),
939            sampler: if value.sampler.is_null() {
940                None
941            } else {
942                Some(unsafe { Sampler::from_raw(value.sampler) })
943            },
944            texture_view: if value.textureView.is_null() {
945                None
946            } else {
947                Some(unsafe { TextureView::from_raw(value.textureView) })
948            },
949        }
950    }
951}
952pub struct BlendComponent {
953    pub operation: Option<BlendOperation>,
954    pub src_factor: Option<BlendFactor>,
955    pub dst_factor: Option<BlendFactor>,
956}
957impl Default for BlendComponent {
958    fn default() -> Self {
959        Self {
960            operation: Some(BlendOperation::Add),
961            src_factor: Some(BlendFactor::One),
962            dst_factor: Some(BlendFactor::Zero),
963        }
964    }
965}
966impl BlendComponent {
967    pub fn new() -> Self {
968        Self::default()
969    }
970    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBlendComponent, ChainedStructStorage) {
971        let mut storage = ChainedStructStorage::new();
972        let mut raw: ffi::WGPUBlendComponent = unsafe { std::mem::zeroed() };
973        if let Some(value) = self.operation {
974            raw.operation = value.into();
975        } else {
976            raw.operation = 0 as ffi::WGPUBlendOperation;
977        }
978        if let Some(value) = self.src_factor {
979            raw.srcFactor = value.into();
980        } else {
981            raw.srcFactor = 0 as ffi::WGPUBlendFactor;
982        }
983        if let Some(value) = self.dst_factor {
984            raw.dstFactor = value.into();
985        } else {
986            raw.dstFactor = 0 as ffi::WGPUBlendFactor;
987        }
988        (raw, storage)
989    }
990    pub(crate) fn from_ffi(value: ffi::WGPUBlendComponent) -> Self {
991        Self {
992            operation: Some(value.operation.into()),
993            src_factor: Some(value.srcFactor.into()),
994            dst_factor: Some(value.dstFactor.into()),
995        }
996    }
997}
998pub struct BlendState {
999    pub color: Option<BlendComponent>,
1000    pub alpha: Option<BlendComponent>,
1001}
1002impl Default for BlendState {
1003    fn default() -> Self {
1004        Self { color: None, alpha: None }
1005    }
1006}
1007impl BlendState {
1008    pub fn new() -> Self {
1009        Self::default()
1010    }
1011    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBlendState, ChainedStructStorage) {
1012        let mut storage = ChainedStructStorage::new();
1013        let mut raw: ffi::WGPUBlendState = unsafe { std::mem::zeroed() };
1014        if let Some(value) = &self.color {
1015            let (raw_value, storage_value) = value.to_ffi();
1016            raw.color = raw_value;
1017            storage.push_storage(storage_value);
1018        }
1019        if let Some(value) = &self.alpha {
1020            let (raw_value, storage_value) = value.to_ffi();
1021            raw.alpha = raw_value;
1022            storage.push_storage(storage_value);
1023        }
1024        (raw, storage)
1025    }
1026    pub(crate) fn from_ffi(value: ffi::WGPUBlendState) -> Self {
1027        Self {
1028            color: Some(BlendComponent::from_ffi(value.color)),
1029            alpha: Some(BlendComponent::from_ffi(value.alpha)),
1030        }
1031    }
1032}
1033pub struct BufferBindingLayout {
1034    pub(crate) extensions: Vec<BufferBindingLayoutExtension>,
1035    pub r#type: Option<BufferBindingType>,
1036    pub has_dynamic_offset: Option<bool>,
1037    pub min_binding_size: Option<u64>,
1038}
1039impl Default for BufferBindingLayout {
1040    fn default() -> Self {
1041        Self {
1042            extensions: Vec::new(),
1043            r#type: Some(BufferBindingType::Uniform),
1044            has_dynamic_offset: None,
1045            min_binding_size: Some(0),
1046        }
1047    }
1048}
1049impl BufferBindingLayout {
1050    pub fn new() -> Self {
1051        Self::default()
1052    }
1053    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBufferBindingLayout, ChainedStructStorage) {
1054        let mut storage = ChainedStructStorage::new();
1055        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1056        for ext in self.extensions.iter().rev() {
1057            next = ext.push_chain(&mut storage, next);
1058        }
1059        let mut raw: ffi::WGPUBufferBindingLayout = unsafe { std::mem::zeroed() };
1060        raw.nextInChain = next;
1061        if let Some(value) = self.r#type {
1062            raw.type_ = value.into();
1063        } else {
1064            raw.type_ = 0 as ffi::WGPUBufferBindingType;
1065        }
1066        raw.hasDynamicOffset = if self.has_dynamic_offset.unwrap_or(false) {
1067            1
1068        } else {
1069            0
1070        };
1071        if let Some(value) = self.min_binding_size {
1072            raw.minBindingSize = value;
1073        }
1074        (raw, storage)
1075    }
1076    pub fn with_extension(mut self, extension: BufferBindingLayoutExtension) -> Self {
1077        self.extensions.push(extension);
1078        self
1079    }
1080    pub(crate) fn from_ffi(value: ffi::WGPUBufferBindingLayout) -> Self {
1081        Self {
1082            extensions: Vec::new(),
1083            r#type: Some(value.type_.into()),
1084            has_dynamic_offset: Some(value.hasDynamicOffset != 0),
1085            min_binding_size: Some(value.minBindingSize),
1086        }
1087    }
1088}
1089pub struct BufferDescriptor {
1090    pub(crate) extensions: Vec<BufferDescriptorExtension>,
1091    pub label: Option<String>,
1092    pub usage: Option<BufferUsage>,
1093    pub size: Option<u64>,
1094    pub mapped_at_creation: Option<bool>,
1095}
1096impl Default for BufferDescriptor {
1097    fn default() -> Self {
1098        Self {
1099            extensions: Vec::new(),
1100            label: None,
1101            usage: None,
1102            size: None,
1103            mapped_at_creation: None,
1104        }
1105    }
1106}
1107impl BufferDescriptor {
1108    pub fn new() -> Self {
1109        Self::default()
1110    }
1111    pub(crate) fn to_ffi(&self) -> (ffi::WGPUBufferDescriptor, ChainedStructStorage) {
1112        let mut storage = ChainedStructStorage::new();
1113        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1114        for ext in self.extensions.iter().rev() {
1115            next = ext.push_chain(&mut storage, next);
1116        }
1117        let mut raw: ffi::WGPUBufferDescriptor = unsafe { std::mem::zeroed() };
1118        raw.nextInChain = next;
1119        if let Some(value) = &self.label {
1120            raw.label = ffi::WGPUStringView {
1121                data: value.as_ptr().cast(),
1122                length: value.len(),
1123            };
1124        } else {
1125            raw.label = ffi::WGPUStringView {
1126                data: std::ptr::null(),
1127                length: 0,
1128            };
1129        }
1130        if let Some(value) = self.usage {
1131            raw.usage = value.into();
1132        } else {
1133            raw.usage = 0 as ffi::WGPUBufferUsage;
1134        }
1135        if let Some(value) = self.size {
1136            raw.size = value;
1137        }
1138        raw.mappedAtCreation = if self.mapped_at_creation.unwrap_or(false) {
1139            1
1140        } else {
1141            0
1142        };
1143        (raw, storage)
1144    }
1145    pub fn with_extension(mut self, extension: BufferDescriptorExtension) -> Self {
1146        self.extensions.push(extension);
1147        self
1148    }
1149    pub(crate) fn from_ffi(value: ffi::WGPUBufferDescriptor) -> Self {
1150        Self {
1151            extensions: Vec::new(),
1152            label: if value.label.data.is_null() || value.label.length == 0 {
1153                None
1154            } else {
1155                Some(string_view_to_string(value.label))
1156            },
1157            usage: Some(value.usage.into()),
1158            size: Some(value.size),
1159            mapped_at_creation: Some(value.mappedAtCreation != 0),
1160        }
1161    }
1162}
1163pub struct BufferHostMappedPointer {
1164    pub pointer: Option<*mut std::ffi::c_void>,
1165    pub dispose_callback: Option<Callback>,
1166    pub userdata: Option<*mut std::ffi::c_void>,
1167}
1168impl Default for BufferHostMappedPointer {
1169    fn default() -> Self {
1170        Self {
1171            pointer: None,
1172            dispose_callback: None,
1173            userdata: None,
1174        }
1175    }
1176}
1177impl BufferHostMappedPointer {
1178    pub fn new() -> Self {
1179        Self::default()
1180    }
1181    pub(crate) fn to_ffi(
1182        &self,
1183    ) -> (ffi::WGPUBufferHostMappedPointer, ChainedStructStorage) {
1184        let mut storage = ChainedStructStorage::new();
1185        let mut raw: ffi::WGPUBufferHostMappedPointer = unsafe { std::mem::zeroed() };
1186        if let Some(value) = self.pointer {
1187            raw.pointer = value;
1188        }
1189        if let Some(value) = self.dispose_callback {
1190            raw.disposeCallback = value;
1191        }
1192        if let Some(value) = self.userdata {
1193            raw.userdata = value;
1194        }
1195        (raw, storage)
1196    }
1197    pub(crate) fn from_ffi(value: ffi::WGPUBufferHostMappedPointer) -> Self {
1198        Self {
1199            pointer: Some(value.pointer),
1200            dispose_callback: Some(value.disposeCallback),
1201            userdata: Some(value.userdata),
1202        }
1203    }
1204}
1205pub struct Color {
1206    pub r: Option<f64>,
1207    pub g: Option<f64>,
1208    pub b: Option<f64>,
1209    pub a: Option<f64>,
1210}
1211impl Default for Color {
1212    fn default() -> Self {
1213        Self {
1214            r: None,
1215            g: None,
1216            b: None,
1217            a: None,
1218        }
1219    }
1220}
1221impl Color {
1222    pub fn new() -> Self {
1223        Self::default()
1224    }
1225    pub(crate) fn to_ffi(&self) -> (ffi::WGPUColor, ChainedStructStorage) {
1226        let mut storage = ChainedStructStorage::new();
1227        let mut raw: ffi::WGPUColor = unsafe { std::mem::zeroed() };
1228        if let Some(value) = self.r {
1229            raw.r = value;
1230        }
1231        if let Some(value) = self.g {
1232            raw.g = value;
1233        }
1234        if let Some(value) = self.b {
1235            raw.b = value;
1236        }
1237        if let Some(value) = self.a {
1238            raw.a = value;
1239        }
1240        (raw, storage)
1241    }
1242    pub(crate) fn from_ffi(value: ffi::WGPUColor) -> Self {
1243        Self {
1244            r: Some(value.r),
1245            g: Some(value.g),
1246            b: Some(value.b),
1247            a: Some(value.a),
1248        }
1249    }
1250}
1251pub struct ColorTargetState {
1252    pub(crate) extensions: Vec<ColorTargetStateExtension>,
1253    pub format: Option<TextureFormat>,
1254    pub blend: Option<BlendState>,
1255    pub write_mask: Option<ColorWriteMask>,
1256}
1257impl Default for ColorTargetState {
1258    fn default() -> Self {
1259        Self {
1260            extensions: Vec::new(),
1261            format: None,
1262            blend: None,
1263            write_mask: Some(ColorWriteMask::ALL),
1264        }
1265    }
1266}
1267impl ColorTargetState {
1268    pub fn new() -> Self {
1269        Self::default()
1270    }
1271    pub(crate) fn to_ffi(&self) -> (ffi::WGPUColorTargetState, ChainedStructStorage) {
1272        let mut storage = ChainedStructStorage::new();
1273        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1274        for ext in self.extensions.iter().rev() {
1275            next = ext.push_chain(&mut storage, next);
1276        }
1277        let mut raw: ffi::WGPUColorTargetState = unsafe { std::mem::zeroed() };
1278        raw.nextInChain = next;
1279        if let Some(value) = self.format {
1280            raw.format = value.into();
1281        } else {
1282            raw.format = 0 as ffi::WGPUTextureFormat;
1283        }
1284        if let Some(value) = &self.blend {
1285            let (raw_value, storage_value) = value.to_ffi();
1286            let ptr = storage.push_value(raw_value);
1287            raw.blend = ptr;
1288            storage.push_storage(storage_value);
1289        } else {
1290            raw.blend = std::ptr::null();
1291        }
1292        if let Some(value) = self.write_mask {
1293            raw.writeMask = value.into();
1294        } else {
1295            raw.writeMask = 0 as ffi::WGPUColorWriteMask;
1296        }
1297        (raw, storage)
1298    }
1299    pub fn with_extension(mut self, extension: ColorTargetStateExtension) -> Self {
1300        self.extensions.push(extension);
1301        self
1302    }
1303    pub(crate) fn from_ffi(value: ffi::WGPUColorTargetState) -> Self {
1304        Self {
1305            extensions: Vec::new(),
1306            format: Some(value.format.into()),
1307            blend: if value.blend.is_null() {
1308                None
1309            } else {
1310                Some(BlendState::from_ffi(unsafe { *value.blend }))
1311            },
1312            write_mask: Some(value.writeMask.into()),
1313        }
1314    }
1315}
1316pub struct ColorTargetStateExpandResolveTextureDawn {
1317    pub enabled: Option<bool>,
1318}
1319impl Default for ColorTargetStateExpandResolveTextureDawn {
1320    fn default() -> Self {
1321        Self { enabled: None }
1322    }
1323}
1324impl ColorTargetStateExpandResolveTextureDawn {
1325    pub fn new() -> Self {
1326        Self::default()
1327    }
1328    pub(crate) fn to_ffi(
1329        &self,
1330    ) -> (ffi::WGPUColorTargetStateExpandResolveTextureDawn, ChainedStructStorage) {
1331        let mut storage = ChainedStructStorage::new();
1332        let mut raw: ffi::WGPUColorTargetStateExpandResolveTextureDawn = unsafe {
1333            std::mem::zeroed()
1334        };
1335        raw.enabled = if self.enabled.unwrap_or(false) { 1 } else { 0 };
1336        (raw, storage)
1337    }
1338    pub(crate) fn from_ffi(
1339        value: ffi::WGPUColorTargetStateExpandResolveTextureDawn,
1340    ) -> Self {
1341        Self {
1342            enabled: Some(value.enabled != 0),
1343        }
1344    }
1345}
1346pub struct CommandBufferDescriptor {
1347    pub(crate) extensions: Vec<CommandBufferDescriptorExtension>,
1348    pub label: Option<String>,
1349}
1350impl Default for CommandBufferDescriptor {
1351    fn default() -> Self {
1352        Self {
1353            extensions: Vec::new(),
1354            label: None,
1355        }
1356    }
1357}
1358impl CommandBufferDescriptor {
1359    pub fn new() -> Self {
1360        Self::default()
1361    }
1362    pub(crate) fn to_ffi(
1363        &self,
1364    ) -> (ffi::WGPUCommandBufferDescriptor, ChainedStructStorage) {
1365        let mut storage = ChainedStructStorage::new();
1366        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1367        for ext in self.extensions.iter().rev() {
1368            next = ext.push_chain(&mut storage, next);
1369        }
1370        let mut raw: ffi::WGPUCommandBufferDescriptor = unsafe { std::mem::zeroed() };
1371        raw.nextInChain = next;
1372        if let Some(value) = &self.label {
1373            raw.label = ffi::WGPUStringView {
1374                data: value.as_ptr().cast(),
1375                length: value.len(),
1376            };
1377        } else {
1378            raw.label = ffi::WGPUStringView {
1379                data: std::ptr::null(),
1380                length: 0,
1381            };
1382        }
1383        (raw, storage)
1384    }
1385    pub fn with_extension(
1386        mut self,
1387        extension: CommandBufferDescriptorExtension,
1388    ) -> Self {
1389        self.extensions.push(extension);
1390        self
1391    }
1392    pub(crate) fn from_ffi(value: ffi::WGPUCommandBufferDescriptor) -> Self {
1393        Self {
1394            extensions: Vec::new(),
1395            label: if value.label.data.is_null() || value.label.length == 0 {
1396                None
1397            } else {
1398                Some(string_view_to_string(value.label))
1399            },
1400        }
1401    }
1402}
1403pub struct CommandEncoderDescriptor {
1404    pub(crate) extensions: Vec<CommandEncoderDescriptorExtension>,
1405    pub label: Option<String>,
1406}
1407impl Default for CommandEncoderDescriptor {
1408    fn default() -> Self {
1409        Self {
1410            extensions: Vec::new(),
1411            label: None,
1412        }
1413    }
1414}
1415impl CommandEncoderDescriptor {
1416    pub fn new() -> Self {
1417        Self::default()
1418    }
1419    pub(crate) fn to_ffi(
1420        &self,
1421    ) -> (ffi::WGPUCommandEncoderDescriptor, ChainedStructStorage) {
1422        let mut storage = ChainedStructStorage::new();
1423        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1424        for ext in self.extensions.iter().rev() {
1425            next = ext.push_chain(&mut storage, next);
1426        }
1427        let mut raw: ffi::WGPUCommandEncoderDescriptor = unsafe { std::mem::zeroed() };
1428        raw.nextInChain = next;
1429        if let Some(value) = &self.label {
1430            raw.label = ffi::WGPUStringView {
1431                data: value.as_ptr().cast(),
1432                length: value.len(),
1433            };
1434        } else {
1435            raw.label = ffi::WGPUStringView {
1436                data: std::ptr::null(),
1437                length: 0,
1438            };
1439        }
1440        (raw, storage)
1441    }
1442    pub fn with_extension(
1443        mut self,
1444        extension: CommandEncoderDescriptorExtension,
1445    ) -> Self {
1446        self.extensions.push(extension);
1447        self
1448    }
1449    pub(crate) fn from_ffi(value: ffi::WGPUCommandEncoderDescriptor) -> Self {
1450        Self {
1451            extensions: Vec::new(),
1452            label: if value.label.data.is_null() || value.label.length == 0 {
1453                None
1454            } else {
1455                Some(string_view_to_string(value.label))
1456            },
1457        }
1458    }
1459}
1460pub struct CompatibilityModeLimits {
1461    pub max_storage_buffers_in_vertex_stage: Option<u32>,
1462    pub max_storage_textures_in_vertex_stage: Option<u32>,
1463    pub max_storage_buffers_in_fragment_stage: Option<u32>,
1464    pub max_storage_textures_in_fragment_stage: Option<u32>,
1465}
1466impl Default for CompatibilityModeLimits {
1467    fn default() -> Self {
1468        Self {
1469            max_storage_buffers_in_vertex_stage: Some(LIMIT_U32_UNDEFINED),
1470            max_storage_textures_in_vertex_stage: Some(LIMIT_U32_UNDEFINED),
1471            max_storage_buffers_in_fragment_stage: Some(LIMIT_U32_UNDEFINED),
1472            max_storage_textures_in_fragment_stage: Some(LIMIT_U32_UNDEFINED),
1473        }
1474    }
1475}
1476impl CompatibilityModeLimits {
1477    pub fn new() -> Self {
1478        Self::default()
1479    }
1480    pub(crate) fn to_ffi(
1481        &self,
1482    ) -> (ffi::WGPUCompatibilityModeLimits, ChainedStructStorage) {
1483        let mut storage = ChainedStructStorage::new();
1484        let mut raw: ffi::WGPUCompatibilityModeLimits = unsafe { std::mem::zeroed() };
1485        if let Some(value) = self.max_storage_buffers_in_vertex_stage {
1486            raw.maxStorageBuffersInVertexStage = value;
1487        }
1488        if let Some(value) = self.max_storage_textures_in_vertex_stage {
1489            raw.maxStorageTexturesInVertexStage = value;
1490        }
1491        if let Some(value) = self.max_storage_buffers_in_fragment_stage {
1492            raw.maxStorageBuffersInFragmentStage = value;
1493        }
1494        if let Some(value) = self.max_storage_textures_in_fragment_stage {
1495            raw.maxStorageTexturesInFragmentStage = value;
1496        }
1497        (raw, storage)
1498    }
1499    pub(crate) fn from_ffi(value: ffi::WGPUCompatibilityModeLimits) -> Self {
1500        Self {
1501            max_storage_buffers_in_vertex_stage: Some(
1502                value.maxStorageBuffersInVertexStage,
1503            ),
1504            max_storage_textures_in_vertex_stage: Some(
1505                value.maxStorageTexturesInVertexStage,
1506            ),
1507            max_storage_buffers_in_fragment_stage: Some(
1508                value.maxStorageBuffersInFragmentStage,
1509            ),
1510            max_storage_textures_in_fragment_stage: Some(
1511                value.maxStorageTexturesInFragmentStage,
1512            ),
1513        }
1514    }
1515}
1516pub struct CompilationInfo {
1517    pub(crate) extensions: Vec<CompilationInfoExtension>,
1518    pub messages: Option<Vec<CompilationMessage>>,
1519}
1520impl Default for CompilationInfo {
1521    fn default() -> Self {
1522        Self {
1523            extensions: Vec::new(),
1524            messages: None,
1525        }
1526    }
1527}
1528impl CompilationInfo {
1529    pub fn new() -> Self {
1530        Self::default()
1531    }
1532    pub(crate) fn to_ffi(&self) -> (ffi::WGPUCompilationInfo, ChainedStructStorage) {
1533        let mut storage = ChainedStructStorage::new();
1534        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1535        for ext in self.extensions.iter().rev() {
1536            next = ext.push_chain(&mut storage, next);
1537        }
1538        let mut raw: ffi::WGPUCompilationInfo = unsafe { std::mem::zeroed() };
1539        raw.nextInChain = next;
1540        raw.messageCount = self.messages.as_ref().map(|v| v.len()).unwrap_or(0);
1541        if let Some(values) = &self.messages {
1542            let len_value = values.len();
1543            let mut raw_vec: Vec<ffi::WGPUCompilationMessage> = Vec::with_capacity(
1544                values.len(),
1545            );
1546            for item in values.iter() {
1547                let (raw_item, storage_item) = item.to_ffi();
1548                raw_vec.push(raw_item);
1549                storage.push_storage(storage_item);
1550            }
1551            let ptr = storage.push_vec(raw_vec);
1552            raw.messages = ptr;
1553            raw.messageCount = len_value;
1554        } else {
1555            raw.messages = std::ptr::null();
1556            raw.messageCount = 0;
1557        }
1558        (raw, storage)
1559    }
1560    pub fn with_extension(mut self, extension: CompilationInfoExtension) -> Self {
1561        self.extensions.push(extension);
1562        self
1563    }
1564    pub(crate) fn from_ffi(value: ffi::WGPUCompilationInfo) -> Self {
1565        Self {
1566            extensions: Vec::new(),
1567            messages: if value.messages.is_null() {
1568                None
1569            } else {
1570                Some(
1571                    unsafe {
1572                        std::slice::from_raw_parts(
1573                            value.messages,
1574                            value.messageCount as usize,
1575                        )
1576                    }
1577                        .iter()
1578                        .map(|raw| CompilationMessage::from_ffi(*raw))
1579                        .collect(),
1580                )
1581            },
1582        }
1583    }
1584}
1585pub struct CompilationMessage {
1586    pub(crate) extensions: Vec<CompilationMessageExtension>,
1587    pub message: Option<String>,
1588    pub r#type: Option<CompilationMessageType>,
1589    pub line_num: Option<u64>,
1590    pub line_pos: Option<u64>,
1591    pub offset: Option<u64>,
1592    pub length: Option<u64>,
1593}
1594impl Default for CompilationMessage {
1595    fn default() -> Self {
1596        Self {
1597            extensions: Vec::new(),
1598            message: None,
1599            r#type: None,
1600            line_num: None,
1601            line_pos: None,
1602            offset: None,
1603            length: None,
1604        }
1605    }
1606}
1607impl CompilationMessage {
1608    pub fn new() -> Self {
1609        Self::default()
1610    }
1611    pub(crate) fn to_ffi(&self) -> (ffi::WGPUCompilationMessage, ChainedStructStorage) {
1612        let mut storage = ChainedStructStorage::new();
1613        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1614        for ext in self.extensions.iter().rev() {
1615            next = ext.push_chain(&mut storage, next);
1616        }
1617        let mut raw: ffi::WGPUCompilationMessage = unsafe { std::mem::zeroed() };
1618        raw.nextInChain = next;
1619        if let Some(value) = &self.message {
1620            raw.message = ffi::WGPUStringView {
1621                data: value.as_ptr().cast(),
1622                length: value.len(),
1623            };
1624        } else {
1625            raw.message = ffi::WGPUStringView {
1626                data: std::ptr::null(),
1627                length: 0,
1628            };
1629        }
1630        if let Some(value) = self.r#type {
1631            raw.type_ = value.into();
1632        } else {
1633            raw.type_ = 0 as ffi::WGPUCompilationMessageType;
1634        }
1635        if let Some(value) = self.line_num {
1636            raw.lineNum = value;
1637        }
1638        if let Some(value) = self.line_pos {
1639            raw.linePos = value;
1640        }
1641        if let Some(value) = self.offset {
1642            raw.offset = value;
1643        }
1644        if let Some(value) = self.length {
1645            raw.length = value;
1646        }
1647        (raw, storage)
1648    }
1649    pub fn with_extension(mut self, extension: CompilationMessageExtension) -> Self {
1650        self.extensions.push(extension);
1651        self
1652    }
1653    pub(crate) fn from_ffi(value: ffi::WGPUCompilationMessage) -> Self {
1654        Self {
1655            extensions: Vec::new(),
1656            message: Some(string_view_to_string(value.message)),
1657            r#type: Some(value.type_.into()),
1658            line_num: Some(value.lineNum),
1659            line_pos: Some(value.linePos),
1660            offset: Some(value.offset),
1661            length: Some(value.length),
1662        }
1663    }
1664}
1665pub struct ComputePassDescriptor {
1666    pub(crate) extensions: Vec<ComputePassDescriptorExtension>,
1667    pub label: Option<String>,
1668    pub timestamp_writes: Option<PassTimestampWrites>,
1669}
1670impl Default for ComputePassDescriptor {
1671    fn default() -> Self {
1672        Self {
1673            extensions: Vec::new(),
1674            label: None,
1675            timestamp_writes: None,
1676        }
1677    }
1678}
1679impl ComputePassDescriptor {
1680    pub fn new() -> Self {
1681        Self::default()
1682    }
1683    pub(crate) fn to_ffi(
1684        &self,
1685    ) -> (ffi::WGPUComputePassDescriptor, ChainedStructStorage) {
1686        let mut storage = ChainedStructStorage::new();
1687        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1688        for ext in self.extensions.iter().rev() {
1689            next = ext.push_chain(&mut storage, next);
1690        }
1691        let mut raw: ffi::WGPUComputePassDescriptor = unsafe { std::mem::zeroed() };
1692        raw.nextInChain = next;
1693        if let Some(value) = &self.label {
1694            raw.label = ffi::WGPUStringView {
1695                data: value.as_ptr().cast(),
1696                length: value.len(),
1697            };
1698        } else {
1699            raw.label = ffi::WGPUStringView {
1700                data: std::ptr::null(),
1701                length: 0,
1702            };
1703        }
1704        if let Some(value) = &self.timestamp_writes {
1705            let (raw_value, storage_value) = value.to_ffi();
1706            let ptr = storage.push_value(raw_value);
1707            raw.timestampWrites = ptr;
1708            storage.push_storage(storage_value);
1709        } else {
1710            raw.timestampWrites = std::ptr::null();
1711        }
1712        (raw, storage)
1713    }
1714    pub fn with_extension(mut self, extension: ComputePassDescriptorExtension) -> Self {
1715        self.extensions.push(extension);
1716        self
1717    }
1718    pub(crate) fn from_ffi(value: ffi::WGPUComputePassDescriptor) -> Self {
1719        Self {
1720            extensions: Vec::new(),
1721            label: if value.label.data.is_null() || value.label.length == 0 {
1722                None
1723            } else {
1724                Some(string_view_to_string(value.label))
1725            },
1726            timestamp_writes: if value.timestampWrites.is_null() {
1727                None
1728            } else {
1729                Some(PassTimestampWrites::from_ffi(unsafe { *value.timestampWrites }))
1730            },
1731        }
1732    }
1733}
1734pub struct ComputePipelineDescriptor {
1735    pub(crate) extensions: Vec<ComputePipelineDescriptorExtension>,
1736    pub label: Option<String>,
1737    pub layout: Option<PipelineLayout>,
1738    pub compute: Option<ComputeState>,
1739}
1740impl Default for ComputePipelineDescriptor {
1741    fn default() -> Self {
1742        Self {
1743            extensions: Vec::new(),
1744            label: None,
1745            layout: None,
1746            compute: None,
1747        }
1748    }
1749}
1750impl ComputePipelineDescriptor {
1751    pub fn new() -> Self {
1752        Self::default()
1753    }
1754    pub(crate) fn to_ffi(
1755        &self,
1756    ) -> (ffi::WGPUComputePipelineDescriptor, ChainedStructStorage) {
1757        let mut storage = ChainedStructStorage::new();
1758        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1759        for ext in self.extensions.iter().rev() {
1760            next = ext.push_chain(&mut storage, next);
1761        }
1762        let mut raw: ffi::WGPUComputePipelineDescriptor = unsafe { std::mem::zeroed() };
1763        raw.nextInChain = next;
1764        if let Some(value) = &self.label {
1765            raw.label = ffi::WGPUStringView {
1766                data: value.as_ptr().cast(),
1767                length: value.len(),
1768            };
1769        } else {
1770            raw.label = ffi::WGPUStringView {
1771                data: std::ptr::null(),
1772                length: 0,
1773            };
1774        }
1775        raw.layout = self
1776            .layout
1777            .as_ref()
1778            .map(|v| v.as_raw())
1779            .unwrap_or(std::ptr::null_mut());
1780        if let Some(value) = &self.compute {
1781            let (raw_value, storage_value) = value.to_ffi();
1782            raw.compute = raw_value;
1783            storage.push_storage(storage_value);
1784        }
1785        (raw, storage)
1786    }
1787    pub fn with_extension(
1788        mut self,
1789        extension: ComputePipelineDescriptorExtension,
1790    ) -> Self {
1791        self.extensions.push(extension);
1792        self
1793    }
1794    pub(crate) fn from_ffi(value: ffi::WGPUComputePipelineDescriptor) -> Self {
1795        Self {
1796            extensions: Vec::new(),
1797            label: if value.label.data.is_null() || value.label.length == 0 {
1798                None
1799            } else {
1800                Some(string_view_to_string(value.label))
1801            },
1802            layout: if value.layout.is_null() {
1803                None
1804            } else {
1805                Some(unsafe { PipelineLayout::from_raw(value.layout) })
1806            },
1807            compute: Some(ComputeState::from_ffi(value.compute)),
1808        }
1809    }
1810}
1811pub struct ComputeState {
1812    pub(crate) extensions: Vec<ComputeStateExtension>,
1813    pub module: Option<ShaderModule>,
1814    pub entry_point: Option<String>,
1815    pub constants: Option<Vec<ConstantEntry>>,
1816}
1817impl Default for ComputeState {
1818    fn default() -> Self {
1819        Self {
1820            extensions: Vec::new(),
1821            module: None,
1822            entry_point: None,
1823            constants: None,
1824        }
1825    }
1826}
1827impl ComputeState {
1828    pub fn new() -> Self {
1829        Self::default()
1830    }
1831    pub(crate) fn to_ffi(&self) -> (ffi::WGPUComputeState, ChainedStructStorage) {
1832        let mut storage = ChainedStructStorage::new();
1833        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1834        for ext in self.extensions.iter().rev() {
1835            next = ext.push_chain(&mut storage, next);
1836        }
1837        let mut raw: ffi::WGPUComputeState = unsafe { std::mem::zeroed() };
1838        raw.nextInChain = next;
1839        raw.module = self
1840            .module
1841            .as_ref()
1842            .map(|v| v.as_raw())
1843            .unwrap_or(std::ptr::null_mut());
1844        if let Some(value) = &self.entry_point {
1845            raw.entryPoint = ffi::WGPUStringView {
1846                data: value.as_ptr().cast(),
1847                length: value.len(),
1848            };
1849        } else {
1850            raw.entryPoint = ffi::WGPUStringView {
1851                data: std::ptr::null(),
1852                length: 0,
1853            };
1854        }
1855        raw.constantCount = self.constants.as_ref().map(|v| v.len()).unwrap_or(0);
1856        if let Some(values) = &self.constants {
1857            let len_value = values.len();
1858            let mut raw_vec: Vec<ffi::WGPUConstantEntry> = Vec::with_capacity(
1859                values.len(),
1860            );
1861            for item in values.iter() {
1862                let (raw_item, storage_item) = item.to_ffi();
1863                raw_vec.push(raw_item);
1864                storage.push_storage(storage_item);
1865            }
1866            let ptr = storage.push_vec(raw_vec);
1867            raw.constants = ptr;
1868            raw.constantCount = len_value;
1869        } else {
1870            raw.constants = std::ptr::null();
1871            raw.constantCount = 0;
1872        }
1873        (raw, storage)
1874    }
1875    pub fn with_extension(mut self, extension: ComputeStateExtension) -> Self {
1876        self.extensions.push(extension);
1877        self
1878    }
1879    pub(crate) fn from_ffi(value: ffi::WGPUComputeState) -> Self {
1880        Self {
1881            extensions: Vec::new(),
1882            module: Some(unsafe { ShaderModule::from_raw(value.module) }),
1883            entry_point: if value.entryPoint.data.is_null()
1884                || value.entryPoint.length == 0
1885            {
1886                None
1887            } else {
1888                Some(string_view_to_string(value.entryPoint))
1889            },
1890            constants: if value.constants.is_null() {
1891                None
1892            } else {
1893                Some(
1894                    unsafe {
1895                        std::slice::from_raw_parts(
1896                            value.constants,
1897                            value.constantCount as usize,
1898                        )
1899                    }
1900                        .iter()
1901                        .map(|raw| ConstantEntry::from_ffi(*raw))
1902                        .collect(),
1903                )
1904            },
1905        }
1906    }
1907}
1908pub struct ConstantEntry {
1909    pub(crate) extensions: Vec<ConstantEntryExtension>,
1910    pub key: Option<String>,
1911    pub value: Option<f64>,
1912}
1913impl Default for ConstantEntry {
1914    fn default() -> Self {
1915        Self {
1916            extensions: Vec::new(),
1917            key: None,
1918            value: None,
1919        }
1920    }
1921}
1922impl ConstantEntry {
1923    pub fn new() -> Self {
1924        Self::default()
1925    }
1926    pub(crate) fn to_ffi(&self) -> (ffi::WGPUConstantEntry, ChainedStructStorage) {
1927        let mut storage = ChainedStructStorage::new();
1928        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1929        for ext in self.extensions.iter().rev() {
1930            next = ext.push_chain(&mut storage, next);
1931        }
1932        let mut raw: ffi::WGPUConstantEntry = unsafe { std::mem::zeroed() };
1933        raw.nextInChain = next;
1934        if let Some(value) = &self.key {
1935            raw.key = ffi::WGPUStringView {
1936                data: value.as_ptr().cast(),
1937                length: value.len(),
1938            };
1939        } else {
1940            raw.key = ffi::WGPUStringView {
1941                data: std::ptr::null(),
1942                length: 0,
1943            };
1944        }
1945        if let Some(value) = self.value {
1946            raw.value = value;
1947        }
1948        (raw, storage)
1949    }
1950    pub fn with_extension(mut self, extension: ConstantEntryExtension) -> Self {
1951        self.extensions.push(extension);
1952        self
1953    }
1954    pub(crate) fn from_ffi(value: ffi::WGPUConstantEntry) -> Self {
1955        Self {
1956            extensions: Vec::new(),
1957            key: Some(string_view_to_string(value.key)),
1958            value: Some(value.value),
1959        }
1960    }
1961}
1962pub struct CopyTextureForBrowserOptions {
1963    pub(crate) extensions: Vec<CopyTextureForBrowserOptionsExtension>,
1964    pub flip_y: Option<bool>,
1965    pub needs_color_space_conversion: Option<bool>,
1966    pub src_alpha_mode: Option<AlphaMode>,
1967    pub src_transfer_function_parameters: Option<Vec<f32>>,
1968    pub conversion_matrix: Option<Vec<f32>>,
1969    pub dst_transfer_function_parameters: Option<Vec<f32>>,
1970    pub dst_alpha_mode: Option<AlphaMode>,
1971    pub internal_usage: Option<bool>,
1972}
1973impl Default for CopyTextureForBrowserOptions {
1974    fn default() -> Self {
1975        Self {
1976            extensions: Vec::new(),
1977            flip_y: None,
1978            needs_color_space_conversion: None,
1979            src_alpha_mode: Some(AlphaMode::Unpremultiplied),
1980            src_transfer_function_parameters: None,
1981            conversion_matrix: None,
1982            dst_transfer_function_parameters: None,
1983            dst_alpha_mode: Some(AlphaMode::Unpremultiplied),
1984            internal_usage: None,
1985        }
1986    }
1987}
1988impl CopyTextureForBrowserOptions {
1989    pub fn new() -> Self {
1990        Self::default()
1991    }
1992    pub(crate) fn to_ffi(
1993        &self,
1994    ) -> (ffi::WGPUCopyTextureForBrowserOptions, ChainedStructStorage) {
1995        let mut storage = ChainedStructStorage::new();
1996        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
1997        for ext in self.extensions.iter().rev() {
1998            next = ext.push_chain(&mut storage, next);
1999        }
2000        let mut raw: ffi::WGPUCopyTextureForBrowserOptions = unsafe {
2001            std::mem::zeroed()
2002        };
2003        raw.nextInChain = next;
2004        raw.flipY = if self.flip_y.unwrap_or(false) { 1 } else { 0 };
2005        raw.needsColorSpaceConversion = if self
2006            .needs_color_space_conversion
2007            .unwrap_or(false)
2008        {
2009            1
2010        } else {
2011            0
2012        };
2013        if let Some(value) = self.src_alpha_mode {
2014            raw.srcAlphaMode = value.into();
2015        } else {
2016            raw.srcAlphaMode = 0 as ffi::WGPUAlphaMode;
2017        }
2018        if let Some(values) = &self.src_transfer_function_parameters {
2019            let len_value = values.len();
2020            let raw_vec = values.to_vec();
2021            let ptr = storage.push_vec(raw_vec);
2022            raw.srcTransferFunctionParameters = ptr;
2023        } else {
2024            raw.srcTransferFunctionParameters = std::ptr::null();
2025            let _ = 0;
2026        }
2027        if let Some(values) = &self.conversion_matrix {
2028            let len_value = values.len();
2029            let raw_vec = values.to_vec();
2030            let ptr = storage.push_vec(raw_vec);
2031            raw.conversionMatrix = ptr;
2032        } else {
2033            raw.conversionMatrix = std::ptr::null();
2034            let _ = 0;
2035        }
2036        if let Some(values) = &self.dst_transfer_function_parameters {
2037            let len_value = values.len();
2038            let raw_vec = values.to_vec();
2039            let ptr = storage.push_vec(raw_vec);
2040            raw.dstTransferFunctionParameters = ptr;
2041        } else {
2042            raw.dstTransferFunctionParameters = std::ptr::null();
2043            let _ = 0;
2044        }
2045        if let Some(value) = self.dst_alpha_mode {
2046            raw.dstAlphaMode = value.into();
2047        } else {
2048            raw.dstAlphaMode = 0 as ffi::WGPUAlphaMode;
2049        }
2050        raw.internalUsage = if self.internal_usage.unwrap_or(false) { 1 } else { 0 };
2051        (raw, storage)
2052    }
2053    pub fn with_extension(
2054        mut self,
2055        extension: CopyTextureForBrowserOptionsExtension,
2056    ) -> Self {
2057        self.extensions.push(extension);
2058        self
2059    }
2060    pub(crate) fn from_ffi(value: ffi::WGPUCopyTextureForBrowserOptions) -> Self {
2061        Self {
2062            extensions: Vec::new(),
2063            flip_y: Some(value.flipY != 0),
2064            needs_color_space_conversion: Some(value.needsColorSpaceConversion != 0),
2065            src_alpha_mode: Some(value.srcAlphaMode.into()),
2066            src_transfer_function_parameters: if value
2067                .srcTransferFunctionParameters
2068                .is_null()
2069            {
2070                None
2071            } else {
2072                Some(
2073                    unsafe {
2074                        std::slice::from_raw_parts(
2075                            value.srcTransferFunctionParameters,
2076                            7usize,
2077                        )
2078                    }
2079                        .to_vec(),
2080                )
2081            },
2082            conversion_matrix: if value.conversionMatrix.is_null() {
2083                None
2084            } else {
2085                Some(
2086                    unsafe { std::slice::from_raw_parts(value.conversionMatrix, 9usize) }
2087                        .to_vec(),
2088                )
2089            },
2090            dst_transfer_function_parameters: if value
2091                .dstTransferFunctionParameters
2092                .is_null()
2093            {
2094                None
2095            } else {
2096                Some(
2097                    unsafe {
2098                        std::slice::from_raw_parts(
2099                            value.dstTransferFunctionParameters,
2100                            7usize,
2101                        )
2102                    }
2103                        .to_vec(),
2104                )
2105            },
2106            dst_alpha_mode: Some(value.dstAlphaMode.into()),
2107            internal_usage: Some(value.internalUsage != 0),
2108        }
2109    }
2110}
2111pub struct DawnWGSLBlocklist {
2112    pub blocklisted_features: Option<Vec<String>>,
2113}
2114impl Default for DawnWGSLBlocklist {
2115    fn default() -> Self {
2116        Self { blocklisted_features: None }
2117    }
2118}
2119impl DawnWGSLBlocklist {
2120    pub fn new() -> Self {
2121        Self::default()
2122    }
2123    pub(crate) fn to_ffi(&self) -> (ffi::WGPUDawnWGSLBlocklist, ChainedStructStorage) {
2124        let mut storage = ChainedStructStorage::new();
2125        let mut raw: ffi::WGPUDawnWGSLBlocklist = unsafe { std::mem::zeroed() };
2126        raw.blocklistedFeatureCount = self
2127            .blocklisted_features
2128            .as_ref()
2129            .map(|v| v.len())
2130            .unwrap_or(0);
2131        if let Some(values) = &self.blocklisted_features {
2132            let len_value = values.len();
2133            let mut c_strings: Vec<std::ffi::CString> = Vec::with_capacity(values.len());
2134            let mut ptrs: Vec<*const std::os::raw::c_char> = Vec::with_capacity(
2135                values.len(),
2136            );
2137            for item in values.iter() {
2138                let c_string = std::ffi::CString::new(item.as_str())
2139                    .unwrap_or_else(|_| std::ffi::CString::new("").unwrap());
2140                ptrs.push(c_string.as_ptr());
2141                c_strings.push(c_string);
2142            }
2143            let ptr = storage.push_vec(ptrs);
2144            storage.push_any(c_strings);
2145            raw.blocklistedFeatures = ptr;
2146            raw.blocklistedFeatureCount = len_value;
2147        } else {
2148            raw.blocklistedFeatures = std::ptr::null();
2149            raw.blocklistedFeatureCount = 0;
2150        }
2151        (raw, storage)
2152    }
2153    pub(crate) fn from_ffi(value: ffi::WGPUDawnWGSLBlocklist) -> Self {
2154        Self {
2155            blocklisted_features: if value.blocklistedFeatures.is_null() {
2156                None
2157            } else {
2158                Some(
2159                    unsafe {
2160                        std::slice::from_raw_parts(
2161                            value.blocklistedFeatures,
2162                            value.blocklistedFeatureCount as usize,
2163                        )
2164                    }
2165                        .iter()
2166                        .map(|raw| {
2167                            if raw.is_null() {
2168                                String::new()
2169                            } else {
2170                                unsafe { CStr::from_ptr(*raw) }
2171                                    .to_string_lossy()
2172                                    .into_owned()
2173                            }
2174                        })
2175                        .collect(),
2176                )
2177            },
2178        }
2179    }
2180}
2181pub struct DawnAdapterPropertiesPowerPreference {
2182    pub power_preference: Option<PowerPreference>,
2183}
2184impl Default for DawnAdapterPropertiesPowerPreference {
2185    fn default() -> Self {
2186        Self { power_preference: None }
2187    }
2188}
2189impl DawnAdapterPropertiesPowerPreference {
2190    pub fn new() -> Self {
2191        Self::default()
2192    }
2193    pub(crate) fn to_ffi(
2194        &self,
2195    ) -> (ffi::WGPUDawnAdapterPropertiesPowerPreference, ChainedStructStorage) {
2196        let mut storage = ChainedStructStorage::new();
2197        let mut raw: ffi::WGPUDawnAdapterPropertiesPowerPreference = unsafe {
2198            std::mem::zeroed()
2199        };
2200        if let Some(value) = self.power_preference {
2201            raw.powerPreference = value.into();
2202        } else {
2203            raw.powerPreference = 0 as ffi::WGPUPowerPreference;
2204        }
2205        (raw, storage)
2206    }
2207    pub(crate) fn from_ffi(
2208        value: ffi::WGPUDawnAdapterPropertiesPowerPreference,
2209    ) -> Self {
2210        Self {
2211            power_preference: Some(value.powerPreference.into()),
2212        }
2213    }
2214}
2215pub struct DawnBufferDescriptorErrorInfoFromWireClient {
2216    pub out_of_memory: Option<bool>,
2217}
2218impl Default for DawnBufferDescriptorErrorInfoFromWireClient {
2219    fn default() -> Self {
2220        Self { out_of_memory: None }
2221    }
2222}
2223impl DawnBufferDescriptorErrorInfoFromWireClient {
2224    pub fn new() -> Self {
2225        Self::default()
2226    }
2227    pub(crate) fn to_ffi(
2228        &self,
2229    ) -> (ffi::WGPUDawnBufferDescriptorErrorInfoFromWireClient, ChainedStructStorage) {
2230        let mut storage = ChainedStructStorage::new();
2231        let mut raw: ffi::WGPUDawnBufferDescriptorErrorInfoFromWireClient = unsafe {
2232            std::mem::zeroed()
2233        };
2234        raw.outOfMemory = if self.out_of_memory.unwrap_or(false) { 1 } else { 0 };
2235        (raw, storage)
2236    }
2237    pub(crate) fn from_ffi(
2238        value: ffi::WGPUDawnBufferDescriptorErrorInfoFromWireClient,
2239    ) -> Self {
2240        Self {
2241            out_of_memory: Some(value.outOfMemory != 0),
2242        }
2243    }
2244}
2245pub struct DawnCacheDeviceDescriptor {
2246    pub isolation_key: Option<String>,
2247    pub load_data_function: Option<DawnLoadCacheDataFunction>,
2248    pub store_data_function: Option<DawnStoreCacheDataFunction>,
2249    pub function_userdata: Option<*mut std::ffi::c_void>,
2250}
2251impl Default for DawnCacheDeviceDescriptor {
2252    fn default() -> Self {
2253        Self {
2254            isolation_key: None,
2255            load_data_function: None,
2256            store_data_function: None,
2257            function_userdata: None,
2258        }
2259    }
2260}
2261impl DawnCacheDeviceDescriptor {
2262    pub fn new() -> Self {
2263        Self::default()
2264    }
2265    pub(crate) fn to_ffi(
2266        &self,
2267    ) -> (ffi::WGPUDawnCacheDeviceDescriptor, ChainedStructStorage) {
2268        let mut storage = ChainedStructStorage::new();
2269        let mut raw: ffi::WGPUDawnCacheDeviceDescriptor = unsafe { std::mem::zeroed() };
2270        if let Some(value) = &self.isolation_key {
2271            raw.isolationKey = ffi::WGPUStringView {
2272                data: value.as_ptr().cast(),
2273                length: value.len(),
2274            };
2275        } else {
2276            raw.isolationKey = ffi::WGPUStringView {
2277                data: std::ptr::null(),
2278                length: 0,
2279            };
2280        }
2281        if let Some(value) = self.load_data_function {
2282            raw.loadDataFunction = value;
2283        }
2284        if let Some(value) = self.store_data_function {
2285            raw.storeDataFunction = value;
2286        }
2287        if let Some(value) = self.function_userdata {
2288            raw.functionUserdata = value;
2289        }
2290        (raw, storage)
2291    }
2292    pub(crate) fn from_ffi(value: ffi::WGPUDawnCacheDeviceDescriptor) -> Self {
2293        Self {
2294            isolation_key: Some(string_view_to_string(value.isolationKey)),
2295            load_data_function: Some(value.loadDataFunction),
2296            store_data_function: Some(value.storeDataFunction),
2297            function_userdata: Some(value.functionUserdata),
2298        }
2299    }
2300}
2301pub struct DawnCompilationMessageUtf16 {
2302    pub line_pos: Option<u64>,
2303    pub offset: Option<u64>,
2304    pub length: Option<u64>,
2305}
2306impl Default for DawnCompilationMessageUtf16 {
2307    fn default() -> Self {
2308        Self {
2309            line_pos: None,
2310            offset: None,
2311            length: None,
2312        }
2313    }
2314}
2315impl DawnCompilationMessageUtf16 {
2316    pub fn new() -> Self {
2317        Self::default()
2318    }
2319    pub(crate) fn to_ffi(
2320        &self,
2321    ) -> (ffi::WGPUDawnCompilationMessageUtf16, ChainedStructStorage) {
2322        let mut storage = ChainedStructStorage::new();
2323        let mut raw: ffi::WGPUDawnCompilationMessageUtf16 = unsafe {
2324            std::mem::zeroed()
2325        };
2326        if let Some(value) = self.line_pos {
2327            raw.linePos = value;
2328        }
2329        if let Some(value) = self.offset {
2330            raw.offset = value;
2331        }
2332        if let Some(value) = self.length {
2333            raw.length = value;
2334        }
2335        (raw, storage)
2336    }
2337    pub(crate) fn from_ffi(value: ffi::WGPUDawnCompilationMessageUtf16) -> Self {
2338        Self {
2339            line_pos: Some(value.linePos),
2340            offset: Some(value.offset),
2341            length: Some(value.length),
2342        }
2343    }
2344}
2345pub struct DawnConsumeAdapterDescriptor {
2346    pub consume_adapter: Option<bool>,
2347}
2348impl Default for DawnConsumeAdapterDescriptor {
2349    fn default() -> Self {
2350        Self { consume_adapter: None }
2351    }
2352}
2353impl DawnConsumeAdapterDescriptor {
2354    pub fn new() -> Self {
2355        Self::default()
2356    }
2357    pub(crate) fn to_ffi(
2358        &self,
2359    ) -> (ffi::WGPUDawnConsumeAdapterDescriptor, ChainedStructStorage) {
2360        let mut storage = ChainedStructStorage::new();
2361        let mut raw: ffi::WGPUDawnConsumeAdapterDescriptor = unsafe {
2362            std::mem::zeroed()
2363        };
2364        raw.consumeAdapter = if self.consume_adapter.unwrap_or(false) { 1 } else { 0 };
2365        (raw, storage)
2366    }
2367    pub(crate) fn from_ffi(value: ffi::WGPUDawnConsumeAdapterDescriptor) -> Self {
2368        Self {
2369            consume_adapter: Some(value.consumeAdapter != 0),
2370        }
2371    }
2372}
2373pub struct DawnDeviceAllocatorControl {
2374    pub allocator_heap_block_size: Option<usize>,
2375}
2376impl Default for DawnDeviceAllocatorControl {
2377    fn default() -> Self {
2378        Self {
2379            allocator_heap_block_size: Some(0),
2380        }
2381    }
2382}
2383impl DawnDeviceAllocatorControl {
2384    pub fn new() -> Self {
2385        Self::default()
2386    }
2387    pub(crate) fn to_ffi(
2388        &self,
2389    ) -> (ffi::WGPUDawnDeviceAllocatorControl, ChainedStructStorage) {
2390        let mut storage = ChainedStructStorage::new();
2391        let mut raw: ffi::WGPUDawnDeviceAllocatorControl = unsafe { std::mem::zeroed() };
2392        if let Some(value) = self.allocator_heap_block_size {
2393            raw.allocatorHeapBlockSize = value;
2394        }
2395        (raw, storage)
2396    }
2397    pub(crate) fn from_ffi(value: ffi::WGPUDawnDeviceAllocatorControl) -> Self {
2398        Self {
2399            allocator_heap_block_size: Some(value.allocatorHeapBlockSize),
2400        }
2401    }
2402}
2403pub struct DawnDrmFormatCapabilities {
2404    pub properties: Option<Vec<DawnDrmFormatProperties>>,
2405    #[doc(hidden)]
2406    pub(crate) _free_members: Option<ffi::WGPUDawnDrmFormatCapabilities>,
2407}
2408impl Default for DawnDrmFormatCapabilities {
2409    fn default() -> Self {
2410        Self {
2411            properties: None,
2412            _free_members: None,
2413        }
2414    }
2415}
2416impl DawnDrmFormatCapabilities {
2417    pub fn new() -> Self {
2418        Self::default()
2419    }
2420    pub(crate) fn to_ffi(
2421        &self,
2422    ) -> (ffi::WGPUDawnDrmFormatCapabilities, ChainedStructStorage) {
2423        let mut storage = ChainedStructStorage::new();
2424        let mut raw: ffi::WGPUDawnDrmFormatCapabilities = unsafe { std::mem::zeroed() };
2425        raw.propertiesCount = self.properties.as_ref().map(|v| v.len()).unwrap_or(0);
2426        if let Some(values) = &self.properties {
2427            let len_value = values.len();
2428            let mut raw_vec: Vec<ffi::WGPUDawnDrmFormatProperties> = Vec::with_capacity(
2429                values.len(),
2430            );
2431            for item in values.iter() {
2432                let (raw_item, storage_item) = item.to_ffi();
2433                raw_vec.push(raw_item);
2434                storage.push_storage(storage_item);
2435            }
2436            let ptr = storage.push_vec(raw_vec);
2437            raw.properties = ptr;
2438            raw.propertiesCount = len_value;
2439        } else {
2440            raw.properties = std::ptr::null();
2441            raw.propertiesCount = 0;
2442        }
2443        (raw, storage)
2444    }
2445    pub(crate) fn from_ffi(value: ffi::WGPUDawnDrmFormatCapabilities) -> Self {
2446        Self {
2447            properties: if value.properties.is_null() {
2448                None
2449            } else {
2450                Some(
2451                    unsafe {
2452                        std::slice::from_raw_parts(
2453                            value.properties,
2454                            value.propertiesCount as usize,
2455                        )
2456                    }
2457                        .iter()
2458                        .map(|raw| DawnDrmFormatProperties::from_ffi(*raw))
2459                        .collect(),
2460                )
2461            },
2462            _free_members: Some(value),
2463        }
2464    }
2465    pub(crate) fn free_members(value: ffi::WGPUDawnDrmFormatCapabilities) {
2466        unsafe { ffi::wgpuDawnDrmFormatCapabilitiesFreeMembers(value) };
2467    }
2468}
2469impl Drop for DawnDrmFormatCapabilities {
2470    fn drop(&mut self) {
2471        if let Some(value) = self._free_members.take() {
2472            unsafe { ffi::wgpuDawnDrmFormatCapabilitiesFreeMembers(value) };
2473        }
2474    }
2475}
2476pub struct DawnDrmFormatProperties {
2477    pub modifier: Option<u64>,
2478    pub modifier_plane_count: Option<u32>,
2479}
2480impl Default for DawnDrmFormatProperties {
2481    fn default() -> Self {
2482        Self {
2483            modifier: None,
2484            modifier_plane_count: None,
2485        }
2486    }
2487}
2488impl DawnDrmFormatProperties {
2489    pub fn new() -> Self {
2490        Self::default()
2491    }
2492    pub(crate) fn to_ffi(
2493        &self,
2494    ) -> (ffi::WGPUDawnDrmFormatProperties, ChainedStructStorage) {
2495        let mut storage = ChainedStructStorage::new();
2496        let mut raw: ffi::WGPUDawnDrmFormatProperties = unsafe { std::mem::zeroed() };
2497        if let Some(value) = self.modifier {
2498            raw.modifier = value;
2499        }
2500        if let Some(value) = self.modifier_plane_count {
2501            raw.modifierPlaneCount = value;
2502        }
2503        (raw, storage)
2504    }
2505    pub(crate) fn from_ffi(value: ffi::WGPUDawnDrmFormatProperties) -> Self {
2506        Self {
2507            modifier: Some(value.modifier),
2508            modifier_plane_count: Some(value.modifierPlaneCount),
2509        }
2510    }
2511}
2512pub struct DawnEncoderInternalUsageDescriptor {
2513    pub use_internal_usages: Option<bool>,
2514}
2515impl Default for DawnEncoderInternalUsageDescriptor {
2516    fn default() -> Self {
2517        Self { use_internal_usages: None }
2518    }
2519}
2520impl DawnEncoderInternalUsageDescriptor {
2521    pub fn new() -> Self {
2522        Self::default()
2523    }
2524    pub(crate) fn to_ffi(
2525        &self,
2526    ) -> (ffi::WGPUDawnEncoderInternalUsageDescriptor, ChainedStructStorage) {
2527        let mut storage = ChainedStructStorage::new();
2528        let mut raw: ffi::WGPUDawnEncoderInternalUsageDescriptor = unsafe {
2529            std::mem::zeroed()
2530        };
2531        raw.useInternalUsages = if self.use_internal_usages.unwrap_or(false) {
2532            1
2533        } else {
2534            0
2535        };
2536        (raw, storage)
2537    }
2538    pub(crate) fn from_ffi(value: ffi::WGPUDawnEncoderInternalUsageDescriptor) -> Self {
2539        Self {
2540            use_internal_usages: Some(value.useInternalUsages != 0),
2541        }
2542    }
2543}
2544pub struct DawnFakeBufferOOMForTesting {
2545    pub fake_oom_at_wire_client_map: Option<bool>,
2546    pub fake_oom_at_native_map: Option<bool>,
2547    pub fake_oom_at_device: Option<bool>,
2548}
2549impl Default for DawnFakeBufferOOMForTesting {
2550    fn default() -> Self {
2551        Self {
2552            fake_oom_at_wire_client_map: None,
2553            fake_oom_at_native_map: None,
2554            fake_oom_at_device: None,
2555        }
2556    }
2557}
2558impl DawnFakeBufferOOMForTesting {
2559    pub fn new() -> Self {
2560        Self::default()
2561    }
2562    pub(crate) fn to_ffi(
2563        &self,
2564    ) -> (ffi::WGPUDawnFakeBufferOOMForTesting, ChainedStructStorage) {
2565        let mut storage = ChainedStructStorage::new();
2566        let mut raw: ffi::WGPUDawnFakeBufferOOMForTesting = unsafe {
2567            std::mem::zeroed()
2568        };
2569        raw.fakeOOMAtWireClientMap = if self.fake_oom_at_wire_client_map.unwrap_or(false)
2570        {
2571            1
2572        } else {
2573            0
2574        };
2575        raw.fakeOOMAtNativeMap = if self.fake_oom_at_native_map.unwrap_or(false) {
2576            1
2577        } else {
2578            0
2579        };
2580        raw.fakeOOMAtDevice = if self.fake_oom_at_device.unwrap_or(false) {
2581            1
2582        } else {
2583            0
2584        };
2585        (raw, storage)
2586    }
2587    pub(crate) fn from_ffi(value: ffi::WGPUDawnFakeBufferOOMForTesting) -> Self {
2588        Self {
2589            fake_oom_at_wire_client_map: Some(value.fakeOOMAtWireClientMap != 0),
2590            fake_oom_at_native_map: Some(value.fakeOOMAtNativeMap != 0),
2591            fake_oom_at_device: Some(value.fakeOOMAtDevice != 0),
2592        }
2593    }
2594}
2595pub struct DawnFakeDeviceInitializeErrorForTesting {}
2596impl Default for DawnFakeDeviceInitializeErrorForTesting {
2597    fn default() -> Self {
2598        Self {}
2599    }
2600}
2601impl DawnFakeDeviceInitializeErrorForTesting {
2602    pub fn new() -> Self {
2603        Self::default()
2604    }
2605    pub(crate) fn to_ffi(
2606        &self,
2607    ) -> (ffi::WGPUDawnFakeDeviceInitializeErrorForTesting, ChainedStructStorage) {
2608        let mut storage = ChainedStructStorage::new();
2609        let mut raw: ffi::WGPUDawnFakeDeviceInitializeErrorForTesting = unsafe {
2610            std::mem::zeroed()
2611        };
2612        (raw, storage)
2613    }
2614    pub(crate) fn from_ffi(
2615        value: ffi::WGPUDawnFakeDeviceInitializeErrorForTesting,
2616    ) -> Self {
2617        let _ = value;
2618        Self::default()
2619    }
2620}
2621pub struct DawnFormatCapabilities {
2622    pub(crate) extensions: Vec<DawnFormatCapabilitiesExtension>,
2623}
2624impl Default for DawnFormatCapabilities {
2625    fn default() -> Self {
2626        Self { extensions: Vec::new() }
2627    }
2628}
2629impl DawnFormatCapabilities {
2630    pub fn new() -> Self {
2631        Self::default()
2632    }
2633    pub(crate) fn to_ffi(
2634        &self,
2635    ) -> (ffi::WGPUDawnFormatCapabilities, ChainedStructStorage) {
2636        let mut storage = ChainedStructStorage::new();
2637        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
2638        for ext in self.extensions.iter().rev() {
2639            next = ext.push_chain(&mut storage, next);
2640        }
2641        let mut raw: ffi::WGPUDawnFormatCapabilities = unsafe { std::mem::zeroed() };
2642        raw.nextInChain = next;
2643        (raw, storage)
2644    }
2645    pub fn with_extension(mut self, extension: DawnFormatCapabilitiesExtension) -> Self {
2646        self.extensions.push(extension);
2647        self
2648    }
2649    pub(crate) fn from_ffi(value: ffi::WGPUDawnFormatCapabilities) -> Self {
2650        Self { extensions: Vec::new() }
2651    }
2652}
2653pub struct DawnHostMappedPointerLimits {
2654    pub host_mapped_pointer_alignment: Option<u32>,
2655}
2656impl Default for DawnHostMappedPointerLimits {
2657    fn default() -> Self {
2658        Self {
2659            host_mapped_pointer_alignment: Some(LIMIT_U32_UNDEFINED),
2660        }
2661    }
2662}
2663impl DawnHostMappedPointerLimits {
2664    pub fn new() -> Self {
2665        Self::default()
2666    }
2667    pub(crate) fn to_ffi(
2668        &self,
2669    ) -> (ffi::WGPUDawnHostMappedPointerLimits, ChainedStructStorage) {
2670        let mut storage = ChainedStructStorage::new();
2671        let mut raw: ffi::WGPUDawnHostMappedPointerLimits = unsafe {
2672            std::mem::zeroed()
2673        };
2674        if let Some(value) = self.host_mapped_pointer_alignment {
2675            raw.hostMappedPointerAlignment = value;
2676        }
2677        (raw, storage)
2678    }
2679    pub(crate) fn from_ffi(value: ffi::WGPUDawnHostMappedPointerLimits) -> Self {
2680        Self {
2681            host_mapped_pointer_alignment: Some(value.hostMappedPointerAlignment),
2682        }
2683    }
2684}
2685pub struct DawnInjectedInvalidSType {
2686    pub invalid_s_type: Option<SType>,
2687}
2688impl Default for DawnInjectedInvalidSType {
2689    fn default() -> Self {
2690        Self { invalid_s_type: None }
2691    }
2692}
2693impl DawnInjectedInvalidSType {
2694    pub fn new() -> Self {
2695        Self::default()
2696    }
2697    pub(crate) fn to_ffi(
2698        &self,
2699    ) -> (ffi::WGPUDawnInjectedInvalidSType, ChainedStructStorage) {
2700        let mut storage = ChainedStructStorage::new();
2701        let mut raw: ffi::WGPUDawnInjectedInvalidSType = unsafe { std::mem::zeroed() };
2702        if let Some(value) = self.invalid_s_type {
2703            raw.invalidSType = value.into();
2704        } else {
2705            raw.invalidSType = 0 as ffi::WGPUSType;
2706        }
2707        (raw, storage)
2708    }
2709    pub(crate) fn from_ffi(value: ffi::WGPUDawnInjectedInvalidSType) -> Self {
2710        Self {
2711            invalid_s_type: Some(value.invalidSType.into()),
2712        }
2713    }
2714}
2715pub struct DawnRenderPassColorAttachmentRenderToSingleSampled {
2716    pub implicit_sample_count: Option<u32>,
2717}
2718impl Default for DawnRenderPassColorAttachmentRenderToSingleSampled {
2719    fn default() -> Self {
2720        Self {
2721            implicit_sample_count: Some(1),
2722        }
2723    }
2724}
2725impl DawnRenderPassColorAttachmentRenderToSingleSampled {
2726    pub fn new() -> Self {
2727        Self::default()
2728    }
2729    pub(crate) fn to_ffi(
2730        &self,
2731    ) -> (
2732        ffi::WGPUDawnRenderPassColorAttachmentRenderToSingleSampled,
2733        ChainedStructStorage,
2734    ) {
2735        let mut storage = ChainedStructStorage::new();
2736        let mut raw: ffi::WGPUDawnRenderPassColorAttachmentRenderToSingleSampled = unsafe {
2737            std::mem::zeroed()
2738        };
2739        if let Some(value) = self.implicit_sample_count {
2740            raw.implicitSampleCount = value;
2741        }
2742        (raw, storage)
2743    }
2744    pub(crate) fn from_ffi(
2745        value: ffi::WGPUDawnRenderPassColorAttachmentRenderToSingleSampled,
2746    ) -> Self {
2747        Self {
2748            implicit_sample_count: Some(value.implicitSampleCount),
2749        }
2750    }
2751}
2752pub struct DawnRenderPassSampleCount {
2753    pub sample_count: Option<u32>,
2754}
2755impl Default for DawnRenderPassSampleCount {
2756    fn default() -> Self {
2757        Self { sample_count: Some(1) }
2758    }
2759}
2760impl DawnRenderPassSampleCount {
2761    pub fn new() -> Self {
2762        Self::default()
2763    }
2764    pub(crate) fn to_ffi(
2765        &self,
2766    ) -> (ffi::WGPUDawnRenderPassSampleCount, ChainedStructStorage) {
2767        let mut storage = ChainedStructStorage::new();
2768        let mut raw: ffi::WGPUDawnRenderPassSampleCount = unsafe { std::mem::zeroed() };
2769        if let Some(value) = self.sample_count {
2770            raw.sampleCount = value;
2771        }
2772        (raw, storage)
2773    }
2774    pub(crate) fn from_ffi(value: ffi::WGPUDawnRenderPassSampleCount) -> Self {
2775        Self {
2776            sample_count: Some(value.sampleCount),
2777        }
2778    }
2779}
2780pub struct DawnShaderModuleSPIRVOptionsDescriptor {
2781    pub allow_non_uniform_derivatives: Option<bool>,
2782}
2783impl Default for DawnShaderModuleSPIRVOptionsDescriptor {
2784    fn default() -> Self {
2785        Self {
2786            allow_non_uniform_derivatives: None,
2787        }
2788    }
2789}
2790impl DawnShaderModuleSPIRVOptionsDescriptor {
2791    pub fn new() -> Self {
2792        Self::default()
2793    }
2794    pub(crate) fn to_ffi(
2795        &self,
2796    ) -> (ffi::WGPUDawnShaderModuleSPIRVOptionsDescriptor, ChainedStructStorage) {
2797        let mut storage = ChainedStructStorage::new();
2798        let mut raw: ffi::WGPUDawnShaderModuleSPIRVOptionsDescriptor = unsafe {
2799            std::mem::zeroed()
2800        };
2801        raw.allowNonUniformDerivatives = if self
2802            .allow_non_uniform_derivatives
2803            .unwrap_or(false)
2804        {
2805            1
2806        } else {
2807            0
2808        };
2809        (raw, storage)
2810    }
2811    pub(crate) fn from_ffi(
2812        value: ffi::WGPUDawnShaderModuleSPIRVOptionsDescriptor,
2813    ) -> Self {
2814        Self {
2815            allow_non_uniform_derivatives: Some(value.allowNonUniformDerivatives != 0),
2816        }
2817    }
2818}
2819pub struct DawnTexelCopyBufferRowAlignmentLimits {
2820    pub min_texel_copy_buffer_row_alignment: Option<u32>,
2821}
2822impl Default for DawnTexelCopyBufferRowAlignmentLimits {
2823    fn default() -> Self {
2824        Self {
2825            min_texel_copy_buffer_row_alignment: Some(LIMIT_U32_UNDEFINED),
2826        }
2827    }
2828}
2829impl DawnTexelCopyBufferRowAlignmentLimits {
2830    pub fn new() -> Self {
2831        Self::default()
2832    }
2833    pub(crate) fn to_ffi(
2834        &self,
2835    ) -> (ffi::WGPUDawnTexelCopyBufferRowAlignmentLimits, ChainedStructStorage) {
2836        let mut storage = ChainedStructStorage::new();
2837        let mut raw: ffi::WGPUDawnTexelCopyBufferRowAlignmentLimits = unsafe {
2838            std::mem::zeroed()
2839        };
2840        if let Some(value) = self.min_texel_copy_buffer_row_alignment {
2841            raw.minTexelCopyBufferRowAlignment = value;
2842        }
2843        (raw, storage)
2844    }
2845    pub(crate) fn from_ffi(
2846        value: ffi::WGPUDawnTexelCopyBufferRowAlignmentLimits,
2847    ) -> Self {
2848        Self {
2849            min_texel_copy_buffer_row_alignment: Some(
2850                value.minTexelCopyBufferRowAlignment,
2851            ),
2852        }
2853    }
2854}
2855pub struct DawnTextureInternalUsageDescriptor {
2856    pub internal_usage: Option<TextureUsage>,
2857}
2858impl Default for DawnTextureInternalUsageDescriptor {
2859    fn default() -> Self {
2860        Self { internal_usage: None }
2861    }
2862}
2863impl DawnTextureInternalUsageDescriptor {
2864    pub fn new() -> Self {
2865        Self::default()
2866    }
2867    pub(crate) fn to_ffi(
2868        &self,
2869    ) -> (ffi::WGPUDawnTextureInternalUsageDescriptor, ChainedStructStorage) {
2870        let mut storage = ChainedStructStorage::new();
2871        let mut raw: ffi::WGPUDawnTextureInternalUsageDescriptor = unsafe {
2872            std::mem::zeroed()
2873        };
2874        if let Some(value) = self.internal_usage {
2875            raw.internalUsage = value.into();
2876        } else {
2877            raw.internalUsage = 0 as ffi::WGPUTextureUsage;
2878        }
2879        (raw, storage)
2880    }
2881    pub(crate) fn from_ffi(value: ffi::WGPUDawnTextureInternalUsageDescriptor) -> Self {
2882        Self {
2883            internal_usage: Some(value.internalUsage.into()),
2884        }
2885    }
2886}
2887pub struct DawnTogglesDescriptor {
2888    pub enabled_toggles: Option<Vec<String>>,
2889    pub disabled_toggles: Option<Vec<String>>,
2890}
2891impl Default for DawnTogglesDescriptor {
2892    fn default() -> Self {
2893        Self {
2894            enabled_toggles: None,
2895            disabled_toggles: None,
2896        }
2897    }
2898}
2899impl DawnTogglesDescriptor {
2900    pub fn new() -> Self {
2901        Self::default()
2902    }
2903    pub(crate) fn to_ffi(
2904        &self,
2905    ) -> (ffi::WGPUDawnTogglesDescriptor, ChainedStructStorage) {
2906        let mut storage = ChainedStructStorage::new();
2907        let mut raw: ffi::WGPUDawnTogglesDescriptor = unsafe { std::mem::zeroed() };
2908        raw.enabledToggleCount = self
2909            .enabled_toggles
2910            .as_ref()
2911            .map(|v| v.len())
2912            .unwrap_or(0);
2913        if let Some(values) = &self.enabled_toggles {
2914            let len_value = values.len();
2915            let mut c_strings: Vec<std::ffi::CString> = Vec::with_capacity(values.len());
2916            let mut ptrs: Vec<*const std::os::raw::c_char> = Vec::with_capacity(
2917                values.len(),
2918            );
2919            for item in values.iter() {
2920                let c_string = std::ffi::CString::new(item.as_str())
2921                    .unwrap_or_else(|_| std::ffi::CString::new("").unwrap());
2922                ptrs.push(c_string.as_ptr());
2923                c_strings.push(c_string);
2924            }
2925            let ptr = storage.push_vec(ptrs);
2926            storage.push_any(c_strings);
2927            raw.enabledToggles = ptr;
2928            raw.enabledToggleCount = len_value;
2929        } else {
2930            raw.enabledToggles = std::ptr::null();
2931            raw.enabledToggleCount = 0;
2932        }
2933        raw.disabledToggleCount = self
2934            .disabled_toggles
2935            .as_ref()
2936            .map(|v| v.len())
2937            .unwrap_or(0);
2938        if let Some(values) = &self.disabled_toggles {
2939            let len_value = values.len();
2940            let mut c_strings: Vec<std::ffi::CString> = Vec::with_capacity(values.len());
2941            let mut ptrs: Vec<*const std::os::raw::c_char> = Vec::with_capacity(
2942                values.len(),
2943            );
2944            for item in values.iter() {
2945                let c_string = std::ffi::CString::new(item.as_str())
2946                    .unwrap_or_else(|_| std::ffi::CString::new("").unwrap());
2947                ptrs.push(c_string.as_ptr());
2948                c_strings.push(c_string);
2949            }
2950            let ptr = storage.push_vec(ptrs);
2951            storage.push_any(c_strings);
2952            raw.disabledToggles = ptr;
2953            raw.disabledToggleCount = len_value;
2954        } else {
2955            raw.disabledToggles = std::ptr::null();
2956            raw.disabledToggleCount = 0;
2957        }
2958        (raw, storage)
2959    }
2960    pub(crate) fn from_ffi(value: ffi::WGPUDawnTogglesDescriptor) -> Self {
2961        Self {
2962            enabled_toggles: if value.enabledToggles.is_null() {
2963                None
2964            } else {
2965                Some(
2966                    unsafe {
2967                        std::slice::from_raw_parts(
2968                            value.enabledToggles,
2969                            value.enabledToggleCount as usize,
2970                        )
2971                    }
2972                        .iter()
2973                        .map(|raw| {
2974                            if raw.is_null() {
2975                                String::new()
2976                            } else {
2977                                unsafe { CStr::from_ptr(*raw) }
2978                                    .to_string_lossy()
2979                                    .into_owned()
2980                            }
2981                        })
2982                        .collect(),
2983                )
2984            },
2985            disabled_toggles: if value.disabledToggles.is_null() {
2986                None
2987            } else {
2988                Some(
2989                    unsafe {
2990                        std::slice::from_raw_parts(
2991                            value.disabledToggles,
2992                            value.disabledToggleCount as usize,
2993                        )
2994                    }
2995                        .iter()
2996                        .map(|raw| {
2997                            if raw.is_null() {
2998                                String::new()
2999                            } else {
3000                                unsafe { CStr::from_ptr(*raw) }
3001                                    .to_string_lossy()
3002                                    .into_owned()
3003                            }
3004                        })
3005                        .collect(),
3006                )
3007            },
3008        }
3009    }
3010}
3011pub struct DawnWireWGSLControl {
3012    pub enable_experimental: Option<bool>,
3013    pub enable_unsafe: Option<bool>,
3014    pub enable_testing: Option<bool>,
3015}
3016impl Default for DawnWireWGSLControl {
3017    fn default() -> Self {
3018        Self {
3019            enable_experimental: None,
3020            enable_unsafe: None,
3021            enable_testing: None,
3022        }
3023    }
3024}
3025impl DawnWireWGSLControl {
3026    pub fn new() -> Self {
3027        Self::default()
3028    }
3029    pub(crate) fn to_ffi(&self) -> (ffi::WGPUDawnWireWGSLControl, ChainedStructStorage) {
3030        let mut storage = ChainedStructStorage::new();
3031        let mut raw: ffi::WGPUDawnWireWGSLControl = unsafe { std::mem::zeroed() };
3032        raw.enableExperimental = if self.enable_experimental.unwrap_or(false) {
3033            1
3034        } else {
3035            0
3036        };
3037        raw.enableUnsafe = if self.enable_unsafe.unwrap_or(false) { 1 } else { 0 };
3038        raw.enableTesting = if self.enable_testing.unwrap_or(false) { 1 } else { 0 };
3039        (raw, storage)
3040    }
3041    pub(crate) fn from_ffi(value: ffi::WGPUDawnWireWGSLControl) -> Self {
3042        Self {
3043            enable_experimental: Some(value.enableExperimental != 0),
3044            enable_unsafe: Some(value.enableUnsafe != 0),
3045            enable_testing: Some(value.enableTesting != 0),
3046        }
3047    }
3048}
3049pub struct DepthStencilState {
3050    pub(crate) extensions: Vec<DepthStencilStateExtension>,
3051    pub format: Option<TextureFormat>,
3052    pub depth_write_enabled: Option<OptionalBool>,
3053    pub depth_compare: Option<CompareFunction>,
3054    pub stencil_front: Option<StencilFaceState>,
3055    pub stencil_back: Option<StencilFaceState>,
3056    pub stencil_read_mask: Option<u32>,
3057    pub stencil_write_mask: Option<u32>,
3058    pub depth_bias: Option<i32>,
3059    pub depth_bias_slope_scale: Option<f32>,
3060    pub depth_bias_clamp: Option<f32>,
3061}
3062impl Default for DepthStencilState {
3063    fn default() -> Self {
3064        Self {
3065            extensions: Vec::new(),
3066            format: None,
3067            depth_write_enabled: None,
3068            depth_compare: None,
3069            stencil_front: None,
3070            stencil_back: None,
3071            stencil_read_mask: Some(4294967295),
3072            stencil_write_mask: Some(4294967295),
3073            depth_bias: Some(0),
3074            depth_bias_slope_scale: None,
3075            depth_bias_clamp: None,
3076        }
3077    }
3078}
3079impl DepthStencilState {
3080    pub fn new() -> Self {
3081        Self::default()
3082    }
3083    pub(crate) fn to_ffi(&self) -> (ffi::WGPUDepthStencilState, ChainedStructStorage) {
3084        let mut storage = ChainedStructStorage::new();
3085        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
3086        for ext in self.extensions.iter().rev() {
3087            next = ext.push_chain(&mut storage, next);
3088        }
3089        let mut raw: ffi::WGPUDepthStencilState = unsafe { std::mem::zeroed() };
3090        raw.nextInChain = next;
3091        if let Some(value) = self.format {
3092            raw.format = value.into();
3093        } else {
3094            raw.format = 0 as ffi::WGPUTextureFormat;
3095        }
3096        if let Some(value) = self.depth_write_enabled {
3097            raw.depthWriteEnabled = value.into();
3098        } else {
3099            raw.depthWriteEnabled = 0 as ffi::WGPUOptionalBool;
3100        }
3101        if let Some(value) = self.depth_compare {
3102            raw.depthCompare = value.into();
3103        } else {
3104            raw.depthCompare = 0 as ffi::WGPUCompareFunction;
3105        }
3106        if let Some(value) = &self.stencil_front {
3107            let (raw_value, storage_value) = value.to_ffi();
3108            raw.stencilFront = raw_value;
3109            storage.push_storage(storage_value);
3110        }
3111        if let Some(value) = &self.stencil_back {
3112            let (raw_value, storage_value) = value.to_ffi();
3113            raw.stencilBack = raw_value;
3114            storage.push_storage(storage_value);
3115        }
3116        if let Some(value) = self.stencil_read_mask {
3117            raw.stencilReadMask = value;
3118        }
3119        if let Some(value) = self.stencil_write_mask {
3120            raw.stencilWriteMask = value;
3121        }
3122        if let Some(value) = self.depth_bias {
3123            raw.depthBias = value;
3124        }
3125        if let Some(value) = self.depth_bias_slope_scale {
3126            raw.depthBiasSlopeScale = value;
3127        }
3128        if let Some(value) = self.depth_bias_clamp {
3129            raw.depthBiasClamp = value;
3130        }
3131        (raw, storage)
3132    }
3133    pub fn with_extension(mut self, extension: DepthStencilStateExtension) -> Self {
3134        self.extensions.push(extension);
3135        self
3136    }
3137    pub(crate) fn from_ffi(value: ffi::WGPUDepthStencilState) -> Self {
3138        Self {
3139            extensions: Vec::new(),
3140            format: Some(value.format.into()),
3141            depth_write_enabled: Some(value.depthWriteEnabled.into()),
3142            depth_compare: Some(value.depthCompare.into()),
3143            stencil_front: Some(StencilFaceState::from_ffi(value.stencilFront)),
3144            stencil_back: Some(StencilFaceState::from_ffi(value.stencilBack)),
3145            stencil_read_mask: Some(value.stencilReadMask),
3146            stencil_write_mask: Some(value.stencilWriteMask),
3147            depth_bias: Some(value.depthBias),
3148            depth_bias_slope_scale: Some(value.depthBiasSlopeScale),
3149            depth_bias_clamp: Some(value.depthBiasClamp),
3150        }
3151    }
3152}
3153pub struct DeviceDescriptor {
3154    pub(crate) extensions: Vec<DeviceDescriptorExtension>,
3155    pub label: Option<String>,
3156    pub required_features: Option<Vec<FeatureName>>,
3157    pub required_limits: Option<Limits>,
3158    pub default_queue: Option<QueueDescriptor>,
3159    pub device_lost_callback_info: Option<DeviceLostCallbackInfo>,
3160    pub uncaptured_error_callback_info: Option<UncapturedErrorCallbackInfo>,
3161}
3162impl Default for DeviceDescriptor {
3163    fn default() -> Self {
3164        Self {
3165            extensions: Vec::new(),
3166            label: None,
3167            required_features: None,
3168            required_limits: None,
3169            default_queue: None,
3170            device_lost_callback_info: None,
3171            uncaptured_error_callback_info: None,
3172        }
3173    }
3174}
3175impl DeviceDescriptor {
3176    pub fn new() -> Self {
3177        Self::default()
3178    }
3179    pub(crate) fn to_ffi(&self) -> (ffi::WGPUDeviceDescriptor, ChainedStructStorage) {
3180        let mut storage = ChainedStructStorage::new();
3181        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
3182        for ext in self.extensions.iter().rev() {
3183            next = ext.push_chain(&mut storage, next);
3184        }
3185        let mut raw: ffi::WGPUDeviceDescriptor = unsafe { std::mem::zeroed() };
3186        raw.nextInChain = next;
3187        if let Some(value) = &self.label {
3188            raw.label = ffi::WGPUStringView {
3189                data: value.as_ptr().cast(),
3190                length: value.len(),
3191            };
3192        } else {
3193            raw.label = ffi::WGPUStringView {
3194                data: std::ptr::null(),
3195                length: 0,
3196            };
3197        }
3198        raw.requiredFeatureCount = self
3199            .required_features
3200            .as_ref()
3201            .map(|v| v.len())
3202            .unwrap_or(0);
3203        if let Some(values) = &self.required_features {
3204            let len_value = values.len();
3205            let raw_vec: Vec<ffi::WGPUFeatureName> = values
3206                .iter()
3207                .map(|v| (*v).into())
3208                .collect();
3209            let ptr = storage.push_vec(raw_vec);
3210            raw.requiredFeatures = ptr;
3211            raw.requiredFeatureCount = len_value;
3212        } else {
3213            raw.requiredFeatures = std::ptr::null();
3214            raw.requiredFeatureCount = 0;
3215        }
3216        if let Some(value) = &self.required_limits {
3217            let (raw_value, storage_value) = value.to_ffi();
3218            let ptr = storage.push_value(raw_value);
3219            raw.requiredLimits = ptr;
3220            storage.push_storage(storage_value);
3221        } else {
3222            raw.requiredLimits = std::ptr::null();
3223        }
3224        if let Some(value) = &self.default_queue {
3225            let (raw_value, storage_value) = value.to_ffi();
3226            raw.defaultQueue = raw_value;
3227            storage.push_storage(storage_value);
3228        }
3229        if let Some(info) = &self.device_lost_callback_info {
3230            let mut callback_slot = info.callback.borrow_mut();
3231            let callback = callback_slot.take();
3232            let (
3233                callback_ptr,
3234                userdata1,
3235            ): (ffi::WGPUDeviceLostCallback, *mut std::ffi::c_void) = if let Some(
3236                callback,
3237            ) = callback {
3238                let callback_box: DeviceLostCallback = callback;
3239                let callback_box = Box::new(Some(callback_box));
3240                let userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
3241                (Some(device_lost_callback_trampoline), userdata)
3242            } else {
3243                (None, std::ptr::null_mut())
3244            };
3245            let mode = info.mode.unwrap_or(CallbackMode::AllowSpontaneous);
3246            raw.deviceLostCallbackInfo = ffi::WGPUDeviceLostCallbackInfo {
3247                nextInChain: std::ptr::null_mut(),
3248                mode: mode.into(),
3249                callback: callback_ptr,
3250                userdata1,
3251                userdata2: std::ptr::null_mut(),
3252            };
3253        } else {
3254            raw.deviceLostCallbackInfo = ffi::WGPUDeviceLostCallbackInfo {
3255                nextInChain: std::ptr::null_mut(),
3256                mode: CallbackMode::AllowSpontaneous.into(),
3257                callback: None,
3258                userdata1: std::ptr::null_mut(),
3259                userdata2: std::ptr::null_mut(),
3260            };
3261        }
3262        if let Some(info) = &self.uncaptured_error_callback_info {
3263            let mut callback_slot = info.callback.borrow_mut();
3264            let callback = callback_slot.take();
3265            let (
3266                callback_ptr,
3267                userdata1,
3268            ): (ffi::WGPUUncapturedErrorCallback, *mut std::ffi::c_void) = if let Some(
3269                callback,
3270            ) = callback {
3271                let callback_box: UncapturedErrorCallback = callback;
3272                let callback_box = Box::new(Some(callback_box));
3273                let userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
3274                (Some(uncaptured_error_callback_trampoline), userdata)
3275            } else {
3276                (None, std::ptr::null_mut())
3277            };
3278            raw.uncapturedErrorCallbackInfo = ffi::WGPUUncapturedErrorCallbackInfo {
3279                nextInChain: std::ptr::null_mut(),
3280                callback: callback_ptr,
3281                userdata1,
3282                userdata2: std::ptr::null_mut(),
3283            };
3284        } else {
3285            raw.uncapturedErrorCallbackInfo = ffi::WGPUUncapturedErrorCallbackInfo {
3286                nextInChain: std::ptr::null_mut(),
3287                callback: None,
3288                userdata1: std::ptr::null_mut(),
3289                userdata2: std::ptr::null_mut(),
3290            };
3291        }
3292        (raw, storage)
3293    }
3294    pub fn with_extension(mut self, extension: DeviceDescriptorExtension) -> Self {
3295        self.extensions.push(extension);
3296        self
3297    }
3298    pub(crate) fn from_ffi(value: ffi::WGPUDeviceDescriptor) -> Self {
3299        Self {
3300            extensions: Vec::new(),
3301            label: if value.label.data.is_null() || value.label.length == 0 {
3302                None
3303            } else {
3304                Some(string_view_to_string(value.label))
3305            },
3306            required_features: if value.requiredFeatures.is_null() {
3307                None
3308            } else {
3309                Some(
3310                    unsafe {
3311                        std::slice::from_raw_parts(
3312                            value.requiredFeatures,
3313                            value.requiredFeatureCount as usize,
3314                        )
3315                    }
3316                        .iter()
3317                        .map(|raw| FeatureName::from(*raw))
3318                        .collect(),
3319                )
3320            },
3321            required_limits: if value.requiredLimits.is_null() {
3322                None
3323            } else {
3324                Some(Limits::from_ffi(unsafe { *value.requiredLimits }))
3325            },
3326            default_queue: Some(QueueDescriptor::from_ffi(value.defaultQueue)),
3327            device_lost_callback_info: None,
3328            uncaptured_error_callback_info: None,
3329        }
3330    }
3331}
3332pub struct EmscriptenSurfaceSourceCanvasHTMLSelector {
3333    pub selector: Option<String>,
3334}
3335impl Default for EmscriptenSurfaceSourceCanvasHTMLSelector {
3336    fn default() -> Self {
3337        Self { selector: None }
3338    }
3339}
3340impl EmscriptenSurfaceSourceCanvasHTMLSelector {
3341    pub fn new() -> Self {
3342        Self::default()
3343    }
3344    pub(crate) fn to_ffi(
3345        &self,
3346    ) -> (ffi::WGPUEmscriptenSurfaceSourceCanvasHTMLSelector, ChainedStructStorage) {
3347        let mut storage = ChainedStructStorage::new();
3348        let mut raw: ffi::WGPUEmscriptenSurfaceSourceCanvasHTMLSelector = unsafe {
3349            std::mem::zeroed()
3350        };
3351        if let Some(value) = &self.selector {
3352            raw.selector = ffi::WGPUStringView {
3353                data: value.as_ptr().cast(),
3354                length: value.len(),
3355            };
3356        } else {
3357            raw.selector = ffi::WGPUStringView {
3358                data: std::ptr::null(),
3359                length: 0,
3360            };
3361        }
3362        (raw, storage)
3363    }
3364    pub(crate) fn from_ffi(
3365        value: ffi::WGPUEmscriptenSurfaceSourceCanvasHTMLSelector,
3366    ) -> Self {
3367        Self {
3368            selector: Some(string_view_to_string(value.selector)),
3369        }
3370    }
3371}
3372pub struct Extent2D {
3373    pub width: Option<u32>,
3374    pub height: Option<u32>,
3375}
3376impl Default for Extent2D {
3377    fn default() -> Self {
3378        Self { width: None, height: None }
3379    }
3380}
3381impl Extent2D {
3382    pub fn new() -> Self {
3383        Self::default()
3384    }
3385    pub(crate) fn to_ffi(&self) -> (ffi::WGPUExtent2D, ChainedStructStorage) {
3386        let mut storage = ChainedStructStorage::new();
3387        let mut raw: ffi::WGPUExtent2D = unsafe { std::mem::zeroed() };
3388        if let Some(value) = self.width {
3389            raw.width = value;
3390        }
3391        if let Some(value) = self.height {
3392            raw.height = value;
3393        }
3394        (raw, storage)
3395    }
3396    pub(crate) fn from_ffi(value: ffi::WGPUExtent2D) -> Self {
3397        Self {
3398            width: Some(value.width),
3399            height: Some(value.height),
3400        }
3401    }
3402}
3403pub struct Extent3D {
3404    pub width: Option<u32>,
3405    pub height: Option<u32>,
3406    pub depth_or_array_layers: Option<u32>,
3407}
3408impl Default for Extent3D {
3409    fn default() -> Self {
3410        Self {
3411            width: None,
3412            height: Some(1),
3413            depth_or_array_layers: Some(1),
3414        }
3415    }
3416}
3417impl Extent3D {
3418    pub fn new() -> Self {
3419        Self::default()
3420    }
3421    pub(crate) fn to_ffi(&self) -> (ffi::WGPUExtent3D, ChainedStructStorage) {
3422        let mut storage = ChainedStructStorage::new();
3423        let mut raw: ffi::WGPUExtent3D = unsafe { std::mem::zeroed() };
3424        if let Some(value) = self.width {
3425            raw.width = value;
3426        }
3427        if let Some(value) = self.height {
3428            raw.height = value;
3429        }
3430        if let Some(value) = self.depth_or_array_layers {
3431            raw.depthOrArrayLayers = value;
3432        }
3433        (raw, storage)
3434    }
3435    pub(crate) fn from_ffi(value: ffi::WGPUExtent3D) -> Self {
3436        Self {
3437            width: Some(value.width),
3438            height: Some(value.height),
3439            depth_or_array_layers: Some(value.depthOrArrayLayers),
3440        }
3441    }
3442}
3443pub struct ExternalTextureBindingEntry {
3444    pub external_texture: Option<ExternalTexture>,
3445}
3446impl Default for ExternalTextureBindingEntry {
3447    fn default() -> Self {
3448        Self { external_texture: None }
3449    }
3450}
3451impl ExternalTextureBindingEntry {
3452    pub fn new() -> Self {
3453        Self::default()
3454    }
3455    pub(crate) fn to_ffi(
3456        &self,
3457    ) -> (ffi::WGPUExternalTextureBindingEntry, ChainedStructStorage) {
3458        let mut storage = ChainedStructStorage::new();
3459        let mut raw: ffi::WGPUExternalTextureBindingEntry = unsafe {
3460            std::mem::zeroed()
3461        };
3462        raw.externalTexture = self
3463            .external_texture
3464            .as_ref()
3465            .map(|v| v.as_raw())
3466            .unwrap_or(std::ptr::null_mut());
3467        (raw, storage)
3468    }
3469    pub(crate) fn from_ffi(value: ffi::WGPUExternalTextureBindingEntry) -> Self {
3470        Self {
3471            external_texture: Some(unsafe {
3472                ExternalTexture::from_raw(value.externalTexture)
3473            }),
3474        }
3475    }
3476}
3477pub struct ExternalTextureBindingLayout {}
3478impl Default for ExternalTextureBindingLayout {
3479    fn default() -> Self {
3480        Self {}
3481    }
3482}
3483impl ExternalTextureBindingLayout {
3484    pub fn new() -> Self {
3485        Self::default()
3486    }
3487    pub(crate) fn to_ffi(
3488        &self,
3489    ) -> (ffi::WGPUExternalTextureBindingLayout, ChainedStructStorage) {
3490        let mut storage = ChainedStructStorage::new();
3491        let mut raw: ffi::WGPUExternalTextureBindingLayout = unsafe {
3492            std::mem::zeroed()
3493        };
3494        (raw, storage)
3495    }
3496    pub(crate) fn from_ffi(value: ffi::WGPUExternalTextureBindingLayout) -> Self {
3497        let _ = value;
3498        Self::default()
3499    }
3500}
3501pub struct ExternalTextureDescriptor {
3502    pub(crate) extensions: Vec<ExternalTextureDescriptorExtension>,
3503    pub label: Option<String>,
3504    pub plane_0: Option<TextureView>,
3505    pub plane_1: Option<TextureView>,
3506    pub crop_origin: Option<Origin2D>,
3507    pub crop_size: Option<Extent2D>,
3508    pub apparent_size: Option<Extent2D>,
3509    pub do_yuv_to_rgb_conversion_only: Option<bool>,
3510    pub yuv_to_rgb_conversion_matrix: Option<Vec<f32>>,
3511    pub src_transfer_function_parameters: Option<Vec<f32>>,
3512    pub dst_transfer_function_parameters: Option<Vec<f32>>,
3513    pub gamut_conversion_matrix: Option<Vec<f32>>,
3514    pub mirrored: Option<bool>,
3515    pub rotation: Option<ExternalTextureRotation>,
3516}
3517impl Default for ExternalTextureDescriptor {
3518    fn default() -> Self {
3519        Self {
3520            extensions: Vec::new(),
3521            label: None,
3522            plane_0: None,
3523            plane_1: None,
3524            crop_origin: None,
3525            crop_size: None,
3526            apparent_size: None,
3527            do_yuv_to_rgb_conversion_only: None,
3528            yuv_to_rgb_conversion_matrix: None,
3529            src_transfer_function_parameters: None,
3530            dst_transfer_function_parameters: None,
3531            gamut_conversion_matrix: None,
3532            mirrored: None,
3533            rotation: Some(ExternalTextureRotation::Rotate0Degrees),
3534        }
3535    }
3536}
3537impl ExternalTextureDescriptor {
3538    pub fn new() -> Self {
3539        Self::default()
3540    }
3541    pub(crate) fn to_ffi(
3542        &self,
3543    ) -> (ffi::WGPUExternalTextureDescriptor, ChainedStructStorage) {
3544        let mut storage = ChainedStructStorage::new();
3545        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
3546        for ext in self.extensions.iter().rev() {
3547            next = ext.push_chain(&mut storage, next);
3548        }
3549        let mut raw: ffi::WGPUExternalTextureDescriptor = unsafe { std::mem::zeroed() };
3550        raw.nextInChain = next;
3551        if let Some(value) = &self.label {
3552            raw.label = ffi::WGPUStringView {
3553                data: value.as_ptr().cast(),
3554                length: value.len(),
3555            };
3556        } else {
3557            raw.label = ffi::WGPUStringView {
3558                data: std::ptr::null(),
3559                length: 0,
3560            };
3561        }
3562        raw.plane0 = self
3563            .plane_0
3564            .as_ref()
3565            .map(|v| v.as_raw())
3566            .unwrap_or(std::ptr::null_mut());
3567        raw.plane1 = self
3568            .plane_1
3569            .as_ref()
3570            .map(|v| v.as_raw())
3571            .unwrap_or(std::ptr::null_mut());
3572        if let Some(value) = &self.crop_origin {
3573            let (raw_value, storage_value) = value.to_ffi();
3574            raw.cropOrigin = raw_value;
3575            storage.push_storage(storage_value);
3576        }
3577        if let Some(value) = &self.crop_size {
3578            let (raw_value, storage_value) = value.to_ffi();
3579            raw.cropSize = raw_value;
3580            storage.push_storage(storage_value);
3581        }
3582        if let Some(value) = &self.apparent_size {
3583            let (raw_value, storage_value) = value.to_ffi();
3584            raw.apparentSize = raw_value;
3585            storage.push_storage(storage_value);
3586        }
3587        raw.doYuvToRgbConversionOnly = if self
3588            .do_yuv_to_rgb_conversion_only
3589            .unwrap_or(false)
3590        {
3591            1
3592        } else {
3593            0
3594        };
3595        if let Some(values) = &self.yuv_to_rgb_conversion_matrix {
3596            let len_value = values.len();
3597            let raw_vec = values.to_vec();
3598            let ptr = storage.push_vec(raw_vec);
3599            raw.yuvToRgbConversionMatrix = ptr;
3600        } else {
3601            raw.yuvToRgbConversionMatrix = std::ptr::null();
3602            let _ = 0;
3603        }
3604        if let Some(values) = &self.src_transfer_function_parameters {
3605            let len_value = values.len();
3606            let raw_vec = values.to_vec();
3607            let ptr = storage.push_vec(raw_vec);
3608            raw.srcTransferFunctionParameters = ptr;
3609        } else {
3610            raw.srcTransferFunctionParameters = std::ptr::null();
3611            let _ = 0;
3612        }
3613        if let Some(values) = &self.dst_transfer_function_parameters {
3614            let len_value = values.len();
3615            let raw_vec = values.to_vec();
3616            let ptr = storage.push_vec(raw_vec);
3617            raw.dstTransferFunctionParameters = ptr;
3618        } else {
3619            raw.dstTransferFunctionParameters = std::ptr::null();
3620            let _ = 0;
3621        }
3622        if let Some(values) = &self.gamut_conversion_matrix {
3623            let len_value = values.len();
3624            let raw_vec = values.to_vec();
3625            let ptr = storage.push_vec(raw_vec);
3626            raw.gamutConversionMatrix = ptr;
3627        } else {
3628            raw.gamutConversionMatrix = std::ptr::null();
3629            let _ = 0;
3630        }
3631        raw.mirrored = if self.mirrored.unwrap_or(false) { 1 } else { 0 };
3632        if let Some(value) = self.rotation {
3633            raw.rotation = value.into();
3634        } else {
3635            raw.rotation = 0 as ffi::WGPUExternalTextureRotation;
3636        }
3637        (raw, storage)
3638    }
3639    pub fn with_extension(
3640        mut self,
3641        extension: ExternalTextureDescriptorExtension,
3642    ) -> Self {
3643        self.extensions.push(extension);
3644        self
3645    }
3646    pub(crate) fn from_ffi(value: ffi::WGPUExternalTextureDescriptor) -> Self {
3647        Self {
3648            extensions: Vec::new(),
3649            label: if value.label.data.is_null() || value.label.length == 0 {
3650                None
3651            } else {
3652                Some(string_view_to_string(value.label))
3653            },
3654            plane_0: Some(unsafe { TextureView::from_raw(value.plane0) }),
3655            plane_1: if value.plane1.is_null() {
3656                None
3657            } else {
3658                Some(unsafe { TextureView::from_raw(value.plane1) })
3659            },
3660            crop_origin: Some(Origin2D::from_ffi(value.cropOrigin)),
3661            crop_size: Some(Extent2D::from_ffi(value.cropSize)),
3662            apparent_size: Some(Extent2D::from_ffi(value.apparentSize)),
3663            do_yuv_to_rgb_conversion_only: Some(value.doYuvToRgbConversionOnly != 0),
3664            yuv_to_rgb_conversion_matrix: if value.yuvToRgbConversionMatrix.is_null() {
3665                None
3666            } else {
3667                Some(
3668                    unsafe {
3669                        std::slice::from_raw_parts(
3670                            value.yuvToRgbConversionMatrix,
3671                            12usize,
3672                        )
3673                    }
3674                        .to_vec(),
3675                )
3676            },
3677            src_transfer_function_parameters: if value
3678                .srcTransferFunctionParameters
3679                .is_null()
3680            {
3681                None
3682            } else {
3683                Some(
3684                    unsafe {
3685                        std::slice::from_raw_parts(
3686                            value.srcTransferFunctionParameters,
3687                            7usize,
3688                        )
3689                    }
3690                        .to_vec(),
3691                )
3692            },
3693            dst_transfer_function_parameters: if value
3694                .dstTransferFunctionParameters
3695                .is_null()
3696            {
3697                None
3698            } else {
3699                Some(
3700                    unsafe {
3701                        std::slice::from_raw_parts(
3702                            value.dstTransferFunctionParameters,
3703                            7usize,
3704                        )
3705                    }
3706                        .to_vec(),
3707                )
3708            },
3709            gamut_conversion_matrix: if value.gamutConversionMatrix.is_null() {
3710                None
3711            } else {
3712                Some(
3713                    unsafe {
3714                        std::slice::from_raw_parts(value.gamutConversionMatrix, 9usize)
3715                    }
3716                        .to_vec(),
3717                )
3718            },
3719            mirrored: Some(value.mirrored != 0),
3720            rotation: Some(value.rotation.into()),
3721        }
3722    }
3723}
3724pub struct FragmentState {
3725    pub(crate) extensions: Vec<FragmentStateExtension>,
3726    pub module: Option<ShaderModule>,
3727    pub entry_point: Option<String>,
3728    pub constants: Option<Vec<ConstantEntry>>,
3729    pub targets: Option<Vec<ColorTargetState>>,
3730}
3731impl Default for FragmentState {
3732    fn default() -> Self {
3733        Self {
3734            extensions: Vec::new(),
3735            module: None,
3736            entry_point: None,
3737            constants: None,
3738            targets: None,
3739        }
3740    }
3741}
3742impl FragmentState {
3743    pub fn new() -> Self {
3744        Self::default()
3745    }
3746    pub(crate) fn to_ffi(&self) -> (ffi::WGPUFragmentState, ChainedStructStorage) {
3747        let mut storage = ChainedStructStorage::new();
3748        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
3749        for ext in self.extensions.iter().rev() {
3750            next = ext.push_chain(&mut storage, next);
3751        }
3752        let mut raw: ffi::WGPUFragmentState = unsafe { std::mem::zeroed() };
3753        raw.nextInChain = next;
3754        raw.module = self
3755            .module
3756            .as_ref()
3757            .map(|v| v.as_raw())
3758            .unwrap_or(std::ptr::null_mut());
3759        if let Some(value) = &self.entry_point {
3760            raw.entryPoint = ffi::WGPUStringView {
3761                data: value.as_ptr().cast(),
3762                length: value.len(),
3763            };
3764        } else {
3765            raw.entryPoint = ffi::WGPUStringView {
3766                data: std::ptr::null(),
3767                length: 0,
3768            };
3769        }
3770        raw.constantCount = self.constants.as_ref().map(|v| v.len()).unwrap_or(0);
3771        if let Some(values) = &self.constants {
3772            let len_value = values.len();
3773            let mut raw_vec: Vec<ffi::WGPUConstantEntry> = Vec::with_capacity(
3774                values.len(),
3775            );
3776            for item in values.iter() {
3777                let (raw_item, storage_item) = item.to_ffi();
3778                raw_vec.push(raw_item);
3779                storage.push_storage(storage_item);
3780            }
3781            let ptr = storage.push_vec(raw_vec);
3782            raw.constants = ptr;
3783            raw.constantCount = len_value;
3784        } else {
3785            raw.constants = std::ptr::null();
3786            raw.constantCount = 0;
3787        }
3788        raw.targetCount = self.targets.as_ref().map(|v| v.len()).unwrap_or(0);
3789        if let Some(values) = &self.targets {
3790            let len_value = values.len();
3791            let mut raw_vec: Vec<ffi::WGPUColorTargetState> = Vec::with_capacity(
3792                values.len(),
3793            );
3794            for item in values.iter() {
3795                let (raw_item, storage_item) = item.to_ffi();
3796                raw_vec.push(raw_item);
3797                storage.push_storage(storage_item);
3798            }
3799            let ptr = storage.push_vec(raw_vec);
3800            raw.targets = ptr;
3801            raw.targetCount = len_value;
3802        } else {
3803            raw.targets = std::ptr::null();
3804            raw.targetCount = 0;
3805        }
3806        (raw, storage)
3807    }
3808    pub fn with_extension(mut self, extension: FragmentStateExtension) -> Self {
3809        self.extensions.push(extension);
3810        self
3811    }
3812    pub(crate) fn from_ffi(value: ffi::WGPUFragmentState) -> Self {
3813        Self {
3814            extensions: Vec::new(),
3815            module: Some(unsafe { ShaderModule::from_raw(value.module) }),
3816            entry_point: if value.entryPoint.data.is_null()
3817                || value.entryPoint.length == 0
3818            {
3819                None
3820            } else {
3821                Some(string_view_to_string(value.entryPoint))
3822            },
3823            constants: if value.constants.is_null() {
3824                None
3825            } else {
3826                Some(
3827                    unsafe {
3828                        std::slice::from_raw_parts(
3829                            value.constants,
3830                            value.constantCount as usize,
3831                        )
3832                    }
3833                        .iter()
3834                        .map(|raw| ConstantEntry::from_ffi(*raw))
3835                        .collect(),
3836                )
3837            },
3838            targets: if value.targets.is_null() {
3839                None
3840            } else {
3841                Some(
3842                    unsafe {
3843                        std::slice::from_raw_parts(
3844                            value.targets,
3845                            value.targetCount as usize,
3846                        )
3847                    }
3848                        .iter()
3849                        .map(|raw| ColorTargetState::from_ffi(*raw))
3850                        .collect(),
3851                )
3852            },
3853        }
3854    }
3855}
3856pub struct Future {
3857    pub id: Option<u64>,
3858}
3859impl Default for Future {
3860    fn default() -> Self {
3861        Self { id: None }
3862    }
3863}
3864impl Future {
3865    pub fn new() -> Self {
3866        Self::default()
3867    }
3868    pub(crate) fn to_ffi(&self) -> (ffi::WGPUFuture, ChainedStructStorage) {
3869        let mut storage = ChainedStructStorage::new();
3870        let mut raw: ffi::WGPUFuture = unsafe { std::mem::zeroed() };
3871        if let Some(value) = self.id {
3872            raw.id = value;
3873        }
3874        (raw, storage)
3875    }
3876    pub(crate) fn from_ffi(value: ffi::WGPUFuture) -> Self {
3877        Self { id: Some(value.id) }
3878    }
3879}
3880pub struct FutureWaitInfo {
3881    pub future: Option<Future>,
3882    pub completed: Option<bool>,
3883}
3884impl Default for FutureWaitInfo {
3885    fn default() -> Self {
3886        Self {
3887            future: None,
3888            completed: None,
3889        }
3890    }
3891}
3892impl FutureWaitInfo {
3893    pub fn new() -> Self {
3894        Self::default()
3895    }
3896    pub(crate) fn to_ffi(&self) -> (ffi::WGPUFutureWaitInfo, ChainedStructStorage) {
3897        let mut storage = ChainedStructStorage::new();
3898        let mut raw: ffi::WGPUFutureWaitInfo = unsafe { std::mem::zeroed() };
3899        if let Some(value) = &self.future {
3900            let (raw_value, storage_value) = value.to_ffi();
3901            raw.future = raw_value;
3902            storage.push_storage(storage_value);
3903        }
3904        raw.completed = if self.completed.unwrap_or(false) { 1 } else { 0 };
3905        (raw, storage)
3906    }
3907    pub(crate) fn from_ffi(value: ffi::WGPUFutureWaitInfo) -> Self {
3908        Self {
3909            future: Some(Future::from_ffi(value.future)),
3910            completed: Some(value.completed != 0),
3911        }
3912    }
3913}
3914pub struct ImageCopyExternalTexture {
3915    pub(crate) extensions: Vec<ImageCopyExternalTextureExtension>,
3916    pub external_texture: Option<ExternalTexture>,
3917    pub origin: Option<Origin3D>,
3918    pub natural_size: Option<Extent2D>,
3919}
3920impl Default for ImageCopyExternalTexture {
3921    fn default() -> Self {
3922        Self {
3923            extensions: Vec::new(),
3924            external_texture: None,
3925            origin: None,
3926            natural_size: None,
3927        }
3928    }
3929}
3930impl ImageCopyExternalTexture {
3931    pub fn new() -> Self {
3932        Self::default()
3933    }
3934    pub(crate) fn to_ffi(
3935        &self,
3936    ) -> (ffi::WGPUImageCopyExternalTexture, ChainedStructStorage) {
3937        let mut storage = ChainedStructStorage::new();
3938        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
3939        for ext in self.extensions.iter().rev() {
3940            next = ext.push_chain(&mut storage, next);
3941        }
3942        let mut raw: ffi::WGPUImageCopyExternalTexture = unsafe { std::mem::zeroed() };
3943        raw.nextInChain = next;
3944        raw.externalTexture = self
3945            .external_texture
3946            .as_ref()
3947            .map(|v| v.as_raw())
3948            .unwrap_or(std::ptr::null_mut());
3949        if let Some(value) = &self.origin {
3950            let (raw_value, storage_value) = value.to_ffi();
3951            raw.origin = raw_value;
3952            storage.push_storage(storage_value);
3953        }
3954        if let Some(value) = &self.natural_size {
3955            let (raw_value, storage_value) = value.to_ffi();
3956            raw.naturalSize = raw_value;
3957            storage.push_storage(storage_value);
3958        }
3959        (raw, storage)
3960    }
3961    pub fn with_extension(
3962        mut self,
3963        extension: ImageCopyExternalTextureExtension,
3964    ) -> Self {
3965        self.extensions.push(extension);
3966        self
3967    }
3968    pub(crate) fn from_ffi(value: ffi::WGPUImageCopyExternalTexture) -> Self {
3969        Self {
3970            extensions: Vec::new(),
3971            external_texture: Some(unsafe {
3972                ExternalTexture::from_raw(value.externalTexture)
3973            }),
3974            origin: Some(Origin3D::from_ffi(value.origin)),
3975            natural_size: Some(Extent2D::from_ffi(value.naturalSize)),
3976        }
3977    }
3978}
3979pub struct InstanceDescriptor {
3980    pub(crate) extensions: Vec<InstanceDescriptorExtension>,
3981    pub required_features: Option<Vec<InstanceFeatureName>>,
3982    pub required_limits: Option<InstanceLimits>,
3983}
3984impl Default for InstanceDescriptor {
3985    fn default() -> Self {
3986        Self {
3987            extensions: Vec::new(),
3988            required_features: None,
3989            required_limits: None,
3990        }
3991    }
3992}
3993impl InstanceDescriptor {
3994    pub fn new() -> Self {
3995        Self::default()
3996    }
3997    pub(crate) fn to_ffi(&self) -> (ffi::WGPUInstanceDescriptor, ChainedStructStorage) {
3998        let mut storage = ChainedStructStorage::new();
3999        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4000        for ext in self.extensions.iter().rev() {
4001            next = ext.push_chain(&mut storage, next);
4002        }
4003        let mut raw: ffi::WGPUInstanceDescriptor = unsafe { std::mem::zeroed() };
4004        raw.nextInChain = next;
4005        raw.requiredFeatureCount = self
4006            .required_features
4007            .as_ref()
4008            .map(|v| v.len())
4009            .unwrap_or(0);
4010        if let Some(values) = &self.required_features {
4011            let len_value = values.len();
4012            let raw_vec: Vec<ffi::WGPUInstanceFeatureName> = values
4013                .iter()
4014                .map(|v| (*v).into())
4015                .collect();
4016            let ptr = storage.push_vec(raw_vec);
4017            raw.requiredFeatures = ptr;
4018            raw.requiredFeatureCount = len_value;
4019        } else {
4020            raw.requiredFeatures = std::ptr::null();
4021            raw.requiredFeatureCount = 0;
4022        }
4023        if let Some(value) = &self.required_limits {
4024            let (raw_value, storage_value) = value.to_ffi();
4025            let ptr = storage.push_value(raw_value);
4026            raw.requiredLimits = ptr;
4027            storage.push_storage(storage_value);
4028        } else {
4029            raw.requiredLimits = std::ptr::null();
4030        }
4031        (raw, storage)
4032    }
4033    pub fn with_extension(mut self, extension: InstanceDescriptorExtension) -> Self {
4034        self.extensions.push(extension);
4035        self
4036    }
4037    pub(crate) fn from_ffi(value: ffi::WGPUInstanceDescriptor) -> Self {
4038        Self {
4039            extensions: Vec::new(),
4040            required_features: if value.requiredFeatures.is_null() {
4041                None
4042            } else {
4043                Some(
4044                    unsafe {
4045                        std::slice::from_raw_parts(
4046                            value.requiredFeatures,
4047                            value.requiredFeatureCount as usize,
4048                        )
4049                    }
4050                        .iter()
4051                        .map(|raw| InstanceFeatureName::from(*raw))
4052                        .collect(),
4053                )
4054            },
4055            required_limits: if value.requiredLimits.is_null() {
4056                None
4057            } else {
4058                Some(InstanceLimits::from_ffi(unsafe { *value.requiredLimits }))
4059            },
4060        }
4061    }
4062}
4063pub struct InstanceLimits {
4064    pub(crate) extensions: Vec<InstanceLimitsExtension>,
4065    pub timed_wait_any_max_count: Option<usize>,
4066}
4067impl Default for InstanceLimits {
4068    fn default() -> Self {
4069        Self {
4070            extensions: Vec::new(),
4071            timed_wait_any_max_count: Some(0),
4072        }
4073    }
4074}
4075impl InstanceLimits {
4076    pub fn new() -> Self {
4077        Self::default()
4078    }
4079    pub(crate) fn to_ffi(&self) -> (ffi::WGPUInstanceLimits, ChainedStructStorage) {
4080        let mut storage = ChainedStructStorage::new();
4081        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4082        for ext in self.extensions.iter().rev() {
4083            next = ext.push_chain(&mut storage, next);
4084        }
4085        let mut raw: ffi::WGPUInstanceLimits = unsafe { std::mem::zeroed() };
4086        raw.nextInChain = next;
4087        if let Some(value) = self.timed_wait_any_max_count {
4088            raw.timedWaitAnyMaxCount = value;
4089        }
4090        (raw, storage)
4091    }
4092    pub fn with_extension(mut self, extension: InstanceLimitsExtension) -> Self {
4093        self.extensions.push(extension);
4094        self
4095    }
4096    pub(crate) fn from_ffi(value: ffi::WGPUInstanceLimits) -> Self {
4097        Self {
4098            extensions: Vec::new(),
4099            timed_wait_any_max_count: Some(value.timedWaitAnyMaxCount),
4100        }
4101    }
4102}
4103pub struct Limits {
4104    pub(crate) extensions: Vec<LimitsExtension>,
4105    pub max_texture_dimension_1d: Option<u32>,
4106    pub max_texture_dimension_2d: Option<u32>,
4107    pub max_texture_dimension_3d: Option<u32>,
4108    pub max_texture_array_layers: Option<u32>,
4109    pub max_bind_groups: Option<u32>,
4110    pub max_bind_groups_plus_vertex_buffers: Option<u32>,
4111    pub max_bindings_per_bind_group: Option<u32>,
4112    pub max_dynamic_uniform_buffers_per_pipeline_layout: Option<u32>,
4113    pub max_dynamic_storage_buffers_per_pipeline_layout: Option<u32>,
4114    pub max_sampled_textures_per_shader_stage: Option<u32>,
4115    pub max_samplers_per_shader_stage: Option<u32>,
4116    pub max_storage_buffers_per_shader_stage: Option<u32>,
4117    pub max_storage_textures_per_shader_stage: Option<u32>,
4118    pub max_uniform_buffers_per_shader_stage: Option<u32>,
4119    pub max_uniform_buffer_binding_size: Option<u64>,
4120    pub max_storage_buffer_binding_size: Option<u64>,
4121    pub min_uniform_buffer_offset_alignment: Option<u32>,
4122    pub min_storage_buffer_offset_alignment: Option<u32>,
4123    pub max_vertex_buffers: Option<u32>,
4124    pub max_buffer_size: Option<u64>,
4125    pub max_vertex_attributes: Option<u32>,
4126    pub max_vertex_buffer_array_stride: Option<u32>,
4127    pub max_inter_stage_shader_variables: Option<u32>,
4128    pub max_color_attachments: Option<u32>,
4129    pub max_color_attachment_bytes_per_sample: Option<u32>,
4130    pub max_compute_workgroup_storage_size: Option<u32>,
4131    pub max_compute_invocations_per_workgroup: Option<u32>,
4132    pub max_compute_workgroup_size_x: Option<u32>,
4133    pub max_compute_workgroup_size_y: Option<u32>,
4134    pub max_compute_workgroup_size_z: Option<u32>,
4135    pub max_compute_workgroups_per_dimension: Option<u32>,
4136    pub max_immediate_size: Option<u32>,
4137}
4138impl Default for Limits {
4139    fn default() -> Self {
4140        Self {
4141            extensions: Vec::new(),
4142            max_texture_dimension_1d: Some(LIMIT_U32_UNDEFINED),
4143            max_texture_dimension_2d: Some(LIMIT_U32_UNDEFINED),
4144            max_texture_dimension_3d: Some(LIMIT_U32_UNDEFINED),
4145            max_texture_array_layers: Some(LIMIT_U32_UNDEFINED),
4146            max_bind_groups: Some(LIMIT_U32_UNDEFINED),
4147            max_bind_groups_plus_vertex_buffers: Some(LIMIT_U32_UNDEFINED),
4148            max_bindings_per_bind_group: Some(LIMIT_U32_UNDEFINED),
4149            max_dynamic_uniform_buffers_per_pipeline_layout: Some(LIMIT_U32_UNDEFINED),
4150            max_dynamic_storage_buffers_per_pipeline_layout: Some(LIMIT_U32_UNDEFINED),
4151            max_sampled_textures_per_shader_stage: Some(LIMIT_U32_UNDEFINED),
4152            max_samplers_per_shader_stage: Some(LIMIT_U32_UNDEFINED),
4153            max_storage_buffers_per_shader_stage: Some(LIMIT_U32_UNDEFINED),
4154            max_storage_textures_per_shader_stage: Some(LIMIT_U32_UNDEFINED),
4155            max_uniform_buffers_per_shader_stage: Some(LIMIT_U32_UNDEFINED),
4156            max_uniform_buffer_binding_size: Some(LIMIT_U64_UNDEFINED),
4157            max_storage_buffer_binding_size: Some(LIMIT_U64_UNDEFINED),
4158            min_uniform_buffer_offset_alignment: Some(LIMIT_U32_UNDEFINED),
4159            min_storage_buffer_offset_alignment: Some(LIMIT_U32_UNDEFINED),
4160            max_vertex_buffers: Some(LIMIT_U32_UNDEFINED),
4161            max_buffer_size: Some(LIMIT_U64_UNDEFINED),
4162            max_vertex_attributes: Some(LIMIT_U32_UNDEFINED),
4163            max_vertex_buffer_array_stride: Some(LIMIT_U32_UNDEFINED),
4164            max_inter_stage_shader_variables: Some(LIMIT_U32_UNDEFINED),
4165            max_color_attachments: Some(LIMIT_U32_UNDEFINED),
4166            max_color_attachment_bytes_per_sample: Some(LIMIT_U32_UNDEFINED),
4167            max_compute_workgroup_storage_size: Some(LIMIT_U32_UNDEFINED),
4168            max_compute_invocations_per_workgroup: Some(LIMIT_U32_UNDEFINED),
4169            max_compute_workgroup_size_x: Some(LIMIT_U32_UNDEFINED),
4170            max_compute_workgroup_size_y: Some(LIMIT_U32_UNDEFINED),
4171            max_compute_workgroup_size_z: Some(LIMIT_U32_UNDEFINED),
4172            max_compute_workgroups_per_dimension: Some(LIMIT_U32_UNDEFINED),
4173            max_immediate_size: Some(LIMIT_U32_UNDEFINED),
4174        }
4175    }
4176}
4177impl Limits {
4178    pub fn new() -> Self {
4179        Self::default()
4180    }
4181    pub(crate) fn to_ffi(&self) -> (ffi::WGPULimits, ChainedStructStorage) {
4182        let mut storage = ChainedStructStorage::new();
4183        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4184        for ext in self.extensions.iter().rev() {
4185            next = ext.push_chain(&mut storage, next);
4186        }
4187        let mut raw: ffi::WGPULimits = unsafe { std::mem::zeroed() };
4188        raw.nextInChain = next;
4189        if let Some(value) = self.max_texture_dimension_1d {
4190            raw.maxTextureDimension1D = value;
4191        }
4192        if let Some(value) = self.max_texture_dimension_2d {
4193            raw.maxTextureDimension2D = value;
4194        }
4195        if let Some(value) = self.max_texture_dimension_3d {
4196            raw.maxTextureDimension3D = value;
4197        }
4198        if let Some(value) = self.max_texture_array_layers {
4199            raw.maxTextureArrayLayers = value;
4200        }
4201        if let Some(value) = self.max_bind_groups {
4202            raw.maxBindGroups = value;
4203        }
4204        if let Some(value) = self.max_bind_groups_plus_vertex_buffers {
4205            raw.maxBindGroupsPlusVertexBuffers = value;
4206        }
4207        if let Some(value) = self.max_bindings_per_bind_group {
4208            raw.maxBindingsPerBindGroup = value;
4209        }
4210        if let Some(value) = self.max_dynamic_uniform_buffers_per_pipeline_layout {
4211            raw.maxDynamicUniformBuffersPerPipelineLayout = value;
4212        }
4213        if let Some(value) = self.max_dynamic_storage_buffers_per_pipeline_layout {
4214            raw.maxDynamicStorageBuffersPerPipelineLayout = value;
4215        }
4216        if let Some(value) = self.max_sampled_textures_per_shader_stage {
4217            raw.maxSampledTexturesPerShaderStage = value;
4218        }
4219        if let Some(value) = self.max_samplers_per_shader_stage {
4220            raw.maxSamplersPerShaderStage = value;
4221        }
4222        if let Some(value) = self.max_storage_buffers_per_shader_stage {
4223            raw.maxStorageBuffersPerShaderStage = value;
4224        }
4225        if let Some(value) = self.max_storage_textures_per_shader_stage {
4226            raw.maxStorageTexturesPerShaderStage = value;
4227        }
4228        if let Some(value) = self.max_uniform_buffers_per_shader_stage {
4229            raw.maxUniformBuffersPerShaderStage = value;
4230        }
4231        if let Some(value) = self.max_uniform_buffer_binding_size {
4232            raw.maxUniformBufferBindingSize = value;
4233        }
4234        if let Some(value) = self.max_storage_buffer_binding_size {
4235            raw.maxStorageBufferBindingSize = value;
4236        }
4237        if let Some(value) = self.min_uniform_buffer_offset_alignment {
4238            raw.minUniformBufferOffsetAlignment = value;
4239        }
4240        if let Some(value) = self.min_storage_buffer_offset_alignment {
4241            raw.minStorageBufferOffsetAlignment = value;
4242        }
4243        if let Some(value) = self.max_vertex_buffers {
4244            raw.maxVertexBuffers = value;
4245        }
4246        if let Some(value) = self.max_buffer_size {
4247            raw.maxBufferSize = value;
4248        }
4249        if let Some(value) = self.max_vertex_attributes {
4250            raw.maxVertexAttributes = value;
4251        }
4252        if let Some(value) = self.max_vertex_buffer_array_stride {
4253            raw.maxVertexBufferArrayStride = value;
4254        }
4255        if let Some(value) = self.max_inter_stage_shader_variables {
4256            raw.maxInterStageShaderVariables = value;
4257        }
4258        if let Some(value) = self.max_color_attachments {
4259            raw.maxColorAttachments = value;
4260        }
4261        if let Some(value) = self.max_color_attachment_bytes_per_sample {
4262            raw.maxColorAttachmentBytesPerSample = value;
4263        }
4264        if let Some(value) = self.max_compute_workgroup_storage_size {
4265            raw.maxComputeWorkgroupStorageSize = value;
4266        }
4267        if let Some(value) = self.max_compute_invocations_per_workgroup {
4268            raw.maxComputeInvocationsPerWorkgroup = value;
4269        }
4270        if let Some(value) = self.max_compute_workgroup_size_x {
4271            raw.maxComputeWorkgroupSizeX = value;
4272        }
4273        if let Some(value) = self.max_compute_workgroup_size_y {
4274            raw.maxComputeWorkgroupSizeY = value;
4275        }
4276        if let Some(value) = self.max_compute_workgroup_size_z {
4277            raw.maxComputeWorkgroupSizeZ = value;
4278        }
4279        if let Some(value) = self.max_compute_workgroups_per_dimension {
4280            raw.maxComputeWorkgroupsPerDimension = value;
4281        }
4282        if let Some(value) = self.max_immediate_size {
4283            raw.maxImmediateSize = value;
4284        }
4285        (raw, storage)
4286    }
4287    pub fn with_extension(mut self, extension: LimitsExtension) -> Self {
4288        self.extensions.push(extension);
4289        self
4290    }
4291    pub(crate) fn from_ffi(value: ffi::WGPULimits) -> Self {
4292        Self {
4293            extensions: Vec::new(),
4294            max_texture_dimension_1d: Some(value.maxTextureDimension1D),
4295            max_texture_dimension_2d: Some(value.maxTextureDimension2D),
4296            max_texture_dimension_3d: Some(value.maxTextureDimension3D),
4297            max_texture_array_layers: Some(value.maxTextureArrayLayers),
4298            max_bind_groups: Some(value.maxBindGroups),
4299            max_bind_groups_plus_vertex_buffers: Some(
4300                value.maxBindGroupsPlusVertexBuffers,
4301            ),
4302            max_bindings_per_bind_group: Some(value.maxBindingsPerBindGroup),
4303            max_dynamic_uniform_buffers_per_pipeline_layout: Some(
4304                value.maxDynamicUniformBuffersPerPipelineLayout,
4305            ),
4306            max_dynamic_storage_buffers_per_pipeline_layout: Some(
4307                value.maxDynamicStorageBuffersPerPipelineLayout,
4308            ),
4309            max_sampled_textures_per_shader_stage: Some(
4310                value.maxSampledTexturesPerShaderStage,
4311            ),
4312            max_samplers_per_shader_stage: Some(value.maxSamplersPerShaderStage),
4313            max_storage_buffers_per_shader_stage: Some(
4314                value.maxStorageBuffersPerShaderStage,
4315            ),
4316            max_storage_textures_per_shader_stage: Some(
4317                value.maxStorageTexturesPerShaderStage,
4318            ),
4319            max_uniform_buffers_per_shader_stage: Some(
4320                value.maxUniformBuffersPerShaderStage,
4321            ),
4322            max_uniform_buffer_binding_size: Some(value.maxUniformBufferBindingSize),
4323            max_storage_buffer_binding_size: Some(value.maxStorageBufferBindingSize),
4324            min_uniform_buffer_offset_alignment: Some(
4325                value.minUniformBufferOffsetAlignment,
4326            ),
4327            min_storage_buffer_offset_alignment: Some(
4328                value.minStorageBufferOffsetAlignment,
4329            ),
4330            max_vertex_buffers: Some(value.maxVertexBuffers),
4331            max_buffer_size: Some(value.maxBufferSize),
4332            max_vertex_attributes: Some(value.maxVertexAttributes),
4333            max_vertex_buffer_array_stride: Some(value.maxVertexBufferArrayStride),
4334            max_inter_stage_shader_variables: Some(value.maxInterStageShaderVariables),
4335            max_color_attachments: Some(value.maxColorAttachments),
4336            max_color_attachment_bytes_per_sample: Some(
4337                value.maxColorAttachmentBytesPerSample,
4338            ),
4339            max_compute_workgroup_storage_size: Some(
4340                value.maxComputeWorkgroupStorageSize,
4341            ),
4342            max_compute_invocations_per_workgroup: Some(
4343                value.maxComputeInvocationsPerWorkgroup,
4344            ),
4345            max_compute_workgroup_size_x: Some(value.maxComputeWorkgroupSizeX),
4346            max_compute_workgroup_size_y: Some(value.maxComputeWorkgroupSizeY),
4347            max_compute_workgroup_size_z: Some(value.maxComputeWorkgroupSizeZ),
4348            max_compute_workgroups_per_dimension: Some(
4349                value.maxComputeWorkgroupsPerDimension,
4350            ),
4351            max_immediate_size: Some(value.maxImmediateSize),
4352        }
4353    }
4354}
4355pub struct MemoryHeapInfo {
4356    pub properties: Option<HeapProperty>,
4357    pub size: Option<u64>,
4358}
4359impl Default for MemoryHeapInfo {
4360    fn default() -> Self {
4361        Self {
4362            properties: None,
4363            size: None,
4364        }
4365    }
4366}
4367impl MemoryHeapInfo {
4368    pub fn new() -> Self {
4369        Self::default()
4370    }
4371    pub(crate) fn to_ffi(&self) -> (ffi::WGPUMemoryHeapInfo, ChainedStructStorage) {
4372        let mut storage = ChainedStructStorage::new();
4373        let mut raw: ffi::WGPUMemoryHeapInfo = unsafe { std::mem::zeroed() };
4374        if let Some(value) = self.properties {
4375            raw.properties = value.into();
4376        } else {
4377            raw.properties = 0 as ffi::WGPUHeapProperty;
4378        }
4379        if let Some(value) = self.size {
4380            raw.size = value;
4381        }
4382        (raw, storage)
4383    }
4384    pub(crate) fn from_ffi(value: ffi::WGPUMemoryHeapInfo) -> Self {
4385        Self {
4386            properties: Some(value.properties.into()),
4387            size: Some(value.size),
4388        }
4389    }
4390}
4391pub struct MultisampleState {
4392    pub(crate) extensions: Vec<MultisampleStateExtension>,
4393    pub count: Option<u32>,
4394    pub mask: Option<u32>,
4395    pub alpha_to_coverage_enabled: Option<bool>,
4396}
4397impl Default for MultisampleState {
4398    fn default() -> Self {
4399        Self {
4400            extensions: Vec::new(),
4401            count: Some(1),
4402            mask: Some(4294967295),
4403            alpha_to_coverage_enabled: None,
4404        }
4405    }
4406}
4407impl MultisampleState {
4408    pub fn new() -> Self {
4409        Self::default()
4410    }
4411    pub(crate) fn to_ffi(&self) -> (ffi::WGPUMultisampleState, ChainedStructStorage) {
4412        let mut storage = ChainedStructStorage::new();
4413        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4414        for ext in self.extensions.iter().rev() {
4415            next = ext.push_chain(&mut storage, next);
4416        }
4417        let mut raw: ffi::WGPUMultisampleState = unsafe { std::mem::zeroed() };
4418        raw.nextInChain = next;
4419        if let Some(value) = self.count {
4420            raw.count = value;
4421        }
4422        if let Some(value) = self.mask {
4423            raw.mask = value;
4424        }
4425        raw.alphaToCoverageEnabled = if self.alpha_to_coverage_enabled.unwrap_or(false) {
4426            1
4427        } else {
4428            0
4429        };
4430        (raw, storage)
4431    }
4432    pub fn with_extension(mut self, extension: MultisampleStateExtension) -> Self {
4433        self.extensions.push(extension);
4434        self
4435    }
4436    pub(crate) fn from_ffi(value: ffi::WGPUMultisampleState) -> Self {
4437        Self {
4438            extensions: Vec::new(),
4439            count: Some(value.count),
4440            mask: Some(value.mask),
4441            alpha_to_coverage_enabled: Some(value.alphaToCoverageEnabled != 0),
4442        }
4443    }
4444}
4445pub struct Origin2D {
4446    pub x: Option<u32>,
4447    pub y: Option<u32>,
4448}
4449impl Default for Origin2D {
4450    fn default() -> Self {
4451        Self { x: Some(0), y: Some(0) }
4452    }
4453}
4454impl Origin2D {
4455    pub fn new() -> Self {
4456        Self::default()
4457    }
4458    pub(crate) fn to_ffi(&self) -> (ffi::WGPUOrigin2D, ChainedStructStorage) {
4459        let mut storage = ChainedStructStorage::new();
4460        let mut raw: ffi::WGPUOrigin2D = unsafe { std::mem::zeroed() };
4461        if let Some(value) = self.x {
4462            raw.x = value;
4463        }
4464        if let Some(value) = self.y {
4465            raw.y = value;
4466        }
4467        (raw, storage)
4468    }
4469    pub(crate) fn from_ffi(value: ffi::WGPUOrigin2D) -> Self {
4470        Self {
4471            x: Some(value.x),
4472            y: Some(value.y),
4473        }
4474    }
4475}
4476pub struct Origin3D {
4477    pub x: Option<u32>,
4478    pub y: Option<u32>,
4479    pub z: Option<u32>,
4480}
4481impl Default for Origin3D {
4482    fn default() -> Self {
4483        Self {
4484            x: Some(0),
4485            y: Some(0),
4486            z: Some(0),
4487        }
4488    }
4489}
4490impl Origin3D {
4491    pub fn new() -> Self {
4492        Self::default()
4493    }
4494    pub(crate) fn to_ffi(&self) -> (ffi::WGPUOrigin3D, ChainedStructStorage) {
4495        let mut storage = ChainedStructStorage::new();
4496        let mut raw: ffi::WGPUOrigin3D = unsafe { std::mem::zeroed() };
4497        if let Some(value) = self.x {
4498            raw.x = value;
4499        }
4500        if let Some(value) = self.y {
4501            raw.y = value;
4502        }
4503        if let Some(value) = self.z {
4504            raw.z = value;
4505        }
4506        (raw, storage)
4507    }
4508    pub(crate) fn from_ffi(value: ffi::WGPUOrigin3D) -> Self {
4509        Self {
4510            x: Some(value.x),
4511            y: Some(value.y),
4512            z: Some(value.z),
4513        }
4514    }
4515}
4516pub struct PassTimestampWrites {
4517    pub(crate) extensions: Vec<PassTimestampWritesExtension>,
4518    pub query_set: Option<QuerySet>,
4519    pub beginning_of_pass_write_index: Option<u32>,
4520    pub end_of_pass_write_index: Option<u32>,
4521}
4522impl Default for PassTimestampWrites {
4523    fn default() -> Self {
4524        Self {
4525            extensions: Vec::new(),
4526            query_set: None,
4527            beginning_of_pass_write_index: Some(QUERY_SET_INDEX_UNDEFINED),
4528            end_of_pass_write_index: Some(QUERY_SET_INDEX_UNDEFINED),
4529        }
4530    }
4531}
4532impl PassTimestampWrites {
4533    pub fn new() -> Self {
4534        Self::default()
4535    }
4536    pub(crate) fn to_ffi(&self) -> (ffi::WGPUPassTimestampWrites, ChainedStructStorage) {
4537        let mut storage = ChainedStructStorage::new();
4538        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4539        for ext in self.extensions.iter().rev() {
4540            next = ext.push_chain(&mut storage, next);
4541        }
4542        let mut raw: ffi::WGPUPassTimestampWrites = unsafe { std::mem::zeroed() };
4543        raw.nextInChain = next;
4544        raw.querySet = self
4545            .query_set
4546            .as_ref()
4547            .map(|v| v.as_raw())
4548            .unwrap_or(std::ptr::null_mut());
4549        if let Some(value) = self.beginning_of_pass_write_index {
4550            raw.beginningOfPassWriteIndex = value;
4551        }
4552        if let Some(value) = self.end_of_pass_write_index {
4553            raw.endOfPassWriteIndex = value;
4554        }
4555        (raw, storage)
4556    }
4557    pub fn with_extension(mut self, extension: PassTimestampWritesExtension) -> Self {
4558        self.extensions.push(extension);
4559        self
4560    }
4561    pub(crate) fn from_ffi(value: ffi::WGPUPassTimestampWrites) -> Self {
4562        Self {
4563            extensions: Vec::new(),
4564            query_set: Some(unsafe { QuerySet::from_raw(value.querySet) }),
4565            beginning_of_pass_write_index: Some(value.beginningOfPassWriteIndex),
4566            end_of_pass_write_index: Some(value.endOfPassWriteIndex),
4567        }
4568    }
4569}
4570pub struct PipelineLayoutDescriptor {
4571    pub(crate) extensions: Vec<PipelineLayoutDescriptorExtension>,
4572    pub label: Option<String>,
4573    pub bind_group_layouts: Option<Vec<BindGroupLayout>>,
4574    pub immediate_size: Option<u32>,
4575}
4576impl Default for PipelineLayoutDescriptor {
4577    fn default() -> Self {
4578        Self {
4579            extensions: Vec::new(),
4580            label: None,
4581            bind_group_layouts: None,
4582            immediate_size: Some(0),
4583        }
4584    }
4585}
4586impl PipelineLayoutDescriptor {
4587    pub fn new() -> Self {
4588        Self::default()
4589    }
4590    pub(crate) fn to_ffi(
4591        &self,
4592    ) -> (ffi::WGPUPipelineLayoutDescriptor, ChainedStructStorage) {
4593        let mut storage = ChainedStructStorage::new();
4594        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4595        for ext in self.extensions.iter().rev() {
4596            next = ext.push_chain(&mut storage, next);
4597        }
4598        let mut raw: ffi::WGPUPipelineLayoutDescriptor = unsafe { std::mem::zeroed() };
4599        raw.nextInChain = next;
4600        if let Some(value) = &self.label {
4601            raw.label = ffi::WGPUStringView {
4602                data: value.as_ptr().cast(),
4603                length: value.len(),
4604            };
4605        } else {
4606            raw.label = ffi::WGPUStringView {
4607                data: std::ptr::null(),
4608                length: 0,
4609            };
4610        }
4611        raw.bindGroupLayoutCount = self
4612            .bind_group_layouts
4613            .as_ref()
4614            .map(|v| v.len())
4615            .unwrap_or(0);
4616        if let Some(values) = &self.bind_group_layouts {
4617            let len_value = values.len();
4618            let raw_vec: Vec<ffi::WGPUBindGroupLayout> = values
4619                .iter()
4620                .map(|v| v.as_raw())
4621                .collect();
4622            let ptr = storage.push_vec(raw_vec);
4623            raw.bindGroupLayouts = ptr;
4624            raw.bindGroupLayoutCount = len_value;
4625        } else {
4626            raw.bindGroupLayouts = std::ptr::null();
4627            raw.bindGroupLayoutCount = 0;
4628        }
4629        if let Some(value) = self.immediate_size {
4630            raw.immediateSize = value;
4631        }
4632        (raw, storage)
4633    }
4634    pub fn with_extension(
4635        mut self,
4636        extension: PipelineLayoutDescriptorExtension,
4637    ) -> Self {
4638        self.extensions.push(extension);
4639        self
4640    }
4641    pub(crate) fn from_ffi(value: ffi::WGPUPipelineLayoutDescriptor) -> Self {
4642        Self {
4643            extensions: Vec::new(),
4644            label: if value.label.data.is_null() || value.label.length == 0 {
4645                None
4646            } else {
4647                Some(string_view_to_string(value.label))
4648            },
4649            bind_group_layouts: if value.bindGroupLayouts.is_null() {
4650                None
4651            } else {
4652                Some(
4653                    unsafe {
4654                        std::slice::from_raw_parts(
4655                            value.bindGroupLayouts,
4656                            value.bindGroupLayoutCount as usize,
4657                        )
4658                    }
4659                        .iter()
4660                        .map(|raw| unsafe { BindGroupLayout::from_raw(*raw) })
4661                        .collect(),
4662                )
4663            },
4664            immediate_size: Some(value.immediateSize),
4665        }
4666    }
4667}
4668pub struct PipelineLayoutPixelLocalStorage {
4669    pub total_pixel_local_storage_size: Option<u64>,
4670    pub storage_attachments: Option<Vec<PipelineLayoutStorageAttachment>>,
4671}
4672impl Default for PipelineLayoutPixelLocalStorage {
4673    fn default() -> Self {
4674        Self {
4675            total_pixel_local_storage_size: None,
4676            storage_attachments: None,
4677        }
4678    }
4679}
4680impl PipelineLayoutPixelLocalStorage {
4681    pub fn new() -> Self {
4682        Self::default()
4683    }
4684    pub(crate) fn to_ffi(
4685        &self,
4686    ) -> (ffi::WGPUPipelineLayoutPixelLocalStorage, ChainedStructStorage) {
4687        let mut storage = ChainedStructStorage::new();
4688        let mut raw: ffi::WGPUPipelineLayoutPixelLocalStorage = unsafe {
4689            std::mem::zeroed()
4690        };
4691        if let Some(value) = self.total_pixel_local_storage_size {
4692            raw.totalPixelLocalStorageSize = value;
4693        }
4694        raw.storageAttachmentCount = self
4695            .storage_attachments
4696            .as_ref()
4697            .map(|v| v.len())
4698            .unwrap_or(0);
4699        if let Some(values) = &self.storage_attachments {
4700            let len_value = values.len();
4701            let mut raw_vec: Vec<ffi::WGPUPipelineLayoutStorageAttachment> = Vec::with_capacity(
4702                values.len(),
4703            );
4704            for item in values.iter() {
4705                let (raw_item, storage_item) = item.to_ffi();
4706                raw_vec.push(raw_item);
4707                storage.push_storage(storage_item);
4708            }
4709            let ptr = storage.push_vec(raw_vec);
4710            raw.storageAttachments = ptr;
4711            raw.storageAttachmentCount = len_value;
4712        } else {
4713            raw.storageAttachments = std::ptr::null();
4714            raw.storageAttachmentCount = 0;
4715        }
4716        (raw, storage)
4717    }
4718    pub(crate) fn from_ffi(value: ffi::WGPUPipelineLayoutPixelLocalStorage) -> Self {
4719        Self {
4720            total_pixel_local_storage_size: Some(value.totalPixelLocalStorageSize),
4721            storage_attachments: if value.storageAttachments.is_null() {
4722                None
4723            } else {
4724                Some(
4725                    unsafe {
4726                        std::slice::from_raw_parts(
4727                            value.storageAttachments,
4728                            value.storageAttachmentCount as usize,
4729                        )
4730                    }
4731                        .iter()
4732                        .map(|raw| PipelineLayoutStorageAttachment::from_ffi(*raw))
4733                        .collect(),
4734                )
4735            },
4736        }
4737    }
4738}
4739pub struct PipelineLayoutResourceTable {
4740    pub uses_resource_table: Option<bool>,
4741}
4742impl Default for PipelineLayoutResourceTable {
4743    fn default() -> Self {
4744        Self { uses_resource_table: None }
4745    }
4746}
4747impl PipelineLayoutResourceTable {
4748    pub fn new() -> Self {
4749        Self::default()
4750    }
4751    pub(crate) fn to_ffi(
4752        &self,
4753    ) -> (ffi::WGPUPipelineLayoutResourceTable, ChainedStructStorage) {
4754        let mut storage = ChainedStructStorage::new();
4755        let mut raw: ffi::WGPUPipelineLayoutResourceTable = unsafe {
4756            std::mem::zeroed()
4757        };
4758        raw.usesResourceTable = if self.uses_resource_table.unwrap_or(false) {
4759            1
4760        } else {
4761            0
4762        };
4763        (raw, storage)
4764    }
4765    pub(crate) fn from_ffi(value: ffi::WGPUPipelineLayoutResourceTable) -> Self {
4766        Self {
4767            uses_resource_table: Some(value.usesResourceTable != 0),
4768        }
4769    }
4770}
4771pub struct PipelineLayoutStorageAttachment {
4772    pub(crate) extensions: Vec<PipelineLayoutStorageAttachmentExtension>,
4773    pub offset: Option<u64>,
4774    pub format: Option<TextureFormat>,
4775}
4776impl Default for PipelineLayoutStorageAttachment {
4777    fn default() -> Self {
4778        Self {
4779            extensions: Vec::new(),
4780            offset: Some(0),
4781            format: None,
4782        }
4783    }
4784}
4785impl PipelineLayoutStorageAttachment {
4786    pub fn new() -> Self {
4787        Self::default()
4788    }
4789    pub(crate) fn to_ffi(
4790        &self,
4791    ) -> (ffi::WGPUPipelineLayoutStorageAttachment, ChainedStructStorage) {
4792        let mut storage = ChainedStructStorage::new();
4793        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4794        for ext in self.extensions.iter().rev() {
4795            next = ext.push_chain(&mut storage, next);
4796        }
4797        let mut raw: ffi::WGPUPipelineLayoutStorageAttachment = unsafe {
4798            std::mem::zeroed()
4799        };
4800        raw.nextInChain = next;
4801        if let Some(value) = self.offset {
4802            raw.offset = value;
4803        }
4804        if let Some(value) = self.format {
4805            raw.format = value.into();
4806        } else {
4807            raw.format = 0 as ffi::WGPUTextureFormat;
4808        }
4809        (raw, storage)
4810    }
4811    pub fn with_extension(
4812        mut self,
4813        extension: PipelineLayoutStorageAttachmentExtension,
4814    ) -> Self {
4815        self.extensions.push(extension);
4816        self
4817    }
4818    pub(crate) fn from_ffi(value: ffi::WGPUPipelineLayoutStorageAttachment) -> Self {
4819        Self {
4820            extensions: Vec::new(),
4821            offset: Some(value.offset),
4822            format: Some(value.format.into()),
4823        }
4824    }
4825}
4826pub struct PrimitiveState {
4827    pub(crate) extensions: Vec<PrimitiveStateExtension>,
4828    pub topology: Option<PrimitiveTopology>,
4829    pub strip_index_format: Option<IndexFormat>,
4830    pub front_face: Option<FrontFace>,
4831    pub cull_mode: Option<CullMode>,
4832    pub unclipped_depth: Option<bool>,
4833}
4834impl Default for PrimitiveState {
4835    fn default() -> Self {
4836        Self {
4837            extensions: Vec::new(),
4838            topology: Some(PrimitiveTopology::TriangleList),
4839            strip_index_format: None,
4840            front_face: Some(FrontFace::Ccw),
4841            cull_mode: Some(CullMode::None),
4842            unclipped_depth: None,
4843        }
4844    }
4845}
4846impl PrimitiveState {
4847    pub fn new() -> Self {
4848        Self::default()
4849    }
4850    pub(crate) fn to_ffi(&self) -> (ffi::WGPUPrimitiveState, ChainedStructStorage) {
4851        let mut storage = ChainedStructStorage::new();
4852        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4853        for ext in self.extensions.iter().rev() {
4854            next = ext.push_chain(&mut storage, next);
4855        }
4856        let mut raw: ffi::WGPUPrimitiveState = unsafe { std::mem::zeroed() };
4857        raw.nextInChain = next;
4858        if let Some(value) = self.topology {
4859            raw.topology = value.into();
4860        } else {
4861            raw.topology = 0 as ffi::WGPUPrimitiveTopology;
4862        }
4863        if let Some(value) = self.strip_index_format {
4864            raw.stripIndexFormat = value.into();
4865        } else {
4866            raw.stripIndexFormat = 0 as ffi::WGPUIndexFormat;
4867        }
4868        if let Some(value) = self.front_face {
4869            raw.frontFace = value.into();
4870        } else {
4871            raw.frontFace = 0 as ffi::WGPUFrontFace;
4872        }
4873        if let Some(value) = self.cull_mode {
4874            raw.cullMode = value.into();
4875        } else {
4876            raw.cullMode = 0 as ffi::WGPUCullMode;
4877        }
4878        raw.unclippedDepth = if self.unclipped_depth.unwrap_or(false) { 1 } else { 0 };
4879        (raw, storage)
4880    }
4881    pub fn with_extension(mut self, extension: PrimitiveStateExtension) -> Self {
4882        self.extensions.push(extension);
4883        self
4884    }
4885    pub(crate) fn from_ffi(value: ffi::WGPUPrimitiveState) -> Self {
4886        Self {
4887            extensions: Vec::new(),
4888            topology: Some(value.topology.into()),
4889            strip_index_format: Some(value.stripIndexFormat.into()),
4890            front_face: Some(value.frontFace.into()),
4891            cull_mode: Some(value.cullMode.into()),
4892            unclipped_depth: Some(value.unclippedDepth != 0),
4893        }
4894    }
4895}
4896pub struct QuerySetDescriptor {
4897    pub(crate) extensions: Vec<QuerySetDescriptorExtension>,
4898    pub label: Option<String>,
4899    pub r#type: Option<QueryType>,
4900    pub count: Option<u32>,
4901}
4902impl Default for QuerySetDescriptor {
4903    fn default() -> Self {
4904        Self {
4905            extensions: Vec::new(),
4906            label: None,
4907            r#type: None,
4908            count: None,
4909        }
4910    }
4911}
4912impl QuerySetDescriptor {
4913    pub fn new() -> Self {
4914        Self::default()
4915    }
4916    pub(crate) fn to_ffi(&self) -> (ffi::WGPUQuerySetDescriptor, ChainedStructStorage) {
4917        let mut storage = ChainedStructStorage::new();
4918        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4919        for ext in self.extensions.iter().rev() {
4920            next = ext.push_chain(&mut storage, next);
4921        }
4922        let mut raw: ffi::WGPUQuerySetDescriptor = unsafe { std::mem::zeroed() };
4923        raw.nextInChain = next;
4924        if let Some(value) = &self.label {
4925            raw.label = ffi::WGPUStringView {
4926                data: value.as_ptr().cast(),
4927                length: value.len(),
4928            };
4929        } else {
4930            raw.label = ffi::WGPUStringView {
4931                data: std::ptr::null(),
4932                length: 0,
4933            };
4934        }
4935        if let Some(value) = self.r#type {
4936            raw.type_ = value.into();
4937        } else {
4938            raw.type_ = 0 as ffi::WGPUQueryType;
4939        }
4940        if let Some(value) = self.count {
4941            raw.count = value;
4942        }
4943        (raw, storage)
4944    }
4945    pub fn with_extension(mut self, extension: QuerySetDescriptorExtension) -> Self {
4946        self.extensions.push(extension);
4947        self
4948    }
4949    pub(crate) fn from_ffi(value: ffi::WGPUQuerySetDescriptor) -> Self {
4950        Self {
4951            extensions: Vec::new(),
4952            label: if value.label.data.is_null() || value.label.length == 0 {
4953                None
4954            } else {
4955                Some(string_view_to_string(value.label))
4956            },
4957            r#type: Some(value.type_.into()),
4958            count: Some(value.count),
4959        }
4960    }
4961}
4962pub struct QueueDescriptor {
4963    pub(crate) extensions: Vec<QueueDescriptorExtension>,
4964    pub label: Option<String>,
4965}
4966impl Default for QueueDescriptor {
4967    fn default() -> Self {
4968        Self {
4969            extensions: Vec::new(),
4970            label: None,
4971        }
4972    }
4973}
4974impl QueueDescriptor {
4975    pub fn new() -> Self {
4976        Self::default()
4977    }
4978    pub(crate) fn to_ffi(&self) -> (ffi::WGPUQueueDescriptor, ChainedStructStorage) {
4979        let mut storage = ChainedStructStorage::new();
4980        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
4981        for ext in self.extensions.iter().rev() {
4982            next = ext.push_chain(&mut storage, next);
4983        }
4984        let mut raw: ffi::WGPUQueueDescriptor = unsafe { std::mem::zeroed() };
4985        raw.nextInChain = next;
4986        if let Some(value) = &self.label {
4987            raw.label = ffi::WGPUStringView {
4988                data: value.as_ptr().cast(),
4989                length: value.len(),
4990            };
4991        } else {
4992            raw.label = ffi::WGPUStringView {
4993                data: std::ptr::null(),
4994                length: 0,
4995            };
4996        }
4997        (raw, storage)
4998    }
4999    pub fn with_extension(mut self, extension: QueueDescriptorExtension) -> Self {
5000        self.extensions.push(extension);
5001        self
5002    }
5003    pub(crate) fn from_ffi(value: ffi::WGPUQueueDescriptor) -> Self {
5004        Self {
5005            extensions: Vec::new(),
5006            label: if value.label.data.is_null() || value.label.length == 0 {
5007                None
5008            } else {
5009                Some(string_view_to_string(value.label))
5010            },
5011        }
5012    }
5013}
5014pub struct RenderBundleDescriptor {
5015    pub(crate) extensions: Vec<RenderBundleDescriptorExtension>,
5016    pub label: Option<String>,
5017}
5018impl Default for RenderBundleDescriptor {
5019    fn default() -> Self {
5020        Self {
5021            extensions: Vec::new(),
5022            label: None,
5023        }
5024    }
5025}
5026impl RenderBundleDescriptor {
5027    pub fn new() -> Self {
5028        Self::default()
5029    }
5030    pub(crate) fn to_ffi(
5031        &self,
5032    ) -> (ffi::WGPURenderBundleDescriptor, ChainedStructStorage) {
5033        let mut storage = ChainedStructStorage::new();
5034        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5035        for ext in self.extensions.iter().rev() {
5036            next = ext.push_chain(&mut storage, next);
5037        }
5038        let mut raw: ffi::WGPURenderBundleDescriptor = unsafe { std::mem::zeroed() };
5039        raw.nextInChain = next;
5040        if let Some(value) = &self.label {
5041            raw.label = ffi::WGPUStringView {
5042                data: value.as_ptr().cast(),
5043                length: value.len(),
5044            };
5045        } else {
5046            raw.label = ffi::WGPUStringView {
5047                data: std::ptr::null(),
5048                length: 0,
5049            };
5050        }
5051        (raw, storage)
5052    }
5053    pub fn with_extension(mut self, extension: RenderBundleDescriptorExtension) -> Self {
5054        self.extensions.push(extension);
5055        self
5056    }
5057    pub(crate) fn from_ffi(value: ffi::WGPURenderBundleDescriptor) -> Self {
5058        Self {
5059            extensions: Vec::new(),
5060            label: if value.label.data.is_null() || value.label.length == 0 {
5061                None
5062            } else {
5063                Some(string_view_to_string(value.label))
5064            },
5065        }
5066    }
5067}
5068pub struct RenderBundleEncoderDescriptor {
5069    pub(crate) extensions: Vec<RenderBundleEncoderDescriptorExtension>,
5070    pub label: Option<String>,
5071    pub color_formats: Option<Vec<TextureFormat>>,
5072    pub depth_stencil_format: Option<TextureFormat>,
5073    pub sample_count: Option<u32>,
5074    pub depth_read_only: Option<bool>,
5075    pub stencil_read_only: Option<bool>,
5076}
5077impl Default for RenderBundleEncoderDescriptor {
5078    fn default() -> Self {
5079        Self {
5080            extensions: Vec::new(),
5081            label: None,
5082            color_formats: None,
5083            depth_stencil_format: None,
5084            sample_count: Some(1),
5085            depth_read_only: None,
5086            stencil_read_only: None,
5087        }
5088    }
5089}
5090impl RenderBundleEncoderDescriptor {
5091    pub fn new() -> Self {
5092        Self::default()
5093    }
5094    pub(crate) fn to_ffi(
5095        &self,
5096    ) -> (ffi::WGPURenderBundleEncoderDescriptor, ChainedStructStorage) {
5097        let mut storage = ChainedStructStorage::new();
5098        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5099        for ext in self.extensions.iter().rev() {
5100            next = ext.push_chain(&mut storage, next);
5101        }
5102        let mut raw: ffi::WGPURenderBundleEncoderDescriptor = unsafe {
5103            std::mem::zeroed()
5104        };
5105        raw.nextInChain = next;
5106        if let Some(value) = &self.label {
5107            raw.label = ffi::WGPUStringView {
5108                data: value.as_ptr().cast(),
5109                length: value.len(),
5110            };
5111        } else {
5112            raw.label = ffi::WGPUStringView {
5113                data: std::ptr::null(),
5114                length: 0,
5115            };
5116        }
5117        raw.colorFormatCount = self.color_formats.as_ref().map(|v| v.len()).unwrap_or(0);
5118        if let Some(values) = &self.color_formats {
5119            let len_value = values.len();
5120            let raw_vec: Vec<ffi::WGPUTextureFormat> = values
5121                .iter()
5122                .map(|v| (*v).into())
5123                .collect();
5124            let ptr = storage.push_vec(raw_vec);
5125            raw.colorFormats = ptr;
5126            raw.colorFormatCount = len_value;
5127        } else {
5128            raw.colorFormats = std::ptr::null();
5129            raw.colorFormatCount = 0;
5130        }
5131        if let Some(value) = self.depth_stencil_format {
5132            raw.depthStencilFormat = value.into();
5133        } else {
5134            raw.depthStencilFormat = 0 as ffi::WGPUTextureFormat;
5135        }
5136        if let Some(value) = self.sample_count {
5137            raw.sampleCount = value;
5138        }
5139        raw.depthReadOnly = if self.depth_read_only.unwrap_or(false) { 1 } else { 0 };
5140        raw.stencilReadOnly = if self.stencil_read_only.unwrap_or(false) {
5141            1
5142        } else {
5143            0
5144        };
5145        (raw, storage)
5146    }
5147    pub fn with_extension(
5148        mut self,
5149        extension: RenderBundleEncoderDescriptorExtension,
5150    ) -> Self {
5151        self.extensions.push(extension);
5152        self
5153    }
5154    pub(crate) fn from_ffi(value: ffi::WGPURenderBundleEncoderDescriptor) -> Self {
5155        Self {
5156            extensions: Vec::new(),
5157            label: if value.label.data.is_null() || value.label.length == 0 {
5158                None
5159            } else {
5160                Some(string_view_to_string(value.label))
5161            },
5162            color_formats: if value.colorFormats.is_null() {
5163                None
5164            } else {
5165                Some(
5166                    unsafe {
5167                        std::slice::from_raw_parts(
5168                            value.colorFormats,
5169                            value.colorFormatCount as usize,
5170                        )
5171                    }
5172                        .iter()
5173                        .map(|raw| TextureFormat::from(*raw))
5174                        .collect(),
5175                )
5176            },
5177            depth_stencil_format: Some(value.depthStencilFormat.into()),
5178            sample_count: Some(value.sampleCount),
5179            depth_read_only: Some(value.depthReadOnly != 0),
5180            stencil_read_only: Some(value.stencilReadOnly != 0),
5181        }
5182    }
5183}
5184pub struct RenderPassColorAttachment {
5185    pub(crate) extensions: Vec<RenderPassColorAttachmentExtension>,
5186    pub view: Option<TextureView>,
5187    pub depth_slice: Option<u32>,
5188    pub resolve_target: Option<TextureView>,
5189    pub load_op: Option<LoadOp>,
5190    pub store_op: Option<StoreOp>,
5191    pub clear_value: Option<Color>,
5192}
5193impl Default for RenderPassColorAttachment {
5194    fn default() -> Self {
5195        Self {
5196            extensions: Vec::new(),
5197            view: None,
5198            depth_slice: Some(DEPTH_SLICE_UNDEFINED),
5199            resolve_target: None,
5200            load_op: None,
5201            store_op: None,
5202            clear_value: None,
5203        }
5204    }
5205}
5206impl RenderPassColorAttachment {
5207    pub fn new() -> Self {
5208        Self::default()
5209    }
5210    pub(crate) fn to_ffi(
5211        &self,
5212    ) -> (ffi::WGPURenderPassColorAttachment, ChainedStructStorage) {
5213        let mut storage = ChainedStructStorage::new();
5214        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5215        for ext in self.extensions.iter().rev() {
5216            next = ext.push_chain(&mut storage, next);
5217        }
5218        let mut raw: ffi::WGPURenderPassColorAttachment = unsafe { std::mem::zeroed() };
5219        raw.nextInChain = next;
5220        raw.view = self
5221            .view
5222            .as_ref()
5223            .map(|v| v.as_raw())
5224            .unwrap_or(std::ptr::null_mut());
5225        if let Some(value) = self.depth_slice {
5226            raw.depthSlice = value;
5227        }
5228        raw.resolveTarget = self
5229            .resolve_target
5230            .as_ref()
5231            .map(|v| v.as_raw())
5232            .unwrap_or(std::ptr::null_mut());
5233        if let Some(value) = self.load_op {
5234            raw.loadOp = value.into();
5235        } else {
5236            raw.loadOp = 0 as ffi::WGPULoadOp;
5237        }
5238        if let Some(value) = self.store_op {
5239            raw.storeOp = value.into();
5240        } else {
5241            raw.storeOp = 0 as ffi::WGPUStoreOp;
5242        }
5243        if let Some(value) = &self.clear_value {
5244            let (raw_value, storage_value) = value.to_ffi();
5245            raw.clearValue = raw_value;
5246            storage.push_storage(storage_value);
5247        }
5248        (raw, storage)
5249    }
5250    pub fn with_extension(
5251        mut self,
5252        extension: RenderPassColorAttachmentExtension,
5253    ) -> Self {
5254        self.extensions.push(extension);
5255        self
5256    }
5257    pub(crate) fn from_ffi(value: ffi::WGPURenderPassColorAttachment) -> Self {
5258        Self {
5259            extensions: Vec::new(),
5260            view: if value.view.is_null() {
5261                None
5262            } else {
5263                Some(unsafe { TextureView::from_raw(value.view) })
5264            },
5265            depth_slice: Some(value.depthSlice),
5266            resolve_target: if value.resolveTarget.is_null() {
5267                None
5268            } else {
5269                Some(unsafe { TextureView::from_raw(value.resolveTarget) })
5270            },
5271            load_op: Some(value.loadOp.into()),
5272            store_op: Some(value.storeOp.into()),
5273            clear_value: Some(Color::from_ffi(value.clearValue)),
5274        }
5275    }
5276}
5277pub struct RenderPassDepthStencilAttachment {
5278    pub(crate) extensions: Vec<RenderPassDepthStencilAttachmentExtension>,
5279    pub view: Option<TextureView>,
5280    pub depth_load_op: Option<LoadOp>,
5281    pub depth_store_op: Option<StoreOp>,
5282    pub depth_clear_value: Option<f32>,
5283    pub depth_read_only: Option<bool>,
5284    pub stencil_load_op: Option<LoadOp>,
5285    pub stencil_store_op: Option<StoreOp>,
5286    pub stencil_clear_value: Option<u32>,
5287    pub stencil_read_only: Option<bool>,
5288}
5289impl Default for RenderPassDepthStencilAttachment {
5290    fn default() -> Self {
5291        Self {
5292            extensions: Vec::new(),
5293            view: None,
5294            depth_load_op: None,
5295            depth_store_op: None,
5296            depth_clear_value: Some(DEPTH_CLEAR_VALUE_UNDEFINED),
5297            depth_read_only: None,
5298            stencil_load_op: None,
5299            stencil_store_op: None,
5300            stencil_clear_value: Some(0),
5301            stencil_read_only: None,
5302        }
5303    }
5304}
5305impl RenderPassDepthStencilAttachment {
5306    pub fn new() -> Self {
5307        Self::default()
5308    }
5309    pub(crate) fn to_ffi(
5310        &self,
5311    ) -> (ffi::WGPURenderPassDepthStencilAttachment, ChainedStructStorage) {
5312        let mut storage = ChainedStructStorage::new();
5313        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5314        for ext in self.extensions.iter().rev() {
5315            next = ext.push_chain(&mut storage, next);
5316        }
5317        let mut raw: ffi::WGPURenderPassDepthStencilAttachment = unsafe {
5318            std::mem::zeroed()
5319        };
5320        raw.nextInChain = next;
5321        raw.view = self
5322            .view
5323            .as_ref()
5324            .map(|v| v.as_raw())
5325            .unwrap_or(std::ptr::null_mut());
5326        if let Some(value) = self.depth_load_op {
5327            raw.depthLoadOp = value.into();
5328        } else {
5329            raw.depthLoadOp = 0 as ffi::WGPULoadOp;
5330        }
5331        if let Some(value) = self.depth_store_op {
5332            raw.depthStoreOp = value.into();
5333        } else {
5334            raw.depthStoreOp = 0 as ffi::WGPUStoreOp;
5335        }
5336        if let Some(value) = self.depth_clear_value {
5337            raw.depthClearValue = value;
5338        }
5339        raw.depthReadOnly = if self.depth_read_only.unwrap_or(false) { 1 } else { 0 };
5340        if let Some(value) = self.stencil_load_op {
5341            raw.stencilLoadOp = value.into();
5342        } else {
5343            raw.stencilLoadOp = 0 as ffi::WGPULoadOp;
5344        }
5345        if let Some(value) = self.stencil_store_op {
5346            raw.stencilStoreOp = value.into();
5347        } else {
5348            raw.stencilStoreOp = 0 as ffi::WGPUStoreOp;
5349        }
5350        if let Some(value) = self.stencil_clear_value {
5351            raw.stencilClearValue = value;
5352        }
5353        raw.stencilReadOnly = if self.stencil_read_only.unwrap_or(false) {
5354            1
5355        } else {
5356            0
5357        };
5358        (raw, storage)
5359    }
5360    pub fn with_extension(
5361        mut self,
5362        extension: RenderPassDepthStencilAttachmentExtension,
5363    ) -> Self {
5364        self.extensions.push(extension);
5365        self
5366    }
5367    pub(crate) fn from_ffi(value: ffi::WGPURenderPassDepthStencilAttachment) -> Self {
5368        Self {
5369            extensions: Vec::new(),
5370            view: Some(unsafe { TextureView::from_raw(value.view) }),
5371            depth_load_op: Some(value.depthLoadOp.into()),
5372            depth_store_op: Some(value.depthStoreOp.into()),
5373            depth_clear_value: Some(value.depthClearValue),
5374            depth_read_only: Some(value.depthReadOnly != 0),
5375            stencil_load_op: Some(value.stencilLoadOp.into()),
5376            stencil_store_op: Some(value.stencilStoreOp.into()),
5377            stencil_clear_value: Some(value.stencilClearValue),
5378            stencil_read_only: Some(value.stencilReadOnly != 0),
5379        }
5380    }
5381}
5382pub struct RenderPassDescriptor {
5383    pub(crate) extensions: Vec<RenderPassDescriptorExtension>,
5384    pub label: Option<String>,
5385    pub color_attachments: Option<Vec<RenderPassColorAttachment>>,
5386    pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachment>,
5387    pub occlusion_query_set: Option<QuerySet>,
5388    pub timestamp_writes: Option<PassTimestampWrites>,
5389}
5390impl Default for RenderPassDescriptor {
5391    fn default() -> Self {
5392        Self {
5393            extensions: Vec::new(),
5394            label: None,
5395            color_attachments: None,
5396            depth_stencil_attachment: None,
5397            occlusion_query_set: None,
5398            timestamp_writes: None,
5399        }
5400    }
5401}
5402impl RenderPassDescriptor {
5403    pub fn new() -> Self {
5404        Self::default()
5405    }
5406    pub(crate) fn to_ffi(
5407        &self,
5408    ) -> (ffi::WGPURenderPassDescriptor, ChainedStructStorage) {
5409        let mut storage = ChainedStructStorage::new();
5410        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5411        for ext in self.extensions.iter().rev() {
5412            next = ext.push_chain(&mut storage, next);
5413        }
5414        let mut raw: ffi::WGPURenderPassDescriptor = unsafe { std::mem::zeroed() };
5415        raw.nextInChain = next;
5416        if let Some(value) = &self.label {
5417            raw.label = ffi::WGPUStringView {
5418                data: value.as_ptr().cast(),
5419                length: value.len(),
5420            };
5421        } else {
5422            raw.label = ffi::WGPUStringView {
5423                data: std::ptr::null(),
5424                length: 0,
5425            };
5426        }
5427        raw.colorAttachmentCount = self
5428            .color_attachments
5429            .as_ref()
5430            .map(|v| v.len())
5431            .unwrap_or(0);
5432        if let Some(values) = &self.color_attachments {
5433            let len_value = values.len();
5434            let mut raw_vec: Vec<ffi::WGPURenderPassColorAttachment> = Vec::with_capacity(
5435                values.len(),
5436            );
5437            for item in values.iter() {
5438                let (raw_item, storage_item) = item.to_ffi();
5439                raw_vec.push(raw_item);
5440                storage.push_storage(storage_item);
5441            }
5442            let ptr = storage.push_vec(raw_vec);
5443            raw.colorAttachments = ptr;
5444            raw.colorAttachmentCount = len_value;
5445        } else {
5446            raw.colorAttachments = std::ptr::null();
5447            raw.colorAttachmentCount = 0;
5448        }
5449        if let Some(value) = &self.depth_stencil_attachment {
5450            let (raw_value, storage_value) = value.to_ffi();
5451            let ptr = storage.push_value(raw_value);
5452            raw.depthStencilAttachment = ptr;
5453            storage.push_storage(storage_value);
5454        } else {
5455            raw.depthStencilAttachment = std::ptr::null();
5456        }
5457        raw.occlusionQuerySet = self
5458            .occlusion_query_set
5459            .as_ref()
5460            .map(|v| v.as_raw())
5461            .unwrap_or(std::ptr::null_mut());
5462        if let Some(value) = &self.timestamp_writes {
5463            let (raw_value, storage_value) = value.to_ffi();
5464            let ptr = storage.push_value(raw_value);
5465            raw.timestampWrites = ptr;
5466            storage.push_storage(storage_value);
5467        } else {
5468            raw.timestampWrites = std::ptr::null();
5469        }
5470        (raw, storage)
5471    }
5472    pub fn with_extension(mut self, extension: RenderPassDescriptorExtension) -> Self {
5473        self.extensions.push(extension);
5474        self
5475    }
5476    pub(crate) fn from_ffi(value: ffi::WGPURenderPassDescriptor) -> Self {
5477        Self {
5478            extensions: Vec::new(),
5479            label: if value.label.data.is_null() || value.label.length == 0 {
5480                None
5481            } else {
5482                Some(string_view_to_string(value.label))
5483            },
5484            color_attachments: if value.colorAttachments.is_null() {
5485                None
5486            } else {
5487                Some(
5488                    unsafe {
5489                        std::slice::from_raw_parts(
5490                            value.colorAttachments,
5491                            value.colorAttachmentCount as usize,
5492                        )
5493                    }
5494                        .iter()
5495                        .map(|raw| RenderPassColorAttachment::from_ffi(*raw))
5496                        .collect(),
5497                )
5498            },
5499            depth_stencil_attachment: if value.depthStencilAttachment.is_null() {
5500                None
5501            } else {
5502                Some(
5503                    RenderPassDepthStencilAttachment::from_ffi(unsafe {
5504                        *value.depthStencilAttachment
5505                    }),
5506                )
5507            },
5508            occlusion_query_set: if value.occlusionQuerySet.is_null() {
5509                None
5510            } else {
5511                Some(unsafe { QuerySet::from_raw(value.occlusionQuerySet) })
5512            },
5513            timestamp_writes: if value.timestampWrites.is_null() {
5514                None
5515            } else {
5516                Some(PassTimestampWrites::from_ffi(unsafe { *value.timestampWrites }))
5517            },
5518        }
5519    }
5520}
5521pub struct RenderPassDescriptorExpandResolveRect {
5522    pub x: Option<u32>,
5523    pub y: Option<u32>,
5524    pub width: Option<u32>,
5525    pub height: Option<u32>,
5526}
5527impl Default for RenderPassDescriptorExpandResolveRect {
5528    fn default() -> Self {
5529        Self {
5530            x: None,
5531            y: None,
5532            width: None,
5533            height: None,
5534        }
5535    }
5536}
5537impl RenderPassDescriptorExpandResolveRect {
5538    pub fn new() -> Self {
5539        Self::default()
5540    }
5541    pub(crate) fn to_ffi(
5542        &self,
5543    ) -> (ffi::WGPURenderPassDescriptorExpandResolveRect, ChainedStructStorage) {
5544        let mut storage = ChainedStructStorage::new();
5545        let mut raw: ffi::WGPURenderPassDescriptorExpandResolveRect = unsafe {
5546            std::mem::zeroed()
5547        };
5548        if let Some(value) = self.x {
5549            raw.x = value;
5550        }
5551        if let Some(value) = self.y {
5552            raw.y = value;
5553        }
5554        if let Some(value) = self.width {
5555            raw.width = value;
5556        }
5557        if let Some(value) = self.height {
5558            raw.height = value;
5559        }
5560        (raw, storage)
5561    }
5562    pub(crate) fn from_ffi(
5563        value: ffi::WGPURenderPassDescriptorExpandResolveRect,
5564    ) -> Self {
5565        Self {
5566            x: Some(value.x),
5567            y: Some(value.y),
5568            width: Some(value.width),
5569            height: Some(value.height),
5570        }
5571    }
5572}
5573pub struct RenderPassDescriptorResolveRect {
5574    pub color_offset_x: Option<u32>,
5575    pub color_offset_y: Option<u32>,
5576    pub resolve_offset_x: Option<u32>,
5577    pub resolve_offset_y: Option<u32>,
5578    pub width: Option<u32>,
5579    pub height: Option<u32>,
5580}
5581impl Default for RenderPassDescriptorResolveRect {
5582    fn default() -> Self {
5583        Self {
5584            color_offset_x: None,
5585            color_offset_y: None,
5586            resolve_offset_x: None,
5587            resolve_offset_y: None,
5588            width: None,
5589            height: None,
5590        }
5591    }
5592}
5593impl RenderPassDescriptorResolveRect {
5594    pub fn new() -> Self {
5595        Self::default()
5596    }
5597    pub(crate) fn to_ffi(
5598        &self,
5599    ) -> (ffi::WGPURenderPassDescriptorResolveRect, ChainedStructStorage) {
5600        let mut storage = ChainedStructStorage::new();
5601        let mut raw: ffi::WGPURenderPassDescriptorResolveRect = unsafe {
5602            std::mem::zeroed()
5603        };
5604        if let Some(value) = self.color_offset_x {
5605            raw.colorOffsetX = value;
5606        }
5607        if let Some(value) = self.color_offset_y {
5608            raw.colorOffsetY = value;
5609        }
5610        if let Some(value) = self.resolve_offset_x {
5611            raw.resolveOffsetX = value;
5612        }
5613        if let Some(value) = self.resolve_offset_y {
5614            raw.resolveOffsetY = value;
5615        }
5616        if let Some(value) = self.width {
5617            raw.width = value;
5618        }
5619        if let Some(value) = self.height {
5620            raw.height = value;
5621        }
5622        (raw, storage)
5623    }
5624    pub(crate) fn from_ffi(value: ffi::WGPURenderPassDescriptorResolveRect) -> Self {
5625        Self {
5626            color_offset_x: Some(value.colorOffsetX),
5627            color_offset_y: Some(value.colorOffsetY),
5628            resolve_offset_x: Some(value.resolveOffsetX),
5629            resolve_offset_y: Some(value.resolveOffsetY),
5630            width: Some(value.width),
5631            height: Some(value.height),
5632        }
5633    }
5634}
5635pub struct RenderPassMaxDrawCount {
5636    pub max_draw_count: Option<u64>,
5637}
5638impl Default for RenderPassMaxDrawCount {
5639    fn default() -> Self {
5640        Self {
5641            max_draw_count: Some(50000000),
5642        }
5643    }
5644}
5645impl RenderPassMaxDrawCount {
5646    pub fn new() -> Self {
5647        Self::default()
5648    }
5649    pub(crate) fn to_ffi(
5650        &self,
5651    ) -> (ffi::WGPURenderPassMaxDrawCount, ChainedStructStorage) {
5652        let mut storage = ChainedStructStorage::new();
5653        let mut raw: ffi::WGPURenderPassMaxDrawCount = unsafe { std::mem::zeroed() };
5654        if let Some(value) = self.max_draw_count {
5655            raw.maxDrawCount = value;
5656        }
5657        (raw, storage)
5658    }
5659    pub(crate) fn from_ffi(value: ffi::WGPURenderPassMaxDrawCount) -> Self {
5660        Self {
5661            max_draw_count: Some(value.maxDrawCount),
5662        }
5663    }
5664}
5665pub struct RenderPassPixelLocalStorage {
5666    pub total_pixel_local_storage_size: Option<u64>,
5667    pub storage_attachments: Option<Vec<RenderPassStorageAttachment>>,
5668}
5669impl Default for RenderPassPixelLocalStorage {
5670    fn default() -> Self {
5671        Self {
5672            total_pixel_local_storage_size: None,
5673            storage_attachments: None,
5674        }
5675    }
5676}
5677impl RenderPassPixelLocalStorage {
5678    pub fn new() -> Self {
5679        Self::default()
5680    }
5681    pub(crate) fn to_ffi(
5682        &self,
5683    ) -> (ffi::WGPURenderPassPixelLocalStorage, ChainedStructStorage) {
5684        let mut storage = ChainedStructStorage::new();
5685        let mut raw: ffi::WGPURenderPassPixelLocalStorage = unsafe {
5686            std::mem::zeroed()
5687        };
5688        if let Some(value) = self.total_pixel_local_storage_size {
5689            raw.totalPixelLocalStorageSize = value;
5690        }
5691        raw.storageAttachmentCount = self
5692            .storage_attachments
5693            .as_ref()
5694            .map(|v| v.len())
5695            .unwrap_or(0);
5696        if let Some(values) = &self.storage_attachments {
5697            let len_value = values.len();
5698            let mut raw_vec: Vec<ffi::WGPURenderPassStorageAttachment> = Vec::with_capacity(
5699                values.len(),
5700            );
5701            for item in values.iter() {
5702                let (raw_item, storage_item) = item.to_ffi();
5703                raw_vec.push(raw_item);
5704                storage.push_storage(storage_item);
5705            }
5706            let ptr = storage.push_vec(raw_vec);
5707            raw.storageAttachments = ptr;
5708            raw.storageAttachmentCount = len_value;
5709        } else {
5710            raw.storageAttachments = std::ptr::null();
5711            raw.storageAttachmentCount = 0;
5712        }
5713        (raw, storage)
5714    }
5715    pub(crate) fn from_ffi(value: ffi::WGPURenderPassPixelLocalStorage) -> Self {
5716        Self {
5717            total_pixel_local_storage_size: Some(value.totalPixelLocalStorageSize),
5718            storage_attachments: if value.storageAttachments.is_null() {
5719                None
5720            } else {
5721                Some(
5722                    unsafe {
5723                        std::slice::from_raw_parts(
5724                            value.storageAttachments,
5725                            value.storageAttachmentCount as usize,
5726                        )
5727                    }
5728                        .iter()
5729                        .map(|raw| RenderPassStorageAttachment::from_ffi(*raw))
5730                        .collect(),
5731                )
5732            },
5733        }
5734    }
5735}
5736pub struct RenderPassStorageAttachment {
5737    pub(crate) extensions: Vec<RenderPassStorageAttachmentExtension>,
5738    pub offset: Option<u64>,
5739    pub storage: Option<TextureView>,
5740    pub load_op: Option<LoadOp>,
5741    pub store_op: Option<StoreOp>,
5742    pub clear_value: Option<Color>,
5743}
5744impl Default for RenderPassStorageAttachment {
5745    fn default() -> Self {
5746        Self {
5747            extensions: Vec::new(),
5748            offset: Some(0),
5749            storage: None,
5750            load_op: None,
5751            store_op: None,
5752            clear_value: None,
5753        }
5754    }
5755}
5756impl RenderPassStorageAttachment {
5757    pub fn new() -> Self {
5758        Self::default()
5759    }
5760    pub(crate) fn to_ffi(
5761        &self,
5762    ) -> (ffi::WGPURenderPassStorageAttachment, ChainedStructStorage) {
5763        let mut storage = ChainedStructStorage::new();
5764        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5765        for ext in self.extensions.iter().rev() {
5766            next = ext.push_chain(&mut storage, next);
5767        }
5768        let mut raw: ffi::WGPURenderPassStorageAttachment = unsafe {
5769            std::mem::zeroed()
5770        };
5771        raw.nextInChain = next;
5772        if let Some(value) = self.offset {
5773            raw.offset = value;
5774        }
5775        raw.storage = self
5776            .storage
5777            .as_ref()
5778            .map(|v| v.as_raw())
5779            .unwrap_or(std::ptr::null_mut());
5780        if let Some(value) = self.load_op {
5781            raw.loadOp = value.into();
5782        } else {
5783            raw.loadOp = 0 as ffi::WGPULoadOp;
5784        }
5785        if let Some(value) = self.store_op {
5786            raw.storeOp = value.into();
5787        } else {
5788            raw.storeOp = 0 as ffi::WGPUStoreOp;
5789        }
5790        if let Some(value) = &self.clear_value {
5791            let (raw_value, storage_value) = value.to_ffi();
5792            raw.clearValue = raw_value;
5793            storage.push_storage(storage_value);
5794        }
5795        (raw, storage)
5796    }
5797    pub fn with_extension(
5798        mut self,
5799        extension: RenderPassStorageAttachmentExtension,
5800    ) -> Self {
5801        self.extensions.push(extension);
5802        self
5803    }
5804    pub(crate) fn from_ffi(value: ffi::WGPURenderPassStorageAttachment) -> Self {
5805        Self {
5806            extensions: Vec::new(),
5807            offset: Some(value.offset),
5808            storage: Some(unsafe { TextureView::from_raw(value.storage) }),
5809            load_op: Some(value.loadOp.into()),
5810            store_op: Some(value.storeOp.into()),
5811            clear_value: Some(Color::from_ffi(value.clearValue)),
5812        }
5813    }
5814}
5815pub struct RenderPipelineDescriptor {
5816    pub(crate) extensions: Vec<RenderPipelineDescriptorExtension>,
5817    pub label: Option<String>,
5818    pub layout: Option<PipelineLayout>,
5819    pub vertex: Option<VertexState>,
5820    pub primitive: Option<PrimitiveState>,
5821    pub depth_stencil: Option<DepthStencilState>,
5822    pub multisample: Option<MultisampleState>,
5823    pub fragment: Option<FragmentState>,
5824}
5825impl Default for RenderPipelineDescriptor {
5826    fn default() -> Self {
5827        Self {
5828            extensions: Vec::new(),
5829            label: None,
5830            layout: None,
5831            vertex: None,
5832            primitive: None,
5833            depth_stencil: None,
5834            multisample: None,
5835            fragment: None,
5836        }
5837    }
5838}
5839impl RenderPipelineDescriptor {
5840    pub fn new() -> Self {
5841        Self::default()
5842    }
5843    pub(crate) fn to_ffi(
5844        &self,
5845    ) -> (ffi::WGPURenderPipelineDescriptor, ChainedStructStorage) {
5846        let mut storage = ChainedStructStorage::new();
5847        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
5848        for ext in self.extensions.iter().rev() {
5849            next = ext.push_chain(&mut storage, next);
5850        }
5851        let mut raw: ffi::WGPURenderPipelineDescriptor = unsafe { std::mem::zeroed() };
5852        raw.nextInChain = next;
5853        if let Some(value) = &self.label {
5854            raw.label = ffi::WGPUStringView {
5855                data: value.as_ptr().cast(),
5856                length: value.len(),
5857            };
5858        } else {
5859            raw.label = ffi::WGPUStringView {
5860                data: std::ptr::null(),
5861                length: 0,
5862            };
5863        }
5864        raw.layout = self
5865            .layout
5866            .as_ref()
5867            .map(|v| v.as_raw())
5868            .unwrap_or(std::ptr::null_mut());
5869        if let Some(value) = &self.vertex {
5870            let (raw_value, storage_value) = value.to_ffi();
5871            raw.vertex = raw_value;
5872            storage.push_storage(storage_value);
5873        }
5874        if let Some(value) = &self.primitive {
5875            let (raw_value, storage_value) = value.to_ffi();
5876            raw.primitive = raw_value;
5877            storage.push_storage(storage_value);
5878        }
5879        if let Some(value) = &self.depth_stencil {
5880            let (raw_value, storage_value) = value.to_ffi();
5881            let ptr = storage.push_value(raw_value);
5882            raw.depthStencil = ptr;
5883            storage.push_storage(storage_value);
5884        } else {
5885            raw.depthStencil = std::ptr::null();
5886        }
5887        if let Some(value) = &self.multisample {
5888            let (raw_value, storage_value) = value.to_ffi();
5889            raw.multisample = raw_value;
5890            storage.push_storage(storage_value);
5891        }
5892        if let Some(value) = &self.fragment {
5893            let (raw_value, storage_value) = value.to_ffi();
5894            let ptr = storage.push_value(raw_value);
5895            raw.fragment = ptr;
5896            storage.push_storage(storage_value);
5897        } else {
5898            raw.fragment = std::ptr::null();
5899        }
5900        (raw, storage)
5901    }
5902    pub fn with_extension(
5903        mut self,
5904        extension: RenderPipelineDescriptorExtension,
5905    ) -> Self {
5906        self.extensions.push(extension);
5907        self
5908    }
5909    pub(crate) fn from_ffi(value: ffi::WGPURenderPipelineDescriptor) -> Self {
5910        Self {
5911            extensions: Vec::new(),
5912            label: if value.label.data.is_null() || value.label.length == 0 {
5913                None
5914            } else {
5915                Some(string_view_to_string(value.label))
5916            },
5917            layout: if value.layout.is_null() {
5918                None
5919            } else {
5920                Some(unsafe { PipelineLayout::from_raw(value.layout) })
5921            },
5922            vertex: Some(VertexState::from_ffi(value.vertex)),
5923            primitive: Some(PrimitiveState::from_ffi(value.primitive)),
5924            depth_stencil: if value.depthStencil.is_null() {
5925                None
5926            } else {
5927                Some(DepthStencilState::from_ffi(unsafe { *value.depthStencil }))
5928            },
5929            multisample: Some(MultisampleState::from_ffi(value.multisample)),
5930            fragment: if value.fragment.is_null() {
5931                None
5932            } else {
5933                Some(FragmentState::from_ffi(unsafe { *value.fragment }))
5934            },
5935        }
5936    }
5937}
5938pub struct RequestAdapterWebGPUBackendOptions {}
5939impl Default for RequestAdapterWebGPUBackendOptions {
5940    fn default() -> Self {
5941        Self {}
5942    }
5943}
5944impl RequestAdapterWebGPUBackendOptions {
5945    pub fn new() -> Self {
5946        Self::default()
5947    }
5948    pub(crate) fn to_ffi(
5949        &self,
5950    ) -> (ffi::WGPURequestAdapterWebGPUBackendOptions, ChainedStructStorage) {
5951        let mut storage = ChainedStructStorage::new();
5952        let mut raw: ffi::WGPURequestAdapterWebGPUBackendOptions = unsafe {
5953            std::mem::zeroed()
5954        };
5955        (raw, storage)
5956    }
5957    pub(crate) fn from_ffi(value: ffi::WGPURequestAdapterWebGPUBackendOptions) -> Self {
5958        let _ = value;
5959        Self::default()
5960    }
5961}
5962pub struct RequestAdapterWebXROptions {
5963    pub xr_compatible: Option<bool>,
5964}
5965impl Default for RequestAdapterWebXROptions {
5966    fn default() -> Self {
5967        Self { xr_compatible: None }
5968    }
5969}
5970impl RequestAdapterWebXROptions {
5971    pub fn new() -> Self {
5972        Self::default()
5973    }
5974    pub(crate) fn to_ffi(
5975        &self,
5976    ) -> (ffi::WGPURequestAdapterWebXROptions, ChainedStructStorage) {
5977        let mut storage = ChainedStructStorage::new();
5978        let mut raw: ffi::WGPURequestAdapterWebXROptions = unsafe { std::mem::zeroed() };
5979        raw.xrCompatible = if self.xr_compatible.unwrap_or(false) { 1 } else { 0 };
5980        (raw, storage)
5981    }
5982    pub(crate) fn from_ffi(value: ffi::WGPURequestAdapterWebXROptions) -> Self {
5983        Self {
5984            xr_compatible: Some(value.xrCompatible != 0),
5985        }
5986    }
5987}
5988pub struct RequestAdapterOptions {
5989    pub(crate) extensions: Vec<RequestAdapterOptionsExtension>,
5990    pub feature_level: Option<FeatureLevel>,
5991    pub power_preference: Option<PowerPreference>,
5992    pub force_fallback_adapter: Option<bool>,
5993    pub backend_type: Option<BackendType>,
5994    pub compatible_surface: Option<Surface>,
5995}
5996impl Default for RequestAdapterOptions {
5997    fn default() -> Self {
5998        Self {
5999            extensions: Vec::new(),
6000            feature_level: Some(FeatureLevel::Core),
6001            power_preference: None,
6002            force_fallback_adapter: None,
6003            backend_type: None,
6004            compatible_surface: None,
6005        }
6006    }
6007}
6008impl RequestAdapterOptions {
6009    pub fn new() -> Self {
6010        Self::default()
6011    }
6012    pub(crate) fn to_ffi(
6013        &self,
6014    ) -> (ffi::WGPURequestAdapterOptions, ChainedStructStorage) {
6015        let mut storage = ChainedStructStorage::new();
6016        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6017        for ext in self.extensions.iter().rev() {
6018            next = ext.push_chain(&mut storage, next);
6019        }
6020        let mut raw: ffi::WGPURequestAdapterOptions = unsafe { std::mem::zeroed() };
6021        raw.nextInChain = next;
6022        if let Some(value) = self.feature_level {
6023            raw.featureLevel = value.into();
6024        } else {
6025            raw.featureLevel = 0 as ffi::WGPUFeatureLevel;
6026        }
6027        if let Some(value) = self.power_preference {
6028            raw.powerPreference = value.into();
6029        } else {
6030            raw.powerPreference = 0 as ffi::WGPUPowerPreference;
6031        }
6032        raw.forceFallbackAdapter = if self.force_fallback_adapter.unwrap_or(false) {
6033            1
6034        } else {
6035            0
6036        };
6037        if let Some(value) = self.backend_type {
6038            raw.backendType = value.into();
6039        } else {
6040            raw.backendType = 0 as ffi::WGPUBackendType;
6041        }
6042        raw.compatibleSurface = self
6043            .compatible_surface
6044            .as_ref()
6045            .map(|v| v.as_raw())
6046            .unwrap_or(std::ptr::null_mut());
6047        (raw, storage)
6048    }
6049    pub fn with_extension(mut self, extension: RequestAdapterOptionsExtension) -> Self {
6050        self.extensions.push(extension);
6051        self
6052    }
6053    pub(crate) fn from_ffi(value: ffi::WGPURequestAdapterOptions) -> Self {
6054        Self {
6055            extensions: Vec::new(),
6056            feature_level: Some(value.featureLevel.into()),
6057            power_preference: Some(value.powerPreference.into()),
6058            force_fallback_adapter: Some(value.forceFallbackAdapter != 0),
6059            backend_type: Some(value.backendType.into()),
6060            compatible_surface: if value.compatibleSurface.is_null() {
6061                None
6062            } else {
6063                Some(unsafe { Surface::from_raw(value.compatibleSurface) })
6064            },
6065        }
6066    }
6067}
6068pub struct ResourceTableDescriptor {
6069    pub(crate) extensions: Vec<ResourceTableDescriptorExtension>,
6070    pub label: Option<String>,
6071    pub size: Option<u32>,
6072}
6073impl Default for ResourceTableDescriptor {
6074    fn default() -> Self {
6075        Self {
6076            extensions: Vec::new(),
6077            label: None,
6078            size: None,
6079        }
6080    }
6081}
6082impl ResourceTableDescriptor {
6083    pub fn new() -> Self {
6084        Self::default()
6085    }
6086    pub(crate) fn to_ffi(
6087        &self,
6088    ) -> (ffi::WGPUResourceTableDescriptor, ChainedStructStorage) {
6089        let mut storage = ChainedStructStorage::new();
6090        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6091        for ext in self.extensions.iter().rev() {
6092            next = ext.push_chain(&mut storage, next);
6093        }
6094        let mut raw: ffi::WGPUResourceTableDescriptor = unsafe { std::mem::zeroed() };
6095        raw.nextInChain = next;
6096        if let Some(value) = &self.label {
6097            raw.label = ffi::WGPUStringView {
6098                data: value.as_ptr().cast(),
6099                length: value.len(),
6100            };
6101        } else {
6102            raw.label = ffi::WGPUStringView {
6103                data: std::ptr::null(),
6104                length: 0,
6105            };
6106        }
6107        if let Some(value) = self.size {
6108            raw.size = value;
6109        }
6110        (raw, storage)
6111    }
6112    pub fn with_extension(
6113        mut self,
6114        extension: ResourceTableDescriptorExtension,
6115    ) -> Self {
6116        self.extensions.push(extension);
6117        self
6118    }
6119    pub(crate) fn from_ffi(value: ffi::WGPUResourceTableDescriptor) -> Self {
6120        Self {
6121            extensions: Vec::new(),
6122            label: if value.label.data.is_null() || value.label.length == 0 {
6123                None
6124            } else {
6125                Some(string_view_to_string(value.label))
6126            },
6127            size: Some(value.size),
6128        }
6129    }
6130}
6131pub struct ResourceTableLimits {
6132    pub max_resource_table_size: Option<u32>,
6133}
6134impl Default for ResourceTableLimits {
6135    fn default() -> Self {
6136        Self {
6137            max_resource_table_size: Some(LIMIT_U32_UNDEFINED),
6138        }
6139    }
6140}
6141impl ResourceTableLimits {
6142    pub fn new() -> Self {
6143        Self::default()
6144    }
6145    pub(crate) fn to_ffi(&self) -> (ffi::WGPUResourceTableLimits, ChainedStructStorage) {
6146        let mut storage = ChainedStructStorage::new();
6147        let mut raw: ffi::WGPUResourceTableLimits = unsafe { std::mem::zeroed() };
6148        if let Some(value) = self.max_resource_table_size {
6149            raw.maxResourceTableSize = value;
6150        }
6151        (raw, storage)
6152    }
6153    pub(crate) fn from_ffi(value: ffi::WGPUResourceTableLimits) -> Self {
6154        Self {
6155            max_resource_table_size: Some(value.maxResourceTableSize),
6156        }
6157    }
6158}
6159pub struct SamplerBindingLayout {
6160    pub(crate) extensions: Vec<SamplerBindingLayoutExtension>,
6161    pub r#type: Option<SamplerBindingType>,
6162}
6163impl Default for SamplerBindingLayout {
6164    fn default() -> Self {
6165        Self {
6166            extensions: Vec::new(),
6167            r#type: Some(SamplerBindingType::Filtering),
6168        }
6169    }
6170}
6171impl SamplerBindingLayout {
6172    pub fn new() -> Self {
6173        Self::default()
6174    }
6175    pub(crate) fn to_ffi(
6176        &self,
6177    ) -> (ffi::WGPUSamplerBindingLayout, ChainedStructStorage) {
6178        let mut storage = ChainedStructStorage::new();
6179        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6180        for ext in self.extensions.iter().rev() {
6181            next = ext.push_chain(&mut storage, next);
6182        }
6183        let mut raw: ffi::WGPUSamplerBindingLayout = unsafe { std::mem::zeroed() };
6184        raw.nextInChain = next;
6185        if let Some(value) = self.r#type {
6186            raw.type_ = value.into();
6187        } else {
6188            raw.type_ = 0 as ffi::WGPUSamplerBindingType;
6189        }
6190        (raw, storage)
6191    }
6192    pub fn with_extension(mut self, extension: SamplerBindingLayoutExtension) -> Self {
6193        self.extensions.push(extension);
6194        self
6195    }
6196    pub(crate) fn from_ffi(value: ffi::WGPUSamplerBindingLayout) -> Self {
6197        Self {
6198            extensions: Vec::new(),
6199            r#type: Some(value.type_.into()),
6200        }
6201    }
6202}
6203pub struct SamplerDescriptor {
6204    pub(crate) extensions: Vec<SamplerDescriptorExtension>,
6205    pub label: Option<String>,
6206    pub address_mode_u: Option<AddressMode>,
6207    pub address_mode_v: Option<AddressMode>,
6208    pub address_mode_w: Option<AddressMode>,
6209    pub mag_filter: Option<FilterMode>,
6210    pub min_filter: Option<FilterMode>,
6211    pub mipmap_filter: Option<MipmapFilterMode>,
6212    pub lod_min_clamp: Option<f32>,
6213    pub lod_max_clamp: Option<f32>,
6214    pub compare: Option<CompareFunction>,
6215    pub max_anisotropy: Option<u16>,
6216}
6217impl Default for SamplerDescriptor {
6218    fn default() -> Self {
6219        Self {
6220            extensions: Vec::new(),
6221            label: None,
6222            address_mode_u: Some(AddressMode::ClampToEdge),
6223            address_mode_v: Some(AddressMode::ClampToEdge),
6224            address_mode_w: Some(AddressMode::ClampToEdge),
6225            mag_filter: Some(FilterMode::Nearest),
6226            min_filter: Some(FilterMode::Nearest),
6227            mipmap_filter: Some(MipmapFilterMode::Nearest),
6228            lod_min_clamp: None,
6229            lod_max_clamp: None,
6230            compare: None,
6231            max_anisotropy: Some(1),
6232        }
6233    }
6234}
6235impl SamplerDescriptor {
6236    pub fn new() -> Self {
6237        Self::default()
6238    }
6239    pub(crate) fn to_ffi(&self) -> (ffi::WGPUSamplerDescriptor, ChainedStructStorage) {
6240        let mut storage = ChainedStructStorage::new();
6241        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6242        for ext in self.extensions.iter().rev() {
6243            next = ext.push_chain(&mut storage, next);
6244        }
6245        let mut raw: ffi::WGPUSamplerDescriptor = unsafe { std::mem::zeroed() };
6246        raw.nextInChain = next;
6247        if let Some(value) = &self.label {
6248            raw.label = ffi::WGPUStringView {
6249                data: value.as_ptr().cast(),
6250                length: value.len(),
6251            };
6252        } else {
6253            raw.label = ffi::WGPUStringView {
6254                data: std::ptr::null(),
6255                length: 0,
6256            };
6257        }
6258        if let Some(value) = self.address_mode_u {
6259            raw.addressModeU = value.into();
6260        } else {
6261            raw.addressModeU = 0 as ffi::WGPUAddressMode;
6262        }
6263        if let Some(value) = self.address_mode_v {
6264            raw.addressModeV = value.into();
6265        } else {
6266            raw.addressModeV = 0 as ffi::WGPUAddressMode;
6267        }
6268        if let Some(value) = self.address_mode_w {
6269            raw.addressModeW = value.into();
6270        } else {
6271            raw.addressModeW = 0 as ffi::WGPUAddressMode;
6272        }
6273        if let Some(value) = self.mag_filter {
6274            raw.magFilter = value.into();
6275        } else {
6276            raw.magFilter = 0 as ffi::WGPUFilterMode;
6277        }
6278        if let Some(value) = self.min_filter {
6279            raw.minFilter = value.into();
6280        } else {
6281            raw.minFilter = 0 as ffi::WGPUFilterMode;
6282        }
6283        if let Some(value) = self.mipmap_filter {
6284            raw.mipmapFilter = value.into();
6285        } else {
6286            raw.mipmapFilter = 0 as ffi::WGPUMipmapFilterMode;
6287        }
6288        if let Some(value) = self.lod_min_clamp {
6289            raw.lodMinClamp = value;
6290        }
6291        if let Some(value) = self.lod_max_clamp {
6292            raw.lodMaxClamp = value;
6293        }
6294        if let Some(value) = self.compare {
6295            raw.compare = value.into();
6296        } else {
6297            raw.compare = 0 as ffi::WGPUCompareFunction;
6298        }
6299        if let Some(value) = self.max_anisotropy {
6300            raw.maxAnisotropy = value;
6301        }
6302        (raw, storage)
6303    }
6304    pub fn with_extension(mut self, extension: SamplerDescriptorExtension) -> Self {
6305        self.extensions.push(extension);
6306        self
6307    }
6308    pub(crate) fn from_ffi(value: ffi::WGPUSamplerDescriptor) -> Self {
6309        Self {
6310            extensions: Vec::new(),
6311            label: if value.label.data.is_null() || value.label.length == 0 {
6312                None
6313            } else {
6314                Some(string_view_to_string(value.label))
6315            },
6316            address_mode_u: Some(value.addressModeU.into()),
6317            address_mode_v: Some(value.addressModeV.into()),
6318            address_mode_w: Some(value.addressModeW.into()),
6319            mag_filter: Some(value.magFilter.into()),
6320            min_filter: Some(value.minFilter.into()),
6321            mipmap_filter: Some(value.mipmapFilter.into()),
6322            lod_min_clamp: Some(value.lodMinClamp),
6323            lod_max_clamp: Some(value.lodMaxClamp),
6324            compare: Some(value.compare.into()),
6325            max_anisotropy: Some(value.maxAnisotropy),
6326        }
6327    }
6328}
6329pub struct ShaderModuleCompilationOptions {
6330    pub strict_math: Option<bool>,
6331}
6332impl Default for ShaderModuleCompilationOptions {
6333    fn default() -> Self {
6334        Self { strict_math: None }
6335    }
6336}
6337impl ShaderModuleCompilationOptions {
6338    pub fn new() -> Self {
6339        Self::default()
6340    }
6341    pub(crate) fn to_ffi(
6342        &self,
6343    ) -> (ffi::WGPUShaderModuleCompilationOptions, ChainedStructStorage) {
6344        let mut storage = ChainedStructStorage::new();
6345        let mut raw: ffi::WGPUShaderModuleCompilationOptions = unsafe {
6346            std::mem::zeroed()
6347        };
6348        raw.strictMath = if self.strict_math.unwrap_or(false) { 1 } else { 0 };
6349        (raw, storage)
6350    }
6351    pub(crate) fn from_ffi(value: ffi::WGPUShaderModuleCompilationOptions) -> Self {
6352        Self {
6353            strict_math: Some(value.strictMath != 0),
6354        }
6355    }
6356}
6357pub struct ShaderModuleDescriptor {
6358    pub(crate) extensions: Vec<ShaderModuleDescriptorExtension>,
6359    pub label: Option<String>,
6360}
6361impl Default for ShaderModuleDescriptor {
6362    fn default() -> Self {
6363        Self {
6364            extensions: Vec::new(),
6365            label: None,
6366        }
6367    }
6368}
6369impl ShaderModuleDescriptor {
6370    pub fn new() -> Self {
6371        Self::default()
6372    }
6373    pub(crate) fn to_ffi(
6374        &self,
6375    ) -> (ffi::WGPUShaderModuleDescriptor, ChainedStructStorage) {
6376        let mut storage = ChainedStructStorage::new();
6377        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6378        for ext in self.extensions.iter().rev() {
6379            next = ext.push_chain(&mut storage, next);
6380        }
6381        let mut raw: ffi::WGPUShaderModuleDescriptor = unsafe { std::mem::zeroed() };
6382        raw.nextInChain = next;
6383        if let Some(value) = &self.label {
6384            raw.label = ffi::WGPUStringView {
6385                data: value.as_ptr().cast(),
6386                length: value.len(),
6387            };
6388        } else {
6389            raw.label = ffi::WGPUStringView {
6390                data: std::ptr::null(),
6391                length: 0,
6392            };
6393        }
6394        (raw, storage)
6395    }
6396    pub fn with_extension(mut self, extension: ShaderModuleDescriptorExtension) -> Self {
6397        self.extensions.push(extension);
6398        self
6399    }
6400    pub(crate) fn from_ffi(value: ffi::WGPUShaderModuleDescriptor) -> Self {
6401        Self {
6402            extensions: Vec::new(),
6403            label: if value.label.data.is_null() || value.label.length == 0 {
6404                None
6405            } else {
6406                Some(string_view_to_string(value.label))
6407            },
6408        }
6409    }
6410}
6411pub struct ShaderSourceSPIRV {
6412    pub code: Option<Vec<u32>>,
6413}
6414impl Default for ShaderSourceSPIRV {
6415    fn default() -> Self {
6416        Self { code: None }
6417    }
6418}
6419impl ShaderSourceSPIRV {
6420    pub fn new() -> Self {
6421        Self::default()
6422    }
6423    pub(crate) fn to_ffi(&self) -> (ffi::WGPUShaderSourceSPIRV, ChainedStructStorage) {
6424        let mut storage = ChainedStructStorage::new();
6425        let mut raw: ffi::WGPUShaderSourceSPIRV = unsafe { std::mem::zeroed() };
6426        raw.codeSize = (self.code.as_ref().map(|v| v.len()).unwrap_or(0)) as u32;
6427        if let Some(values) = &self.code {
6428            let len_value = values.len();
6429            let raw_vec = values.to_vec();
6430            let ptr = storage.push_vec(raw_vec);
6431            raw.code = ptr;
6432            raw.codeSize = len_value as u32;
6433        } else {
6434            raw.code = std::ptr::null();
6435            raw.codeSize = 0;
6436        }
6437        (raw, storage)
6438    }
6439    pub(crate) fn from_ffi(value: ffi::WGPUShaderSourceSPIRV) -> Self {
6440        Self {
6441            code: if value.code.is_null() {
6442                None
6443            } else {
6444                Some(
6445                    unsafe {
6446                        std::slice::from_raw_parts(value.code, value.codeSize as usize)
6447                    }
6448                        .to_vec(),
6449                )
6450            },
6451        }
6452    }
6453}
6454pub struct ShaderSourceWGSL {
6455    pub code: Option<String>,
6456}
6457impl Default for ShaderSourceWGSL {
6458    fn default() -> Self {
6459        Self { code: None }
6460    }
6461}
6462impl ShaderSourceWGSL {
6463    pub fn new() -> Self {
6464        Self::default()
6465    }
6466    pub(crate) fn to_ffi(&self) -> (ffi::WGPUShaderSourceWGSL, ChainedStructStorage) {
6467        let mut storage = ChainedStructStorage::new();
6468        let mut raw: ffi::WGPUShaderSourceWGSL = unsafe { std::mem::zeroed() };
6469        if let Some(value) = &self.code {
6470            raw.code = ffi::WGPUStringView {
6471                data: value.as_ptr().cast(),
6472                length: value.len(),
6473            };
6474        } else {
6475            raw.code = ffi::WGPUStringView {
6476                data: std::ptr::null(),
6477                length: 0,
6478            };
6479        }
6480        (raw, storage)
6481    }
6482    pub(crate) fn from_ffi(value: ffi::WGPUShaderSourceWGSL) -> Self {
6483        Self {
6484            code: Some(string_view_to_string(value.code)),
6485        }
6486    }
6487}
6488pub struct SharedBufferMemoryBeginAccessDescriptor {
6489    pub(crate) extensions: Vec<SharedBufferMemoryBeginAccessDescriptorExtension>,
6490    pub initialized: Option<bool>,
6491    pub fences: Option<Vec<SharedFence>>,
6492    pub signaled_values: Option<Vec<u64>>,
6493}
6494impl Default for SharedBufferMemoryBeginAccessDescriptor {
6495    fn default() -> Self {
6496        Self {
6497            extensions: Vec::new(),
6498            initialized: None,
6499            fences: None,
6500            signaled_values: None,
6501        }
6502    }
6503}
6504impl SharedBufferMemoryBeginAccessDescriptor {
6505    pub fn new() -> Self {
6506        Self::default()
6507    }
6508    pub(crate) fn to_ffi(
6509        &self,
6510    ) -> (ffi::WGPUSharedBufferMemoryBeginAccessDescriptor, ChainedStructStorage) {
6511        let mut storage = ChainedStructStorage::new();
6512        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6513        for ext in self.extensions.iter().rev() {
6514            next = ext.push_chain(&mut storage, next);
6515        }
6516        let mut raw: ffi::WGPUSharedBufferMemoryBeginAccessDescriptor = unsafe {
6517            std::mem::zeroed()
6518        };
6519        raw.nextInChain = next;
6520        raw.initialized = if self.initialized.unwrap_or(false) { 1 } else { 0 };
6521        raw.fenceCount = self.signaled_values.as_ref().map(|v| v.len()).unwrap_or(0);
6522        if let Some(values) = &self.fences {
6523            let len_value = values.len();
6524            let raw_vec: Vec<ffi::WGPUSharedFence> = values
6525                .iter()
6526                .map(|v| v.as_raw())
6527                .collect();
6528            let ptr = storage.push_vec(raw_vec);
6529            raw.fences = ptr;
6530            raw.fenceCount = len_value;
6531        } else {
6532            raw.fences = std::ptr::null();
6533            raw.fenceCount = 0;
6534        }
6535        if let Some(values) = &self.signaled_values {
6536            let len_value = values.len();
6537            let raw_vec = values.to_vec();
6538            let ptr = storage.push_vec(raw_vec);
6539            raw.signaledValues = ptr;
6540            raw.fenceCount = len_value;
6541        } else {
6542            raw.signaledValues = std::ptr::null();
6543            raw.fenceCount = 0;
6544        }
6545        (raw, storage)
6546    }
6547    pub fn with_extension(
6548        mut self,
6549        extension: SharedBufferMemoryBeginAccessDescriptorExtension,
6550    ) -> Self {
6551        self.extensions.push(extension);
6552        self
6553    }
6554    pub(crate) fn from_ffi(
6555        value: ffi::WGPUSharedBufferMemoryBeginAccessDescriptor,
6556    ) -> Self {
6557        Self {
6558            extensions: Vec::new(),
6559            initialized: Some(value.initialized != 0),
6560            fences: if value.fences.is_null() {
6561                None
6562            } else {
6563                Some(
6564                    unsafe {
6565                        std::slice::from_raw_parts(
6566                            value.fences,
6567                            value.fenceCount as usize,
6568                        )
6569                    }
6570                        .iter()
6571                        .map(|raw| unsafe { SharedFence::from_raw(*raw) })
6572                        .collect(),
6573                )
6574            },
6575            signaled_values: if value.signaledValues.is_null() {
6576                None
6577            } else {
6578                Some(
6579                    unsafe {
6580                        std::slice::from_raw_parts(
6581                            value.signaledValues,
6582                            value.fenceCount as usize,
6583                        )
6584                    }
6585                        .to_vec(),
6586                )
6587            },
6588        }
6589    }
6590}
6591pub struct SharedBufferMemoryDescriptor {
6592    pub(crate) extensions: Vec<SharedBufferMemoryDescriptorExtension>,
6593    pub label: Option<String>,
6594}
6595impl Default for SharedBufferMemoryDescriptor {
6596    fn default() -> Self {
6597        Self {
6598            extensions: Vec::new(),
6599            label: None,
6600        }
6601    }
6602}
6603impl SharedBufferMemoryDescriptor {
6604    pub fn new() -> Self {
6605        Self::default()
6606    }
6607    pub(crate) fn to_ffi(
6608        &self,
6609    ) -> (ffi::WGPUSharedBufferMemoryDescriptor, ChainedStructStorage) {
6610        let mut storage = ChainedStructStorage::new();
6611        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6612        for ext in self.extensions.iter().rev() {
6613            next = ext.push_chain(&mut storage, next);
6614        }
6615        let mut raw: ffi::WGPUSharedBufferMemoryDescriptor = unsafe {
6616            std::mem::zeroed()
6617        };
6618        raw.nextInChain = next;
6619        if let Some(value) = &self.label {
6620            raw.label = ffi::WGPUStringView {
6621                data: value.as_ptr().cast(),
6622                length: value.len(),
6623            };
6624        } else {
6625            raw.label = ffi::WGPUStringView {
6626                data: std::ptr::null(),
6627                length: 0,
6628            };
6629        }
6630        (raw, storage)
6631    }
6632    pub fn with_extension(
6633        mut self,
6634        extension: SharedBufferMemoryDescriptorExtension,
6635    ) -> Self {
6636        self.extensions.push(extension);
6637        self
6638    }
6639    pub(crate) fn from_ffi(value: ffi::WGPUSharedBufferMemoryDescriptor) -> Self {
6640        Self {
6641            extensions: Vec::new(),
6642            label: if value.label.data.is_null() || value.label.length == 0 {
6643                None
6644            } else {
6645                Some(string_view_to_string(value.label))
6646            },
6647        }
6648    }
6649}
6650pub struct SharedBufferMemoryEndAccessState {
6651    pub(crate) extensions: Vec<SharedBufferMemoryEndAccessStateExtension>,
6652    pub initialized: Option<bool>,
6653    pub fences: Option<Vec<SharedFence>>,
6654    pub signaled_values: Option<Vec<u64>>,
6655    #[doc(hidden)]
6656    pub(crate) _free_members: Option<ffi::WGPUSharedBufferMemoryEndAccessState>,
6657}
6658impl Default for SharedBufferMemoryEndAccessState {
6659    fn default() -> Self {
6660        Self {
6661            extensions: Vec::new(),
6662            initialized: None,
6663            fences: None,
6664            signaled_values: None,
6665            _free_members: None,
6666        }
6667    }
6668}
6669impl SharedBufferMemoryEndAccessState {
6670    pub fn new() -> Self {
6671        Self::default()
6672    }
6673    pub(crate) fn to_ffi(
6674        &self,
6675    ) -> (ffi::WGPUSharedBufferMemoryEndAccessState, ChainedStructStorage) {
6676        let mut storage = ChainedStructStorage::new();
6677        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6678        for ext in self.extensions.iter().rev() {
6679            next = ext.push_chain(&mut storage, next);
6680        }
6681        let mut raw: ffi::WGPUSharedBufferMemoryEndAccessState = unsafe {
6682            std::mem::zeroed()
6683        };
6684        raw.nextInChain = next;
6685        raw.initialized = if self.initialized.unwrap_or(false) { 1 } else { 0 };
6686        raw.fenceCount = self.signaled_values.as_ref().map(|v| v.len()).unwrap_or(0);
6687        if let Some(values) = &self.fences {
6688            let len_value = values.len();
6689            let raw_vec: Vec<ffi::WGPUSharedFence> = values
6690                .iter()
6691                .map(|v| v.as_raw())
6692                .collect();
6693            let ptr = storage.push_vec(raw_vec);
6694            raw.fences = ptr;
6695            raw.fenceCount = len_value;
6696        } else {
6697            raw.fences = std::ptr::null();
6698            raw.fenceCount = 0;
6699        }
6700        if let Some(values) = &self.signaled_values {
6701            let len_value = values.len();
6702            let raw_vec = values.to_vec();
6703            let ptr = storage.push_vec(raw_vec);
6704            raw.signaledValues = ptr;
6705            raw.fenceCount = len_value;
6706        } else {
6707            raw.signaledValues = std::ptr::null();
6708            raw.fenceCount = 0;
6709        }
6710        (raw, storage)
6711    }
6712    pub fn with_extension(
6713        mut self,
6714        extension: SharedBufferMemoryEndAccessStateExtension,
6715    ) -> Self {
6716        self.extensions.push(extension);
6717        self
6718    }
6719    pub(crate) fn from_ffi(value: ffi::WGPUSharedBufferMemoryEndAccessState) -> Self {
6720        Self {
6721            extensions: Vec::new(),
6722            initialized: Some(value.initialized != 0),
6723            fences: if value.fences.is_null() {
6724                None
6725            } else {
6726                Some(
6727                    unsafe {
6728                        std::slice::from_raw_parts(
6729                            value.fences,
6730                            value.fenceCount as usize,
6731                        )
6732                    }
6733                        .iter()
6734                        .map(|raw| unsafe { SharedFence::from_raw(*raw) })
6735                        .collect(),
6736                )
6737            },
6738            signaled_values: if value.signaledValues.is_null() {
6739                None
6740            } else {
6741                Some(
6742                    unsafe {
6743                        std::slice::from_raw_parts(
6744                            value.signaledValues,
6745                            value.fenceCount as usize,
6746                        )
6747                    }
6748                        .to_vec(),
6749                )
6750            },
6751            _free_members: Some(value),
6752        }
6753    }
6754    pub(crate) fn free_members(value: ffi::WGPUSharedBufferMemoryEndAccessState) {
6755        unsafe { ffi::wgpuSharedBufferMemoryEndAccessStateFreeMembers(value) };
6756    }
6757}
6758impl Drop for SharedBufferMemoryEndAccessState {
6759    fn drop(&mut self) {
6760        if let Some(value) = self._free_members.take() {
6761            unsafe { ffi::wgpuSharedBufferMemoryEndAccessStateFreeMembers(value) };
6762        }
6763    }
6764}
6765pub struct SharedBufferMemoryProperties {
6766    pub(crate) extensions: Vec<SharedBufferMemoryPropertiesExtension>,
6767    pub usage: Option<BufferUsage>,
6768    pub size: Option<u64>,
6769}
6770impl Default for SharedBufferMemoryProperties {
6771    fn default() -> Self {
6772        Self {
6773            extensions: Vec::new(),
6774            usage: None,
6775            size: None,
6776        }
6777    }
6778}
6779impl SharedBufferMemoryProperties {
6780    pub fn new() -> Self {
6781        Self::default()
6782    }
6783    pub(crate) fn to_ffi(
6784        &self,
6785    ) -> (ffi::WGPUSharedBufferMemoryProperties, ChainedStructStorage) {
6786        let mut storage = ChainedStructStorage::new();
6787        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
6788        for ext in self.extensions.iter().rev() {
6789            next = ext.push_chain(&mut storage, next);
6790        }
6791        let mut raw: ffi::WGPUSharedBufferMemoryProperties = unsafe {
6792            std::mem::zeroed()
6793        };
6794        raw.nextInChain = next;
6795        if let Some(value) = self.usage {
6796            raw.usage = value.into();
6797        } else {
6798            raw.usage = 0 as ffi::WGPUBufferUsage;
6799        }
6800        if let Some(value) = self.size {
6801            raw.size = value;
6802        }
6803        (raw, storage)
6804    }
6805    pub fn with_extension(
6806        mut self,
6807        extension: SharedBufferMemoryPropertiesExtension,
6808    ) -> Self {
6809        self.extensions.push(extension);
6810        self
6811    }
6812    pub(crate) fn from_ffi(value: ffi::WGPUSharedBufferMemoryProperties) -> Self {
6813        Self {
6814            extensions: Vec::new(),
6815            usage: Some(value.usage.into()),
6816            size: Some(value.size),
6817        }
6818    }
6819}
6820pub struct SharedFenceDXGISharedHandleDescriptor {
6821    pub handle: Option<*mut std::ffi::c_void>,
6822}
6823impl Default for SharedFenceDXGISharedHandleDescriptor {
6824    fn default() -> Self {
6825        Self { handle: None }
6826    }
6827}
6828impl SharedFenceDXGISharedHandleDescriptor {
6829    pub fn new() -> Self {
6830        Self::default()
6831    }
6832    pub(crate) fn to_ffi(
6833        &self,
6834    ) -> (ffi::WGPUSharedFenceDXGISharedHandleDescriptor, ChainedStructStorage) {
6835        let mut storage = ChainedStructStorage::new();
6836        let mut raw: ffi::WGPUSharedFenceDXGISharedHandleDescriptor = unsafe {
6837            std::mem::zeroed()
6838        };
6839        if let Some(value) = self.handle {
6840            raw.handle = value;
6841        }
6842        (raw, storage)
6843    }
6844    pub(crate) fn from_ffi(
6845        value: ffi::WGPUSharedFenceDXGISharedHandleDescriptor,
6846    ) -> Self {
6847        Self { handle: Some(value.handle) }
6848    }
6849}
6850pub struct SharedFenceDXGISharedHandleExportInfo {
6851    pub handle: Option<*mut std::ffi::c_void>,
6852}
6853impl Default for SharedFenceDXGISharedHandleExportInfo {
6854    fn default() -> Self {
6855        Self { handle: None }
6856    }
6857}
6858impl SharedFenceDXGISharedHandleExportInfo {
6859    pub fn new() -> Self {
6860        Self::default()
6861    }
6862    pub(crate) fn to_ffi(
6863        &self,
6864    ) -> (ffi::WGPUSharedFenceDXGISharedHandleExportInfo, ChainedStructStorage) {
6865        let mut storage = ChainedStructStorage::new();
6866        let mut raw: ffi::WGPUSharedFenceDXGISharedHandleExportInfo = unsafe {
6867            std::mem::zeroed()
6868        };
6869        if let Some(value) = self.handle {
6870            raw.handle = value;
6871        }
6872        (raw, storage)
6873    }
6874    pub(crate) fn from_ffi(
6875        value: ffi::WGPUSharedFenceDXGISharedHandleExportInfo,
6876    ) -> Self {
6877        Self { handle: Some(value.handle) }
6878    }
6879}
6880pub struct SharedFenceEGLSyncDescriptor {
6881    pub sync: Option<*mut std::ffi::c_void>,
6882}
6883impl Default for SharedFenceEGLSyncDescriptor {
6884    fn default() -> Self {
6885        Self { sync: None }
6886    }
6887}
6888impl SharedFenceEGLSyncDescriptor {
6889    pub fn new() -> Self {
6890        Self::default()
6891    }
6892    pub(crate) fn to_ffi(
6893        &self,
6894    ) -> (ffi::WGPUSharedFenceEGLSyncDescriptor, ChainedStructStorage) {
6895        let mut storage = ChainedStructStorage::new();
6896        let mut raw: ffi::WGPUSharedFenceEGLSyncDescriptor = unsafe {
6897            std::mem::zeroed()
6898        };
6899        if let Some(value) = self.sync {
6900            raw.sync = value;
6901        }
6902        (raw, storage)
6903    }
6904    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceEGLSyncDescriptor) -> Self {
6905        Self { sync: Some(value.sync) }
6906    }
6907}
6908pub struct SharedFenceEGLSyncExportInfo {
6909    pub sync: Option<*mut std::ffi::c_void>,
6910}
6911impl Default for SharedFenceEGLSyncExportInfo {
6912    fn default() -> Self {
6913        Self { sync: None }
6914    }
6915}
6916impl SharedFenceEGLSyncExportInfo {
6917    pub fn new() -> Self {
6918        Self::default()
6919    }
6920    pub(crate) fn to_ffi(
6921        &self,
6922    ) -> (ffi::WGPUSharedFenceEGLSyncExportInfo, ChainedStructStorage) {
6923        let mut storage = ChainedStructStorage::new();
6924        let mut raw: ffi::WGPUSharedFenceEGLSyncExportInfo = unsafe {
6925            std::mem::zeroed()
6926        };
6927        if let Some(value) = self.sync {
6928            raw.sync = value;
6929        }
6930        (raw, storage)
6931    }
6932    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceEGLSyncExportInfo) -> Self {
6933        Self { sync: Some(value.sync) }
6934    }
6935}
6936pub struct SharedFenceMTLSharedEventDescriptor {
6937    pub shared_event: Option<*mut std::ffi::c_void>,
6938}
6939impl Default for SharedFenceMTLSharedEventDescriptor {
6940    fn default() -> Self {
6941        Self { shared_event: None }
6942    }
6943}
6944impl SharedFenceMTLSharedEventDescriptor {
6945    pub fn new() -> Self {
6946        Self::default()
6947    }
6948    pub(crate) fn to_ffi(
6949        &self,
6950    ) -> (ffi::WGPUSharedFenceMTLSharedEventDescriptor, ChainedStructStorage) {
6951        let mut storage = ChainedStructStorage::new();
6952        let mut raw: ffi::WGPUSharedFenceMTLSharedEventDescriptor = unsafe {
6953            std::mem::zeroed()
6954        };
6955        if let Some(value) = self.shared_event {
6956            raw.sharedEvent = value;
6957        }
6958        (raw, storage)
6959    }
6960    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceMTLSharedEventDescriptor) -> Self {
6961        Self {
6962            shared_event: Some(value.sharedEvent),
6963        }
6964    }
6965}
6966pub struct SharedFenceMTLSharedEventExportInfo {
6967    pub shared_event: Option<*mut std::ffi::c_void>,
6968}
6969impl Default for SharedFenceMTLSharedEventExportInfo {
6970    fn default() -> Self {
6971        Self { shared_event: None }
6972    }
6973}
6974impl SharedFenceMTLSharedEventExportInfo {
6975    pub fn new() -> Self {
6976        Self::default()
6977    }
6978    pub(crate) fn to_ffi(
6979        &self,
6980    ) -> (ffi::WGPUSharedFenceMTLSharedEventExportInfo, ChainedStructStorage) {
6981        let mut storage = ChainedStructStorage::new();
6982        let mut raw: ffi::WGPUSharedFenceMTLSharedEventExportInfo = unsafe {
6983            std::mem::zeroed()
6984        };
6985        if let Some(value) = self.shared_event {
6986            raw.sharedEvent = value;
6987        }
6988        (raw, storage)
6989    }
6990    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceMTLSharedEventExportInfo) -> Self {
6991        Self {
6992            shared_event: Some(value.sharedEvent),
6993        }
6994    }
6995}
6996pub struct SharedFenceDescriptor {
6997    pub(crate) extensions: Vec<SharedFenceDescriptorExtension>,
6998    pub label: Option<String>,
6999}
7000impl Default for SharedFenceDescriptor {
7001    fn default() -> Self {
7002        Self {
7003            extensions: Vec::new(),
7004            label: None,
7005        }
7006    }
7007}
7008impl SharedFenceDescriptor {
7009    pub fn new() -> Self {
7010        Self::default()
7011    }
7012    pub(crate) fn to_ffi(
7013        &self,
7014    ) -> (ffi::WGPUSharedFenceDescriptor, ChainedStructStorage) {
7015        let mut storage = ChainedStructStorage::new();
7016        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
7017        for ext in self.extensions.iter().rev() {
7018            next = ext.push_chain(&mut storage, next);
7019        }
7020        let mut raw: ffi::WGPUSharedFenceDescriptor = unsafe { std::mem::zeroed() };
7021        raw.nextInChain = next;
7022        if let Some(value) = &self.label {
7023            raw.label = ffi::WGPUStringView {
7024                data: value.as_ptr().cast(),
7025                length: value.len(),
7026            };
7027        } else {
7028            raw.label = ffi::WGPUStringView {
7029                data: std::ptr::null(),
7030                length: 0,
7031            };
7032        }
7033        (raw, storage)
7034    }
7035    pub fn with_extension(mut self, extension: SharedFenceDescriptorExtension) -> Self {
7036        self.extensions.push(extension);
7037        self
7038    }
7039    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceDescriptor) -> Self {
7040        Self {
7041            extensions: Vec::new(),
7042            label: if value.label.data.is_null() || value.label.length == 0 {
7043                None
7044            } else {
7045                Some(string_view_to_string(value.label))
7046            },
7047        }
7048    }
7049}
7050pub struct SharedFenceExportInfo {
7051    pub(crate) extensions: Vec<SharedFenceExportInfoExtension>,
7052    pub r#type: Option<SharedFenceType>,
7053}
7054impl Default for SharedFenceExportInfo {
7055    fn default() -> Self {
7056        Self {
7057            extensions: Vec::new(),
7058            r#type: None,
7059        }
7060    }
7061}
7062impl SharedFenceExportInfo {
7063    pub fn new() -> Self {
7064        Self::default()
7065    }
7066    pub(crate) fn to_ffi(
7067        &self,
7068    ) -> (ffi::WGPUSharedFenceExportInfo, ChainedStructStorage) {
7069        let mut storage = ChainedStructStorage::new();
7070        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
7071        for ext in self.extensions.iter().rev() {
7072            next = ext.push_chain(&mut storage, next);
7073        }
7074        let mut raw: ffi::WGPUSharedFenceExportInfo = unsafe { std::mem::zeroed() };
7075        raw.nextInChain = next;
7076        if let Some(value) = self.r#type {
7077            raw.type_ = value.into();
7078        } else {
7079            raw.type_ = 0 as ffi::WGPUSharedFenceType;
7080        }
7081        (raw, storage)
7082    }
7083    pub fn with_extension(mut self, extension: SharedFenceExportInfoExtension) -> Self {
7084        self.extensions.push(extension);
7085        self
7086    }
7087    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceExportInfo) -> Self {
7088        Self {
7089            extensions: Vec::new(),
7090            r#type: Some(value.type_.into()),
7091        }
7092    }
7093}
7094pub struct SharedFenceSyncFDDescriptor {
7095    pub handle: Option<i32>,
7096}
7097impl Default for SharedFenceSyncFDDescriptor {
7098    fn default() -> Self {
7099        Self { handle: None }
7100    }
7101}
7102impl SharedFenceSyncFDDescriptor {
7103    pub fn new() -> Self {
7104        Self::default()
7105    }
7106    pub(crate) fn to_ffi(
7107        &self,
7108    ) -> (ffi::WGPUSharedFenceSyncFDDescriptor, ChainedStructStorage) {
7109        let mut storage = ChainedStructStorage::new();
7110        let mut raw: ffi::WGPUSharedFenceSyncFDDescriptor = unsafe {
7111            std::mem::zeroed()
7112        };
7113        if let Some(value) = self.handle {
7114            raw.handle = value;
7115        }
7116        (raw, storage)
7117    }
7118    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceSyncFDDescriptor) -> Self {
7119        Self { handle: Some(value.handle) }
7120    }
7121}
7122pub struct SharedFenceSyncFDExportInfo {
7123    pub handle: Option<i32>,
7124}
7125impl Default for SharedFenceSyncFDExportInfo {
7126    fn default() -> Self {
7127        Self { handle: None }
7128    }
7129}
7130impl SharedFenceSyncFDExportInfo {
7131    pub fn new() -> Self {
7132        Self::default()
7133    }
7134    pub(crate) fn to_ffi(
7135        &self,
7136    ) -> (ffi::WGPUSharedFenceSyncFDExportInfo, ChainedStructStorage) {
7137        let mut storage = ChainedStructStorage::new();
7138        let mut raw: ffi::WGPUSharedFenceSyncFDExportInfo = unsafe {
7139            std::mem::zeroed()
7140        };
7141        if let Some(value) = self.handle {
7142            raw.handle = value;
7143        }
7144        (raw, storage)
7145    }
7146    pub(crate) fn from_ffi(value: ffi::WGPUSharedFenceSyncFDExportInfo) -> Self {
7147        Self { handle: Some(value.handle) }
7148    }
7149}
7150pub struct SharedFenceVkSemaphoreOpaqueFDDescriptor {
7151    pub handle: Option<i32>,
7152}
7153impl Default for SharedFenceVkSemaphoreOpaqueFDDescriptor {
7154    fn default() -> Self {
7155        Self { handle: None }
7156    }
7157}
7158impl SharedFenceVkSemaphoreOpaqueFDDescriptor {
7159    pub fn new() -> Self {
7160        Self::default()
7161    }
7162    pub(crate) fn to_ffi(
7163        &self,
7164    ) -> (ffi::WGPUSharedFenceVkSemaphoreOpaqueFDDescriptor, ChainedStructStorage) {
7165        let mut storage = ChainedStructStorage::new();
7166        let mut raw: ffi::WGPUSharedFenceVkSemaphoreOpaqueFDDescriptor = unsafe {
7167            std::mem::zeroed()
7168        };
7169        if let Some(value) = self.handle {
7170            raw.handle = value;
7171        }
7172        (raw, storage)
7173    }
7174    pub(crate) fn from_ffi(
7175        value: ffi::WGPUSharedFenceVkSemaphoreOpaqueFDDescriptor,
7176    ) -> Self {
7177        Self { handle: Some(value.handle) }
7178    }
7179}
7180pub struct SharedFenceVkSemaphoreOpaqueFDExportInfo {
7181    pub handle: Option<i32>,
7182}
7183impl Default for SharedFenceVkSemaphoreOpaqueFDExportInfo {
7184    fn default() -> Self {
7185        Self { handle: None }
7186    }
7187}
7188impl SharedFenceVkSemaphoreOpaqueFDExportInfo {
7189    pub fn new() -> Self {
7190        Self::default()
7191    }
7192    pub(crate) fn to_ffi(
7193        &self,
7194    ) -> (ffi::WGPUSharedFenceVkSemaphoreOpaqueFDExportInfo, ChainedStructStorage) {
7195        let mut storage = ChainedStructStorage::new();
7196        let mut raw: ffi::WGPUSharedFenceVkSemaphoreOpaqueFDExportInfo = unsafe {
7197            std::mem::zeroed()
7198        };
7199        if let Some(value) = self.handle {
7200            raw.handle = value;
7201        }
7202        (raw, storage)
7203    }
7204    pub(crate) fn from_ffi(
7205        value: ffi::WGPUSharedFenceVkSemaphoreOpaqueFDExportInfo,
7206    ) -> Self {
7207        Self { handle: Some(value.handle) }
7208    }
7209}
7210pub struct SharedFenceVkSemaphoreZirconHandleDescriptor {
7211    pub handle: Option<u32>,
7212}
7213impl Default for SharedFenceVkSemaphoreZirconHandleDescriptor {
7214    fn default() -> Self {
7215        Self { handle: None }
7216    }
7217}
7218impl SharedFenceVkSemaphoreZirconHandleDescriptor {
7219    pub fn new() -> Self {
7220        Self::default()
7221    }
7222    pub(crate) fn to_ffi(
7223        &self,
7224    ) -> (ffi::WGPUSharedFenceVkSemaphoreZirconHandleDescriptor, ChainedStructStorage) {
7225        let mut storage = ChainedStructStorage::new();
7226        let mut raw: ffi::WGPUSharedFenceVkSemaphoreZirconHandleDescriptor = unsafe {
7227            std::mem::zeroed()
7228        };
7229        if let Some(value) = self.handle {
7230            raw.handle = value;
7231        }
7232        (raw, storage)
7233    }
7234    pub(crate) fn from_ffi(
7235        value: ffi::WGPUSharedFenceVkSemaphoreZirconHandleDescriptor,
7236    ) -> Self {
7237        Self { handle: Some(value.handle) }
7238    }
7239}
7240pub struct SharedFenceVkSemaphoreZirconHandleExportInfo {
7241    pub handle: Option<u32>,
7242}
7243impl Default for SharedFenceVkSemaphoreZirconHandleExportInfo {
7244    fn default() -> Self {
7245        Self { handle: None }
7246    }
7247}
7248impl SharedFenceVkSemaphoreZirconHandleExportInfo {
7249    pub fn new() -> Self {
7250        Self::default()
7251    }
7252    pub(crate) fn to_ffi(
7253        &self,
7254    ) -> (ffi::WGPUSharedFenceVkSemaphoreZirconHandleExportInfo, ChainedStructStorage) {
7255        let mut storage = ChainedStructStorage::new();
7256        let mut raw: ffi::WGPUSharedFenceVkSemaphoreZirconHandleExportInfo = unsafe {
7257            std::mem::zeroed()
7258        };
7259        if let Some(value) = self.handle {
7260            raw.handle = value;
7261        }
7262        (raw, storage)
7263    }
7264    pub(crate) fn from_ffi(
7265        value: ffi::WGPUSharedFenceVkSemaphoreZirconHandleExportInfo,
7266    ) -> Self {
7267        Self { handle: Some(value.handle) }
7268    }
7269}
7270pub struct SharedTextureMemoryD3DSwapchainBeginState {
7271    pub is_swapchain: Option<bool>,
7272}
7273impl Default for SharedTextureMemoryD3DSwapchainBeginState {
7274    fn default() -> Self {
7275        Self { is_swapchain: None }
7276    }
7277}
7278impl SharedTextureMemoryD3DSwapchainBeginState {
7279    pub fn new() -> Self {
7280        Self::default()
7281    }
7282    pub(crate) fn to_ffi(
7283        &self,
7284    ) -> (ffi::WGPUSharedTextureMemoryD3DSwapchainBeginState, ChainedStructStorage) {
7285        let mut storage = ChainedStructStorage::new();
7286        let mut raw: ffi::WGPUSharedTextureMemoryD3DSwapchainBeginState = unsafe {
7287            std::mem::zeroed()
7288        };
7289        raw.isSwapchain = if self.is_swapchain.unwrap_or(false) { 1 } else { 0 };
7290        (raw, storage)
7291    }
7292    pub(crate) fn from_ffi(
7293        value: ffi::WGPUSharedTextureMemoryD3DSwapchainBeginState,
7294    ) -> Self {
7295        Self {
7296            is_swapchain: Some(value.isSwapchain != 0),
7297        }
7298    }
7299}
7300pub struct SharedTextureMemoryD3D11BeginState {
7301    pub requires_end_access_fence: Option<bool>,
7302}
7303impl Default for SharedTextureMemoryD3D11BeginState {
7304    fn default() -> Self {
7305        Self {
7306            requires_end_access_fence: None,
7307        }
7308    }
7309}
7310impl SharedTextureMemoryD3D11BeginState {
7311    pub fn new() -> Self {
7312        Self::default()
7313    }
7314    pub(crate) fn to_ffi(
7315        &self,
7316    ) -> (ffi::WGPUSharedTextureMemoryD3D11BeginState, ChainedStructStorage) {
7317        let mut storage = ChainedStructStorage::new();
7318        let mut raw: ffi::WGPUSharedTextureMemoryD3D11BeginState = unsafe {
7319            std::mem::zeroed()
7320        };
7321        raw.requiresEndAccessFence = if self.requires_end_access_fence.unwrap_or(false) {
7322            1
7323        } else {
7324            0
7325        };
7326        (raw, storage)
7327    }
7328    pub(crate) fn from_ffi(value: ffi::WGPUSharedTextureMemoryD3D11BeginState) -> Self {
7329        Self {
7330            requires_end_access_fence: Some(value.requiresEndAccessFence != 0),
7331        }
7332    }
7333}
7334pub struct SharedTextureMemoryDXGISharedHandleDescriptor {
7335    pub handle: Option<*mut std::ffi::c_void>,
7336    pub use_keyed_mutex: Option<bool>,
7337}
7338impl Default for SharedTextureMemoryDXGISharedHandleDescriptor {
7339    fn default() -> Self {
7340        Self {
7341            handle: None,
7342            use_keyed_mutex: None,
7343        }
7344    }
7345}
7346impl SharedTextureMemoryDXGISharedHandleDescriptor {
7347    pub fn new() -> Self {
7348        Self::default()
7349    }
7350    pub(crate) fn to_ffi(
7351        &self,
7352    ) -> (ffi::WGPUSharedTextureMemoryDXGISharedHandleDescriptor, ChainedStructStorage) {
7353        let mut storage = ChainedStructStorage::new();
7354        let mut raw: ffi::WGPUSharedTextureMemoryDXGISharedHandleDescriptor = unsafe {
7355            std::mem::zeroed()
7356        };
7357        if let Some(value) = self.handle {
7358            raw.handle = value;
7359        }
7360        raw.useKeyedMutex = if self.use_keyed_mutex.unwrap_or(false) { 1 } else { 0 };
7361        (raw, storage)
7362    }
7363    pub(crate) fn from_ffi(
7364        value: ffi::WGPUSharedTextureMemoryDXGISharedHandleDescriptor,
7365    ) -> Self {
7366        Self {
7367            handle: Some(value.handle),
7368            use_keyed_mutex: Some(value.useKeyedMutex != 0),
7369        }
7370    }
7371}
7372pub struct SharedTextureMemoryEGLImageDescriptor {
7373    pub image: Option<*mut std::ffi::c_void>,
7374}
7375impl Default for SharedTextureMemoryEGLImageDescriptor {
7376    fn default() -> Self {
7377        Self { image: None }
7378    }
7379}
7380impl SharedTextureMemoryEGLImageDescriptor {
7381    pub fn new() -> Self {
7382        Self::default()
7383    }
7384    pub(crate) fn to_ffi(
7385        &self,
7386    ) -> (ffi::WGPUSharedTextureMemoryEGLImageDescriptor, ChainedStructStorage) {
7387        let mut storage = ChainedStructStorage::new();
7388        let mut raw: ffi::WGPUSharedTextureMemoryEGLImageDescriptor = unsafe {
7389            std::mem::zeroed()
7390        };
7391        if let Some(value) = self.image {
7392            raw.image = value;
7393        }
7394        (raw, storage)
7395    }
7396    pub(crate) fn from_ffi(
7397        value: ffi::WGPUSharedTextureMemoryEGLImageDescriptor,
7398    ) -> Self {
7399        Self { image: Some(value.image) }
7400    }
7401}
7402pub struct SharedTextureMemoryIOSurfaceDescriptor {
7403    pub io_surface: Option<*mut std::ffi::c_void>,
7404    pub allow_storage_binding: Option<bool>,
7405}
7406impl Default for SharedTextureMemoryIOSurfaceDescriptor {
7407    fn default() -> Self {
7408        Self {
7409            io_surface: None,
7410            allow_storage_binding: None,
7411        }
7412    }
7413}
7414impl SharedTextureMemoryIOSurfaceDescriptor {
7415    pub fn new() -> Self {
7416        Self::default()
7417    }
7418    pub(crate) fn to_ffi(
7419        &self,
7420    ) -> (ffi::WGPUSharedTextureMemoryIOSurfaceDescriptor, ChainedStructStorage) {
7421        let mut storage = ChainedStructStorage::new();
7422        let mut raw: ffi::WGPUSharedTextureMemoryIOSurfaceDescriptor = unsafe {
7423            std::mem::zeroed()
7424        };
7425        if let Some(value) = self.io_surface {
7426            raw.ioSurface = value;
7427        }
7428        raw.allowStorageBinding = if self.allow_storage_binding.unwrap_or(false) {
7429            1
7430        } else {
7431            0
7432        };
7433        (raw, storage)
7434    }
7435    pub(crate) fn from_ffi(
7436        value: ffi::WGPUSharedTextureMemoryIOSurfaceDescriptor,
7437    ) -> Self {
7438        Self {
7439            io_surface: Some(value.ioSurface),
7440            allow_storage_binding: Some(value.allowStorageBinding != 0),
7441        }
7442    }
7443}
7444pub struct SharedTextureMemoryAHardwareBufferDescriptor {
7445    pub handle: Option<*mut std::ffi::c_void>,
7446    pub use_external_format: Option<bool>,
7447}
7448impl Default for SharedTextureMemoryAHardwareBufferDescriptor {
7449    fn default() -> Self {
7450        Self {
7451            handle: None,
7452            use_external_format: None,
7453        }
7454    }
7455}
7456impl SharedTextureMemoryAHardwareBufferDescriptor {
7457    pub fn new() -> Self {
7458        Self::default()
7459    }
7460    pub(crate) fn to_ffi(
7461        &self,
7462    ) -> (ffi::WGPUSharedTextureMemoryAHardwareBufferDescriptor, ChainedStructStorage) {
7463        let mut storage = ChainedStructStorage::new();
7464        let mut raw: ffi::WGPUSharedTextureMemoryAHardwareBufferDescriptor = unsafe {
7465            std::mem::zeroed()
7466        };
7467        if let Some(value) = self.handle {
7468            raw.handle = value;
7469        }
7470        raw.useExternalFormat = if self.use_external_format.unwrap_or(false) {
7471            1
7472        } else {
7473            0
7474        };
7475        (raw, storage)
7476    }
7477    pub(crate) fn from_ffi(
7478        value: ffi::WGPUSharedTextureMemoryAHardwareBufferDescriptor,
7479    ) -> Self {
7480        Self {
7481            handle: Some(value.handle),
7482            use_external_format: Some(value.useExternalFormat != 0),
7483        }
7484    }
7485}
7486pub struct SharedTextureMemoryAHardwareBufferProperties {
7487    pub y_cb_cr_info: Option<YCbCrVkDescriptor>,
7488}
7489impl Default for SharedTextureMemoryAHardwareBufferProperties {
7490    fn default() -> Self {
7491        Self { y_cb_cr_info: None }
7492    }
7493}
7494impl SharedTextureMemoryAHardwareBufferProperties {
7495    pub fn new() -> Self {
7496        Self::default()
7497    }
7498    pub(crate) fn to_ffi(
7499        &self,
7500    ) -> (ffi::WGPUSharedTextureMemoryAHardwareBufferProperties, ChainedStructStorage) {
7501        let mut storage = ChainedStructStorage::new();
7502        let mut raw: ffi::WGPUSharedTextureMemoryAHardwareBufferProperties = unsafe {
7503            std::mem::zeroed()
7504        };
7505        if let Some(value) = &self.y_cb_cr_info {
7506            let (raw_value, storage_value) = value.to_ffi();
7507            raw.yCbCrInfo = raw_value;
7508            storage.push_storage(storage_value);
7509        }
7510        (raw, storage)
7511    }
7512    pub(crate) fn from_ffi(
7513        value: ffi::WGPUSharedTextureMemoryAHardwareBufferProperties,
7514    ) -> Self {
7515        Self {
7516            y_cb_cr_info: Some(YCbCrVkDescriptor::from_ffi(value.yCbCrInfo)),
7517        }
7518    }
7519}
7520pub struct SharedTextureMemoryBeginAccessDescriptor {
7521    pub(crate) extensions: Vec<SharedTextureMemoryBeginAccessDescriptorExtension>,
7522    pub concurrent_read: Option<bool>,
7523    pub initialized: Option<bool>,
7524    pub fences: Option<Vec<SharedFence>>,
7525    pub signaled_values: Option<Vec<u64>>,
7526}
7527impl Default for SharedTextureMemoryBeginAccessDescriptor {
7528    fn default() -> Self {
7529        Self {
7530            extensions: Vec::new(),
7531            concurrent_read: None,
7532            initialized: None,
7533            fences: None,
7534            signaled_values: None,
7535        }
7536    }
7537}
7538impl SharedTextureMemoryBeginAccessDescriptor {
7539    pub fn new() -> Self {
7540        Self::default()
7541    }
7542    pub(crate) fn to_ffi(
7543        &self,
7544    ) -> (ffi::WGPUSharedTextureMemoryBeginAccessDescriptor, ChainedStructStorage) {
7545        let mut storage = ChainedStructStorage::new();
7546        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
7547        for ext in self.extensions.iter().rev() {
7548            next = ext.push_chain(&mut storage, next);
7549        }
7550        let mut raw: ffi::WGPUSharedTextureMemoryBeginAccessDescriptor = unsafe {
7551            std::mem::zeroed()
7552        };
7553        raw.nextInChain = next;
7554        raw.concurrentRead = if self.concurrent_read.unwrap_or(false) { 1 } else { 0 };
7555        raw.initialized = if self.initialized.unwrap_or(false) { 1 } else { 0 };
7556        raw.fenceCount = self.signaled_values.as_ref().map(|v| v.len()).unwrap_or(0);
7557        if let Some(values) = &self.fences {
7558            let len_value = values.len();
7559            let raw_vec: Vec<ffi::WGPUSharedFence> = values
7560                .iter()
7561                .map(|v| v.as_raw())
7562                .collect();
7563            let ptr = storage.push_vec(raw_vec);
7564            raw.fences = ptr;
7565            raw.fenceCount = len_value;
7566        } else {
7567            raw.fences = std::ptr::null();
7568            raw.fenceCount = 0;
7569        }
7570        if let Some(values) = &self.signaled_values {
7571            let len_value = values.len();
7572            let raw_vec = values.to_vec();
7573            let ptr = storage.push_vec(raw_vec);
7574            raw.signaledValues = ptr;
7575            raw.fenceCount = len_value;
7576        } else {
7577            raw.signaledValues = std::ptr::null();
7578            raw.fenceCount = 0;
7579        }
7580        (raw, storage)
7581    }
7582    pub fn with_extension(
7583        mut self,
7584        extension: SharedTextureMemoryBeginAccessDescriptorExtension,
7585    ) -> Self {
7586        self.extensions.push(extension);
7587        self
7588    }
7589    pub(crate) fn from_ffi(
7590        value: ffi::WGPUSharedTextureMemoryBeginAccessDescriptor,
7591    ) -> Self {
7592        Self {
7593            extensions: Vec::new(),
7594            concurrent_read: Some(value.concurrentRead != 0),
7595            initialized: Some(value.initialized != 0),
7596            fences: if value.fences.is_null() {
7597                None
7598            } else {
7599                Some(
7600                    unsafe {
7601                        std::slice::from_raw_parts(
7602                            value.fences,
7603                            value.fenceCount as usize,
7604                        )
7605                    }
7606                        .iter()
7607                        .map(|raw| unsafe { SharedFence::from_raw(*raw) })
7608                        .collect(),
7609                )
7610            },
7611            signaled_values: if value.signaledValues.is_null() {
7612                None
7613            } else {
7614                Some(
7615                    unsafe {
7616                        std::slice::from_raw_parts(
7617                            value.signaledValues,
7618                            value.fenceCount as usize,
7619                        )
7620                    }
7621                        .to_vec(),
7622                )
7623            },
7624        }
7625    }
7626}
7627pub struct SharedTextureMemoryDescriptor {
7628    pub(crate) extensions: Vec<SharedTextureMemoryDescriptorExtension>,
7629    pub label: Option<String>,
7630}
7631impl Default for SharedTextureMemoryDescriptor {
7632    fn default() -> Self {
7633        Self {
7634            extensions: Vec::new(),
7635            label: None,
7636        }
7637    }
7638}
7639impl SharedTextureMemoryDescriptor {
7640    pub fn new() -> Self {
7641        Self::default()
7642    }
7643    pub(crate) fn to_ffi(
7644        &self,
7645    ) -> (ffi::WGPUSharedTextureMemoryDescriptor, ChainedStructStorage) {
7646        let mut storage = ChainedStructStorage::new();
7647        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
7648        for ext in self.extensions.iter().rev() {
7649            next = ext.push_chain(&mut storage, next);
7650        }
7651        let mut raw: ffi::WGPUSharedTextureMemoryDescriptor = unsafe {
7652            std::mem::zeroed()
7653        };
7654        raw.nextInChain = next;
7655        if let Some(value) = &self.label {
7656            raw.label = ffi::WGPUStringView {
7657                data: value.as_ptr().cast(),
7658                length: value.len(),
7659            };
7660        } else {
7661            raw.label = ffi::WGPUStringView {
7662                data: std::ptr::null(),
7663                length: 0,
7664            };
7665        }
7666        (raw, storage)
7667    }
7668    pub fn with_extension(
7669        mut self,
7670        extension: SharedTextureMemoryDescriptorExtension,
7671    ) -> Self {
7672        self.extensions.push(extension);
7673        self
7674    }
7675    pub(crate) fn from_ffi(value: ffi::WGPUSharedTextureMemoryDescriptor) -> Self {
7676        Self {
7677            extensions: Vec::new(),
7678            label: if value.label.data.is_null() || value.label.length == 0 {
7679                None
7680            } else {
7681                Some(string_view_to_string(value.label))
7682            },
7683        }
7684    }
7685}
7686pub struct SharedTextureMemoryDmaBufDescriptor {
7687    pub size: Option<Extent3D>,
7688    pub drm_format: Option<u32>,
7689    pub drm_modifier: Option<u64>,
7690    pub planes: Option<Vec<SharedTextureMemoryDmaBufPlane>>,
7691}
7692impl Default for SharedTextureMemoryDmaBufDescriptor {
7693    fn default() -> Self {
7694        Self {
7695            size: None,
7696            drm_format: None,
7697            drm_modifier: None,
7698            planes: None,
7699        }
7700    }
7701}
7702impl SharedTextureMemoryDmaBufDescriptor {
7703    pub fn new() -> Self {
7704        Self::default()
7705    }
7706    pub(crate) fn to_ffi(
7707        &self,
7708    ) -> (ffi::WGPUSharedTextureMemoryDmaBufDescriptor, ChainedStructStorage) {
7709        let mut storage = ChainedStructStorage::new();
7710        let mut raw: ffi::WGPUSharedTextureMemoryDmaBufDescriptor = unsafe {
7711            std::mem::zeroed()
7712        };
7713        if let Some(value) = &self.size {
7714            let (raw_value, storage_value) = value.to_ffi();
7715            raw.size = raw_value;
7716            storage.push_storage(storage_value);
7717        }
7718        if let Some(value) = self.drm_format {
7719            raw.drmFormat = value;
7720        }
7721        if let Some(value) = self.drm_modifier {
7722            raw.drmModifier = value;
7723        }
7724        raw.planeCount = self.planes.as_ref().map(|v| v.len()).unwrap_or(0);
7725        if let Some(values) = &self.planes {
7726            let len_value = values.len();
7727            let mut raw_vec: Vec<ffi::WGPUSharedTextureMemoryDmaBufPlane> = Vec::with_capacity(
7728                values.len(),
7729            );
7730            for item in values.iter() {
7731                let (raw_item, storage_item) = item.to_ffi();
7732                raw_vec.push(raw_item);
7733                storage.push_storage(storage_item);
7734            }
7735            let ptr = storage.push_vec(raw_vec);
7736            raw.planes = ptr;
7737            raw.planeCount = len_value;
7738        } else {
7739            raw.planes = std::ptr::null();
7740            raw.planeCount = 0;
7741        }
7742        (raw, storage)
7743    }
7744    pub(crate) fn from_ffi(value: ffi::WGPUSharedTextureMemoryDmaBufDescriptor) -> Self {
7745        Self {
7746            size: Some(Extent3D::from_ffi(value.size)),
7747            drm_format: Some(value.drmFormat),
7748            drm_modifier: Some(value.drmModifier),
7749            planes: if value.planes.is_null() {
7750                None
7751            } else {
7752                Some(
7753                    unsafe {
7754                        std::slice::from_raw_parts(
7755                            value.planes,
7756                            value.planeCount as usize,
7757                        )
7758                    }
7759                        .iter()
7760                        .map(|raw| SharedTextureMemoryDmaBufPlane::from_ffi(*raw))
7761                        .collect(),
7762                )
7763            },
7764        }
7765    }
7766}
7767pub struct SharedTextureMemoryDmaBufPlane {
7768    pub fd: Option<i32>,
7769    pub offset: Option<u64>,
7770    pub stride: Option<u32>,
7771}
7772impl Default for SharedTextureMemoryDmaBufPlane {
7773    fn default() -> Self {
7774        Self {
7775            fd: None,
7776            offset: None,
7777            stride: None,
7778        }
7779    }
7780}
7781impl SharedTextureMemoryDmaBufPlane {
7782    pub fn new() -> Self {
7783        Self::default()
7784    }
7785    pub(crate) fn to_ffi(
7786        &self,
7787    ) -> (ffi::WGPUSharedTextureMemoryDmaBufPlane, ChainedStructStorage) {
7788        let mut storage = ChainedStructStorage::new();
7789        let mut raw: ffi::WGPUSharedTextureMemoryDmaBufPlane = unsafe {
7790            std::mem::zeroed()
7791        };
7792        if let Some(value) = self.fd {
7793            raw.fd = value;
7794        }
7795        if let Some(value) = self.offset {
7796            raw.offset = value;
7797        }
7798        if let Some(value) = self.stride {
7799            raw.stride = value;
7800        }
7801        (raw, storage)
7802    }
7803    pub(crate) fn from_ffi(value: ffi::WGPUSharedTextureMemoryDmaBufPlane) -> Self {
7804        Self {
7805            fd: Some(value.fd),
7806            offset: Some(value.offset),
7807            stride: Some(value.stride),
7808        }
7809    }
7810}
7811pub struct SharedTextureMemoryEndAccessState {
7812    pub(crate) extensions: Vec<SharedTextureMemoryEndAccessStateExtension>,
7813    pub initialized: Option<bool>,
7814    pub fences: Option<Vec<SharedFence>>,
7815    pub signaled_values: Option<Vec<u64>>,
7816    #[doc(hidden)]
7817    pub(crate) _free_members: Option<ffi::WGPUSharedTextureMemoryEndAccessState>,
7818}
7819impl Default for SharedTextureMemoryEndAccessState {
7820    fn default() -> Self {
7821        Self {
7822            extensions: Vec::new(),
7823            initialized: None,
7824            fences: None,
7825            signaled_values: None,
7826            _free_members: None,
7827        }
7828    }
7829}
7830impl SharedTextureMemoryEndAccessState {
7831    pub fn new() -> Self {
7832        Self::default()
7833    }
7834    pub(crate) fn to_ffi(
7835        &self,
7836    ) -> (ffi::WGPUSharedTextureMemoryEndAccessState, ChainedStructStorage) {
7837        let mut storage = ChainedStructStorage::new();
7838        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
7839        for ext in self.extensions.iter().rev() {
7840            next = ext.push_chain(&mut storage, next);
7841        }
7842        let mut raw: ffi::WGPUSharedTextureMemoryEndAccessState = unsafe {
7843            std::mem::zeroed()
7844        };
7845        raw.nextInChain = next;
7846        raw.initialized = if self.initialized.unwrap_or(false) { 1 } else { 0 };
7847        raw.fenceCount = self.signaled_values.as_ref().map(|v| v.len()).unwrap_or(0);
7848        if let Some(values) = &self.fences {
7849            let len_value = values.len();
7850            let raw_vec: Vec<ffi::WGPUSharedFence> = values
7851                .iter()
7852                .map(|v| v.as_raw())
7853                .collect();
7854            let ptr = storage.push_vec(raw_vec);
7855            raw.fences = ptr;
7856            raw.fenceCount = len_value;
7857        } else {
7858            raw.fences = std::ptr::null();
7859            raw.fenceCount = 0;
7860        }
7861        if let Some(values) = &self.signaled_values {
7862            let len_value = values.len();
7863            let raw_vec = values.to_vec();
7864            let ptr = storage.push_vec(raw_vec);
7865            raw.signaledValues = ptr;
7866            raw.fenceCount = len_value;
7867        } else {
7868            raw.signaledValues = std::ptr::null();
7869            raw.fenceCount = 0;
7870        }
7871        (raw, storage)
7872    }
7873    pub fn with_extension(
7874        mut self,
7875        extension: SharedTextureMemoryEndAccessStateExtension,
7876    ) -> Self {
7877        self.extensions.push(extension);
7878        self
7879    }
7880    pub(crate) fn from_ffi(value: ffi::WGPUSharedTextureMemoryEndAccessState) -> Self {
7881        Self {
7882            extensions: Vec::new(),
7883            initialized: Some(value.initialized != 0),
7884            fences: if value.fences.is_null() {
7885                None
7886            } else {
7887                Some(
7888                    unsafe {
7889                        std::slice::from_raw_parts(
7890                            value.fences,
7891                            value.fenceCount as usize,
7892                        )
7893                    }
7894                        .iter()
7895                        .map(|raw| unsafe { SharedFence::from_raw(*raw) })
7896                        .collect(),
7897                )
7898            },
7899            signaled_values: if value.signaledValues.is_null() {
7900                None
7901            } else {
7902                Some(
7903                    unsafe {
7904                        std::slice::from_raw_parts(
7905                            value.signaledValues,
7906                            value.fenceCount as usize,
7907                        )
7908                    }
7909                        .to_vec(),
7910                )
7911            },
7912            _free_members: Some(value),
7913        }
7914    }
7915    pub(crate) fn free_members(value: ffi::WGPUSharedTextureMemoryEndAccessState) {
7916        unsafe { ffi::wgpuSharedTextureMemoryEndAccessStateFreeMembers(value) };
7917    }
7918}
7919impl Drop for SharedTextureMemoryEndAccessState {
7920    fn drop(&mut self) {
7921        if let Some(value) = self._free_members.take() {
7922            unsafe { ffi::wgpuSharedTextureMemoryEndAccessStateFreeMembers(value) };
7923        }
7924    }
7925}
7926pub struct SharedTextureMemoryMetalEndAccessState {
7927    pub commands_scheduled_future: Option<Future>,
7928}
7929impl Default for SharedTextureMemoryMetalEndAccessState {
7930    fn default() -> Self {
7931        Self {
7932            commands_scheduled_future: None,
7933        }
7934    }
7935}
7936impl SharedTextureMemoryMetalEndAccessState {
7937    pub fn new() -> Self {
7938        Self::default()
7939    }
7940    pub(crate) fn to_ffi(
7941        &self,
7942    ) -> (ffi::WGPUSharedTextureMemoryMetalEndAccessState, ChainedStructStorage) {
7943        let mut storage = ChainedStructStorage::new();
7944        let mut raw: ffi::WGPUSharedTextureMemoryMetalEndAccessState = unsafe {
7945            std::mem::zeroed()
7946        };
7947        if let Some(value) = &self.commands_scheduled_future {
7948            let (raw_value, storage_value) = value.to_ffi();
7949            raw.commandsScheduledFuture = raw_value;
7950            storage.push_storage(storage_value);
7951        }
7952        (raw, storage)
7953    }
7954    pub(crate) fn from_ffi(
7955        value: ffi::WGPUSharedTextureMemoryMetalEndAccessState,
7956    ) -> Self {
7957        Self {
7958            commands_scheduled_future: Some(
7959                Future::from_ffi(value.commandsScheduledFuture),
7960            ),
7961        }
7962    }
7963}
7964pub struct SharedTextureMemoryOpaqueFDDescriptor {
7965    pub vk_image_create_info: Option<*const std::ffi::c_void>,
7966    pub memory_fd: Option<i32>,
7967    pub memory_type_index: Option<u32>,
7968    pub allocation_size: Option<u64>,
7969    pub dedicated_allocation: Option<bool>,
7970}
7971impl Default for SharedTextureMemoryOpaqueFDDescriptor {
7972    fn default() -> Self {
7973        Self {
7974            vk_image_create_info: None,
7975            memory_fd: None,
7976            memory_type_index: None,
7977            allocation_size: None,
7978            dedicated_allocation: None,
7979        }
7980    }
7981}
7982impl SharedTextureMemoryOpaqueFDDescriptor {
7983    pub fn new() -> Self {
7984        Self::default()
7985    }
7986    pub(crate) fn to_ffi(
7987        &self,
7988    ) -> (ffi::WGPUSharedTextureMemoryOpaqueFDDescriptor, ChainedStructStorage) {
7989        let mut storage = ChainedStructStorage::new();
7990        let mut raw: ffi::WGPUSharedTextureMemoryOpaqueFDDescriptor = unsafe {
7991            std::mem::zeroed()
7992        };
7993        if let Some(value) = self.vk_image_create_info {
7994            raw.vkImageCreateInfo = value;
7995        }
7996        if let Some(value) = self.memory_fd {
7997            raw.memoryFD = value;
7998        }
7999        if let Some(value) = self.memory_type_index {
8000            raw.memoryTypeIndex = value;
8001        }
8002        if let Some(value) = self.allocation_size {
8003            raw.allocationSize = value;
8004        }
8005        raw.dedicatedAllocation = if self.dedicated_allocation.unwrap_or(false) {
8006            1
8007        } else {
8008            0
8009        };
8010        (raw, storage)
8011    }
8012    pub(crate) fn from_ffi(
8013        value: ffi::WGPUSharedTextureMemoryOpaqueFDDescriptor,
8014    ) -> Self {
8015        Self {
8016            vk_image_create_info: Some(value.vkImageCreateInfo),
8017            memory_fd: Some(value.memoryFD),
8018            memory_type_index: Some(value.memoryTypeIndex),
8019            allocation_size: Some(value.allocationSize),
8020            dedicated_allocation: Some(value.dedicatedAllocation != 0),
8021        }
8022    }
8023}
8024pub struct SharedTextureMemoryProperties {
8025    pub(crate) extensions: Vec<SharedTextureMemoryPropertiesExtension>,
8026    pub usage: Option<TextureUsage>,
8027    pub size: Option<Extent3D>,
8028    pub format: Option<TextureFormat>,
8029}
8030impl Default for SharedTextureMemoryProperties {
8031    fn default() -> Self {
8032        Self {
8033            extensions: Vec::new(),
8034            usage: None,
8035            size: None,
8036            format: None,
8037        }
8038    }
8039}
8040impl SharedTextureMemoryProperties {
8041    pub fn new() -> Self {
8042        Self::default()
8043    }
8044    pub(crate) fn to_ffi(
8045        &self,
8046    ) -> (ffi::WGPUSharedTextureMemoryProperties, ChainedStructStorage) {
8047        let mut storage = ChainedStructStorage::new();
8048        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
8049        for ext in self.extensions.iter().rev() {
8050            next = ext.push_chain(&mut storage, next);
8051        }
8052        let mut raw: ffi::WGPUSharedTextureMemoryProperties = unsafe {
8053            std::mem::zeroed()
8054        };
8055        raw.nextInChain = next;
8056        if let Some(value) = self.usage {
8057            raw.usage = value.into();
8058        } else {
8059            raw.usage = 0 as ffi::WGPUTextureUsage;
8060        }
8061        if let Some(value) = &self.size {
8062            let (raw_value, storage_value) = value.to_ffi();
8063            raw.size = raw_value;
8064            storage.push_storage(storage_value);
8065        }
8066        if let Some(value) = self.format {
8067            raw.format = value.into();
8068        } else {
8069            raw.format = 0 as ffi::WGPUTextureFormat;
8070        }
8071        (raw, storage)
8072    }
8073    pub fn with_extension(
8074        mut self,
8075        extension: SharedTextureMemoryPropertiesExtension,
8076    ) -> Self {
8077        self.extensions.push(extension);
8078        self
8079    }
8080    pub(crate) fn from_ffi(value: ffi::WGPUSharedTextureMemoryProperties) -> Self {
8081        Self {
8082            extensions: Vec::new(),
8083            usage: Some(value.usage.into()),
8084            size: Some(Extent3D::from_ffi(value.size)),
8085            format: Some(value.format.into()),
8086        }
8087    }
8088}
8089pub struct SharedTextureMemoryVkDedicatedAllocationDescriptor {
8090    pub dedicated_allocation: Option<bool>,
8091}
8092impl Default for SharedTextureMemoryVkDedicatedAllocationDescriptor {
8093    fn default() -> Self {
8094        Self { dedicated_allocation: None }
8095    }
8096}
8097impl SharedTextureMemoryVkDedicatedAllocationDescriptor {
8098    pub fn new() -> Self {
8099        Self::default()
8100    }
8101    pub(crate) fn to_ffi(
8102        &self,
8103    ) -> (
8104        ffi::WGPUSharedTextureMemoryVkDedicatedAllocationDescriptor,
8105        ChainedStructStorage,
8106    ) {
8107        let mut storage = ChainedStructStorage::new();
8108        let mut raw: ffi::WGPUSharedTextureMemoryVkDedicatedAllocationDescriptor = unsafe {
8109            std::mem::zeroed()
8110        };
8111        raw.dedicatedAllocation = if self.dedicated_allocation.unwrap_or(false) {
8112            1
8113        } else {
8114            0
8115        };
8116        (raw, storage)
8117    }
8118    pub(crate) fn from_ffi(
8119        value: ffi::WGPUSharedTextureMemoryVkDedicatedAllocationDescriptor,
8120    ) -> Self {
8121        Self {
8122            dedicated_allocation: Some(value.dedicatedAllocation != 0),
8123        }
8124    }
8125}
8126pub struct SharedTextureMemoryVkImageLayoutBeginState {
8127    pub old_layout: Option<i32>,
8128    pub new_layout: Option<i32>,
8129}
8130impl Default for SharedTextureMemoryVkImageLayoutBeginState {
8131    fn default() -> Self {
8132        Self {
8133            old_layout: None,
8134            new_layout: None,
8135        }
8136    }
8137}
8138impl SharedTextureMemoryVkImageLayoutBeginState {
8139    pub fn new() -> Self {
8140        Self::default()
8141    }
8142    pub(crate) fn to_ffi(
8143        &self,
8144    ) -> (ffi::WGPUSharedTextureMemoryVkImageLayoutBeginState, ChainedStructStorage) {
8145        let mut storage = ChainedStructStorage::new();
8146        let mut raw: ffi::WGPUSharedTextureMemoryVkImageLayoutBeginState = unsafe {
8147            std::mem::zeroed()
8148        };
8149        if let Some(value) = self.old_layout {
8150            raw.oldLayout = value;
8151        }
8152        if let Some(value) = self.new_layout {
8153            raw.newLayout = value;
8154        }
8155        (raw, storage)
8156    }
8157    pub(crate) fn from_ffi(
8158        value: ffi::WGPUSharedTextureMemoryVkImageLayoutBeginState,
8159    ) -> Self {
8160        Self {
8161            old_layout: Some(value.oldLayout),
8162            new_layout: Some(value.newLayout),
8163        }
8164    }
8165}
8166pub struct SharedTextureMemoryVkImageLayoutEndState {
8167    pub old_layout: Option<i32>,
8168    pub new_layout: Option<i32>,
8169}
8170impl Default for SharedTextureMemoryVkImageLayoutEndState {
8171    fn default() -> Self {
8172        Self {
8173            old_layout: None,
8174            new_layout: None,
8175        }
8176    }
8177}
8178impl SharedTextureMemoryVkImageLayoutEndState {
8179    pub fn new() -> Self {
8180        Self::default()
8181    }
8182    pub(crate) fn to_ffi(
8183        &self,
8184    ) -> (ffi::WGPUSharedTextureMemoryVkImageLayoutEndState, ChainedStructStorage) {
8185        let mut storage = ChainedStructStorage::new();
8186        let mut raw: ffi::WGPUSharedTextureMemoryVkImageLayoutEndState = unsafe {
8187            std::mem::zeroed()
8188        };
8189        if let Some(value) = self.old_layout {
8190            raw.oldLayout = value;
8191        }
8192        if let Some(value) = self.new_layout {
8193            raw.newLayout = value;
8194        }
8195        (raw, storage)
8196    }
8197    pub(crate) fn from_ffi(
8198        value: ffi::WGPUSharedTextureMemoryVkImageLayoutEndState,
8199    ) -> Self {
8200        Self {
8201            old_layout: Some(value.oldLayout),
8202            new_layout: Some(value.newLayout),
8203        }
8204    }
8205}
8206pub struct SharedTextureMemoryZirconHandleDescriptor {
8207    pub memory_fd: Option<u32>,
8208    pub allocation_size: Option<u64>,
8209}
8210impl Default for SharedTextureMemoryZirconHandleDescriptor {
8211    fn default() -> Self {
8212        Self {
8213            memory_fd: None,
8214            allocation_size: None,
8215        }
8216    }
8217}
8218impl SharedTextureMemoryZirconHandleDescriptor {
8219    pub fn new() -> Self {
8220        Self::default()
8221    }
8222    pub(crate) fn to_ffi(
8223        &self,
8224    ) -> (ffi::WGPUSharedTextureMemoryZirconHandleDescriptor, ChainedStructStorage) {
8225        let mut storage = ChainedStructStorage::new();
8226        let mut raw: ffi::WGPUSharedTextureMemoryZirconHandleDescriptor = unsafe {
8227            std::mem::zeroed()
8228        };
8229        if let Some(value) = self.memory_fd {
8230            raw.memoryFD = value;
8231        }
8232        if let Some(value) = self.allocation_size {
8233            raw.allocationSize = value;
8234        }
8235        (raw, storage)
8236    }
8237    pub(crate) fn from_ffi(
8238        value: ffi::WGPUSharedTextureMemoryZirconHandleDescriptor,
8239    ) -> Self {
8240        Self {
8241            memory_fd: Some(value.memoryFD),
8242            allocation_size: Some(value.allocationSize),
8243        }
8244    }
8245}
8246pub struct StaticSamplerBindingLayout {
8247    pub sampler: Option<Sampler>,
8248    pub sampled_texture_binding: Option<u32>,
8249}
8250impl Default for StaticSamplerBindingLayout {
8251    fn default() -> Self {
8252        Self {
8253            sampler: None,
8254            sampled_texture_binding: Some(LIMIT_U32_UNDEFINED),
8255        }
8256    }
8257}
8258impl StaticSamplerBindingLayout {
8259    pub fn new() -> Self {
8260        Self::default()
8261    }
8262    pub(crate) fn to_ffi(
8263        &self,
8264    ) -> (ffi::WGPUStaticSamplerBindingLayout, ChainedStructStorage) {
8265        let mut storage = ChainedStructStorage::new();
8266        let mut raw: ffi::WGPUStaticSamplerBindingLayout = unsafe { std::mem::zeroed() };
8267        raw.sampler = self
8268            .sampler
8269            .as_ref()
8270            .map(|v| v.as_raw())
8271            .unwrap_or(std::ptr::null_mut());
8272        if let Some(value) = self.sampled_texture_binding {
8273            raw.sampledTextureBinding = value;
8274        }
8275        (raw, storage)
8276    }
8277    pub(crate) fn from_ffi(value: ffi::WGPUStaticSamplerBindingLayout) -> Self {
8278        Self {
8279            sampler: Some(unsafe { Sampler::from_raw(value.sampler) }),
8280            sampled_texture_binding: Some(value.sampledTextureBinding),
8281        }
8282    }
8283}
8284pub struct StencilFaceState {
8285    pub compare: Option<CompareFunction>,
8286    pub fail_op: Option<StencilOperation>,
8287    pub depth_fail_op: Option<StencilOperation>,
8288    pub pass_op: Option<StencilOperation>,
8289}
8290impl Default for StencilFaceState {
8291    fn default() -> Self {
8292        Self {
8293            compare: Some(CompareFunction::Always),
8294            fail_op: Some(StencilOperation::Keep),
8295            depth_fail_op: Some(StencilOperation::Keep),
8296            pass_op: Some(StencilOperation::Keep),
8297        }
8298    }
8299}
8300impl StencilFaceState {
8301    pub fn new() -> Self {
8302        Self::default()
8303    }
8304    pub(crate) fn to_ffi(&self) -> (ffi::WGPUStencilFaceState, ChainedStructStorage) {
8305        let mut storage = ChainedStructStorage::new();
8306        let mut raw: ffi::WGPUStencilFaceState = unsafe { std::mem::zeroed() };
8307        if let Some(value) = self.compare {
8308            raw.compare = value.into();
8309        } else {
8310            raw.compare = 0 as ffi::WGPUCompareFunction;
8311        }
8312        if let Some(value) = self.fail_op {
8313            raw.failOp = value.into();
8314        } else {
8315            raw.failOp = 0 as ffi::WGPUStencilOperation;
8316        }
8317        if let Some(value) = self.depth_fail_op {
8318            raw.depthFailOp = value.into();
8319        } else {
8320            raw.depthFailOp = 0 as ffi::WGPUStencilOperation;
8321        }
8322        if let Some(value) = self.pass_op {
8323            raw.passOp = value.into();
8324        } else {
8325            raw.passOp = 0 as ffi::WGPUStencilOperation;
8326        }
8327        (raw, storage)
8328    }
8329    pub(crate) fn from_ffi(value: ffi::WGPUStencilFaceState) -> Self {
8330        Self {
8331            compare: Some(value.compare.into()),
8332            fail_op: Some(value.failOp.into()),
8333            depth_fail_op: Some(value.depthFailOp.into()),
8334            pass_op: Some(value.passOp.into()),
8335        }
8336    }
8337}
8338pub struct StorageTextureBindingLayout {
8339    pub(crate) extensions: Vec<StorageTextureBindingLayoutExtension>,
8340    pub access: Option<StorageTextureAccess>,
8341    pub format: Option<TextureFormat>,
8342    pub view_dimension: Option<TextureViewDimension>,
8343}
8344impl Default for StorageTextureBindingLayout {
8345    fn default() -> Self {
8346        Self {
8347            extensions: Vec::new(),
8348            access: Some(StorageTextureAccess::WriteOnly),
8349            format: None,
8350            view_dimension: Some(TextureViewDimension::D2),
8351        }
8352    }
8353}
8354impl StorageTextureBindingLayout {
8355    pub fn new() -> Self {
8356        Self::default()
8357    }
8358    pub(crate) fn to_ffi(
8359        &self,
8360    ) -> (ffi::WGPUStorageTextureBindingLayout, ChainedStructStorage) {
8361        let mut storage = ChainedStructStorage::new();
8362        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
8363        for ext in self.extensions.iter().rev() {
8364            next = ext.push_chain(&mut storage, next);
8365        }
8366        let mut raw: ffi::WGPUStorageTextureBindingLayout = unsafe {
8367            std::mem::zeroed()
8368        };
8369        raw.nextInChain = next;
8370        if let Some(value) = self.access {
8371            raw.access = value.into();
8372        } else {
8373            raw.access = 0 as ffi::WGPUStorageTextureAccess;
8374        }
8375        if let Some(value) = self.format {
8376            raw.format = value.into();
8377        } else {
8378            raw.format = 0 as ffi::WGPUTextureFormat;
8379        }
8380        if let Some(value) = self.view_dimension {
8381            raw.viewDimension = value.into();
8382        } else {
8383            raw.viewDimension = 0 as ffi::WGPUTextureViewDimension;
8384        }
8385        (raw, storage)
8386    }
8387    pub fn with_extension(
8388        mut self,
8389        extension: StorageTextureBindingLayoutExtension,
8390    ) -> Self {
8391        self.extensions.push(extension);
8392        self
8393    }
8394    pub(crate) fn from_ffi(value: ffi::WGPUStorageTextureBindingLayout) -> Self {
8395        Self {
8396            extensions: Vec::new(),
8397            access: Some(value.access.into()),
8398            format: Some(value.format.into()),
8399            view_dimension: Some(value.viewDimension.into()),
8400        }
8401    }
8402}
8403pub struct StringView {
8404    pub data: Option<*const std::os::raw::c_char>,
8405    pub length: Option<usize>,
8406}
8407impl Default for StringView {
8408    fn default() -> Self {
8409        Self {
8410            data: None,
8411            length: Some(STRLEN),
8412        }
8413    }
8414}
8415impl StringView {
8416    pub fn new() -> Self {
8417        Self::default()
8418    }
8419    pub(crate) fn to_ffi(&self) -> (ffi::WGPUStringView, ChainedStructStorage) {
8420        let mut storage = ChainedStructStorage::new();
8421        let mut raw: ffi::WGPUStringView = unsafe { std::mem::zeroed() };
8422        if let Some(value) = self.data {
8423            raw.data = value;
8424        }
8425        if let Some(value) = self.length {
8426            raw.length = value;
8427        }
8428        (raw, storage)
8429    }
8430    pub(crate) fn from_ffi(value: ffi::WGPUStringView) -> Self {
8431        Self {
8432            data: Some(value.data),
8433            length: Some(value.length),
8434        }
8435    }
8436}
8437pub struct SubgroupMatrixConfig {
8438    pub component_type: Option<SubgroupMatrixComponentType>,
8439    pub result_component_type: Option<SubgroupMatrixComponentType>,
8440    pub m: Option<u32>,
8441    pub n: Option<u32>,
8442    pub k: Option<u32>,
8443}
8444impl Default for SubgroupMatrixConfig {
8445    fn default() -> Self {
8446        Self {
8447            component_type: None,
8448            result_component_type: None,
8449            m: None,
8450            n: None,
8451            k: None,
8452        }
8453    }
8454}
8455impl SubgroupMatrixConfig {
8456    pub fn new() -> Self {
8457        Self::default()
8458    }
8459    pub(crate) fn to_ffi(
8460        &self,
8461    ) -> (ffi::WGPUSubgroupMatrixConfig, ChainedStructStorage) {
8462        let mut storage = ChainedStructStorage::new();
8463        let mut raw: ffi::WGPUSubgroupMatrixConfig = unsafe { std::mem::zeroed() };
8464        if let Some(value) = self.component_type {
8465            raw.componentType = value.into();
8466        } else {
8467            raw.componentType = 0 as ffi::WGPUSubgroupMatrixComponentType;
8468        }
8469        if let Some(value) = self.result_component_type {
8470            raw.resultComponentType = value.into();
8471        } else {
8472            raw.resultComponentType = 0 as ffi::WGPUSubgroupMatrixComponentType;
8473        }
8474        if let Some(value) = self.m {
8475            raw.M = value;
8476        }
8477        if let Some(value) = self.n {
8478            raw.N = value;
8479        }
8480        if let Some(value) = self.k {
8481            raw.K = value;
8482        }
8483        (raw, storage)
8484    }
8485    pub(crate) fn from_ffi(value: ffi::WGPUSubgroupMatrixConfig) -> Self {
8486        Self {
8487            component_type: Some(value.componentType.into()),
8488            result_component_type: Some(value.resultComponentType.into()),
8489            m: Some(value.M),
8490            n: Some(value.N),
8491            k: Some(value.K),
8492        }
8493    }
8494}
8495pub struct SupportedWGSLLanguageFeatures {
8496    pub features: Option<Vec<WGSLLanguageFeatureName>>,
8497    #[doc(hidden)]
8498    pub(crate) _free_members: Option<ffi::WGPUSupportedWGSLLanguageFeatures>,
8499}
8500impl Default for SupportedWGSLLanguageFeatures {
8501    fn default() -> Self {
8502        Self {
8503            features: None,
8504            _free_members: None,
8505        }
8506    }
8507}
8508impl SupportedWGSLLanguageFeatures {
8509    pub fn new() -> Self {
8510        Self::default()
8511    }
8512    pub(crate) fn to_ffi(
8513        &self,
8514    ) -> (ffi::WGPUSupportedWGSLLanguageFeatures, ChainedStructStorage) {
8515        let mut storage = ChainedStructStorage::new();
8516        let mut raw: ffi::WGPUSupportedWGSLLanguageFeatures = unsafe {
8517            std::mem::zeroed()
8518        };
8519        raw.featureCount = self.features.as_ref().map(|v| v.len()).unwrap_or(0);
8520        if let Some(values) = &self.features {
8521            let len_value = values.len();
8522            let raw_vec: Vec<ffi::WGPUWGSLLanguageFeatureName> = values
8523                .iter()
8524                .map(|v| (*v).into())
8525                .collect();
8526            let ptr = storage.push_vec(raw_vec);
8527            raw.features = ptr;
8528            raw.featureCount = len_value;
8529        } else {
8530            raw.features = std::ptr::null();
8531            raw.featureCount = 0;
8532        }
8533        (raw, storage)
8534    }
8535    pub(crate) fn from_ffi(value: ffi::WGPUSupportedWGSLLanguageFeatures) -> Self {
8536        Self {
8537            features: if value.features.is_null() {
8538                None
8539            } else {
8540                Some(
8541                    unsafe {
8542                        std::slice::from_raw_parts(
8543                            value.features,
8544                            value.featureCount as usize,
8545                        )
8546                    }
8547                        .iter()
8548                        .map(|raw| WGSLLanguageFeatureName::from(*raw))
8549                        .collect(),
8550                )
8551            },
8552            _free_members: Some(value),
8553        }
8554    }
8555    pub(crate) fn free_members(value: ffi::WGPUSupportedWGSLLanguageFeatures) {
8556        unsafe { ffi::wgpuSupportedWGSLLanguageFeaturesFreeMembers(value) };
8557    }
8558}
8559impl Drop for SupportedWGSLLanguageFeatures {
8560    fn drop(&mut self) {
8561        if let Some(value) = self._free_members.take() {
8562            unsafe { ffi::wgpuSupportedWGSLLanguageFeaturesFreeMembers(value) };
8563        }
8564    }
8565}
8566pub struct SupportedFeatures {
8567    pub features: Option<Vec<FeatureName>>,
8568    #[doc(hidden)]
8569    pub(crate) _free_members: Option<ffi::WGPUSupportedFeatures>,
8570}
8571impl Default for SupportedFeatures {
8572    fn default() -> Self {
8573        Self {
8574            features: None,
8575            _free_members: None,
8576        }
8577    }
8578}
8579impl SupportedFeatures {
8580    pub fn new() -> Self {
8581        Self::default()
8582    }
8583    pub(crate) fn to_ffi(&self) -> (ffi::WGPUSupportedFeatures, ChainedStructStorage) {
8584        let mut storage = ChainedStructStorage::new();
8585        let mut raw: ffi::WGPUSupportedFeatures = unsafe { std::mem::zeroed() };
8586        raw.featureCount = self.features.as_ref().map(|v| v.len()).unwrap_or(0);
8587        if let Some(values) = &self.features {
8588            let len_value = values.len();
8589            let raw_vec: Vec<ffi::WGPUFeatureName> = values
8590                .iter()
8591                .map(|v| (*v).into())
8592                .collect();
8593            let ptr = storage.push_vec(raw_vec);
8594            raw.features = ptr;
8595            raw.featureCount = len_value;
8596        } else {
8597            raw.features = std::ptr::null();
8598            raw.featureCount = 0;
8599        }
8600        (raw, storage)
8601    }
8602    pub(crate) fn from_ffi(value: ffi::WGPUSupportedFeatures) -> Self {
8603        Self {
8604            features: if value.features.is_null() {
8605                None
8606            } else {
8607                Some(
8608                    unsafe {
8609                        std::slice::from_raw_parts(
8610                            value.features,
8611                            value.featureCount as usize,
8612                        )
8613                    }
8614                        .iter()
8615                        .map(|raw| FeatureName::from(*raw))
8616                        .collect(),
8617                )
8618            },
8619            _free_members: Some(value),
8620        }
8621    }
8622    pub(crate) fn free_members(value: ffi::WGPUSupportedFeatures) {
8623        unsafe { ffi::wgpuSupportedFeaturesFreeMembers(value) };
8624    }
8625}
8626impl Drop for SupportedFeatures {
8627    fn drop(&mut self) {
8628        if let Some(value) = self._free_members.take() {
8629            unsafe { ffi::wgpuSupportedFeaturesFreeMembers(value) };
8630        }
8631    }
8632}
8633pub struct SupportedInstanceFeatures {
8634    pub features: Option<Vec<InstanceFeatureName>>,
8635    #[doc(hidden)]
8636    pub(crate) _free_members: Option<ffi::WGPUSupportedInstanceFeatures>,
8637}
8638impl Default for SupportedInstanceFeatures {
8639    fn default() -> Self {
8640        Self {
8641            features: None,
8642            _free_members: None,
8643        }
8644    }
8645}
8646impl SupportedInstanceFeatures {
8647    pub fn new() -> Self {
8648        Self::default()
8649    }
8650    pub(crate) fn to_ffi(
8651        &self,
8652    ) -> (ffi::WGPUSupportedInstanceFeatures, ChainedStructStorage) {
8653        let mut storage = ChainedStructStorage::new();
8654        let mut raw: ffi::WGPUSupportedInstanceFeatures = unsafe { std::mem::zeroed() };
8655        raw.featureCount = self.features.as_ref().map(|v| v.len()).unwrap_or(0);
8656        if let Some(values) = &self.features {
8657            let len_value = values.len();
8658            let raw_vec: Vec<ffi::WGPUInstanceFeatureName> = values
8659                .iter()
8660                .map(|v| (*v).into())
8661                .collect();
8662            let ptr = storage.push_vec(raw_vec);
8663            raw.features = ptr;
8664            raw.featureCount = len_value;
8665        } else {
8666            raw.features = std::ptr::null();
8667            raw.featureCount = 0;
8668        }
8669        (raw, storage)
8670    }
8671    pub(crate) fn from_ffi(value: ffi::WGPUSupportedInstanceFeatures) -> Self {
8672        Self {
8673            features: if value.features.is_null() {
8674                None
8675            } else {
8676                Some(
8677                    unsafe {
8678                        std::slice::from_raw_parts(
8679                            value.features,
8680                            value.featureCount as usize,
8681                        )
8682                    }
8683                        .iter()
8684                        .map(|raw| InstanceFeatureName::from(*raw))
8685                        .collect(),
8686                )
8687            },
8688            _free_members: Some(value),
8689        }
8690    }
8691    pub(crate) fn free_members(value: ffi::WGPUSupportedInstanceFeatures) {
8692        unsafe { ffi::wgpuSupportedInstanceFeaturesFreeMembers(value) };
8693    }
8694}
8695impl Drop for SupportedInstanceFeatures {
8696    fn drop(&mut self) {
8697        if let Some(value) = self._free_members.take() {
8698            unsafe { ffi::wgpuSupportedInstanceFeaturesFreeMembers(value) };
8699        }
8700    }
8701}
8702pub struct SurfaceCapabilities {
8703    pub(crate) extensions: Vec<SurfaceCapabilitiesExtension>,
8704    pub usages: Option<TextureUsage>,
8705    pub formats: Option<Vec<TextureFormat>>,
8706    pub present_modes: Option<Vec<PresentMode>>,
8707    pub alpha_modes: Option<Vec<CompositeAlphaMode>>,
8708    #[doc(hidden)]
8709    pub(crate) _free_members: Option<ffi::WGPUSurfaceCapabilities>,
8710}
8711impl Default for SurfaceCapabilities {
8712    fn default() -> Self {
8713        Self {
8714            extensions: Vec::new(),
8715            usages: None,
8716            formats: None,
8717            present_modes: None,
8718            alpha_modes: None,
8719            _free_members: None,
8720        }
8721    }
8722}
8723impl SurfaceCapabilities {
8724    pub fn new() -> Self {
8725        Self::default()
8726    }
8727    pub(crate) fn to_ffi(&self) -> (ffi::WGPUSurfaceCapabilities, ChainedStructStorage) {
8728        let mut storage = ChainedStructStorage::new();
8729        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
8730        for ext in self.extensions.iter().rev() {
8731            next = ext.push_chain(&mut storage, next);
8732        }
8733        let mut raw: ffi::WGPUSurfaceCapabilities = unsafe { std::mem::zeroed() };
8734        raw.nextInChain = next;
8735        if let Some(value) = self.usages {
8736            raw.usages = value.into();
8737        } else {
8738            raw.usages = 0 as ffi::WGPUTextureUsage;
8739        }
8740        raw.formatCount = self.formats.as_ref().map(|v| v.len()).unwrap_or(0);
8741        if let Some(values) = &self.formats {
8742            let len_value = values.len();
8743            let raw_vec: Vec<ffi::WGPUTextureFormat> = values
8744                .iter()
8745                .map(|v| (*v).into())
8746                .collect();
8747            let ptr = storage.push_vec(raw_vec);
8748            raw.formats = ptr;
8749            raw.formatCount = len_value;
8750        } else {
8751            raw.formats = std::ptr::null();
8752            raw.formatCount = 0;
8753        }
8754        raw.presentModeCount = self.present_modes.as_ref().map(|v| v.len()).unwrap_or(0);
8755        if let Some(values) = &self.present_modes {
8756            let len_value = values.len();
8757            let raw_vec: Vec<ffi::WGPUPresentMode> = values
8758                .iter()
8759                .map(|v| (*v).into())
8760                .collect();
8761            let ptr = storage.push_vec(raw_vec);
8762            raw.presentModes = ptr;
8763            raw.presentModeCount = len_value;
8764        } else {
8765            raw.presentModes = std::ptr::null();
8766            raw.presentModeCount = 0;
8767        }
8768        raw.alphaModeCount = self.alpha_modes.as_ref().map(|v| v.len()).unwrap_or(0);
8769        if let Some(values) = &self.alpha_modes {
8770            let len_value = values.len();
8771            let raw_vec: Vec<ffi::WGPUCompositeAlphaMode> = values
8772                .iter()
8773                .map(|v| (*v).into())
8774                .collect();
8775            let ptr = storage.push_vec(raw_vec);
8776            raw.alphaModes = ptr;
8777            raw.alphaModeCount = len_value;
8778        } else {
8779            raw.alphaModes = std::ptr::null();
8780            raw.alphaModeCount = 0;
8781        }
8782        (raw, storage)
8783    }
8784    pub fn with_extension(mut self, extension: SurfaceCapabilitiesExtension) -> Self {
8785        self.extensions.push(extension);
8786        self
8787    }
8788    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceCapabilities) -> Self {
8789        Self {
8790            extensions: Vec::new(),
8791            usages: Some(value.usages.into()),
8792            formats: if value.formats.is_null() {
8793                None
8794            } else {
8795                Some(
8796                    unsafe {
8797                        std::slice::from_raw_parts(
8798                            value.formats,
8799                            value.formatCount as usize,
8800                        )
8801                    }
8802                        .iter()
8803                        .map(|raw| TextureFormat::from(*raw))
8804                        .collect(),
8805                )
8806            },
8807            present_modes: if value.presentModes.is_null() {
8808                None
8809            } else {
8810                Some(
8811                    unsafe {
8812                        std::slice::from_raw_parts(
8813                            value.presentModes,
8814                            value.presentModeCount as usize,
8815                        )
8816                    }
8817                        .iter()
8818                        .map(|raw| PresentMode::from(*raw))
8819                        .collect(),
8820                )
8821            },
8822            alpha_modes: if value.alphaModes.is_null() {
8823                None
8824            } else {
8825                Some(
8826                    unsafe {
8827                        std::slice::from_raw_parts(
8828                            value.alphaModes,
8829                            value.alphaModeCount as usize,
8830                        )
8831                    }
8832                        .iter()
8833                        .map(|raw| CompositeAlphaMode::from(*raw))
8834                        .collect(),
8835                )
8836            },
8837            _free_members: Some(value),
8838        }
8839    }
8840    pub(crate) fn free_members(value: ffi::WGPUSurfaceCapabilities) {
8841        unsafe { ffi::wgpuSurfaceCapabilitiesFreeMembers(value) };
8842    }
8843}
8844impl Drop for SurfaceCapabilities {
8845    fn drop(&mut self) {
8846        if let Some(value) = self._free_members.take() {
8847            unsafe { ffi::wgpuSurfaceCapabilitiesFreeMembers(value) };
8848        }
8849    }
8850}
8851pub struct SurfaceColorManagement {
8852    pub color_space: Option<PredefinedColorSpace>,
8853    pub tone_mapping_mode: Option<ToneMappingMode>,
8854}
8855impl Default for SurfaceColorManagement {
8856    fn default() -> Self {
8857        Self {
8858            color_space: None,
8859            tone_mapping_mode: None,
8860        }
8861    }
8862}
8863impl SurfaceColorManagement {
8864    pub fn new() -> Self {
8865        Self::default()
8866    }
8867    pub(crate) fn to_ffi(
8868        &self,
8869    ) -> (ffi::WGPUSurfaceColorManagement, ChainedStructStorage) {
8870        let mut storage = ChainedStructStorage::new();
8871        let mut raw: ffi::WGPUSurfaceColorManagement = unsafe { std::mem::zeroed() };
8872        if let Some(value) = self.color_space {
8873            raw.colorSpace = value.into();
8874        } else {
8875            raw.colorSpace = 0 as ffi::WGPUPredefinedColorSpace;
8876        }
8877        if let Some(value) = self.tone_mapping_mode {
8878            raw.toneMappingMode = value.into();
8879        } else {
8880            raw.toneMappingMode = 0 as ffi::WGPUToneMappingMode;
8881        }
8882        (raw, storage)
8883    }
8884    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceColorManagement) -> Self {
8885        Self {
8886            color_space: Some(value.colorSpace.into()),
8887            tone_mapping_mode: Some(value.toneMappingMode.into()),
8888        }
8889    }
8890}
8891pub struct SurfaceConfiguration {
8892    pub(crate) extensions: Vec<SurfaceConfigurationExtension>,
8893    pub device: Option<Device>,
8894    pub format: Option<TextureFormat>,
8895    pub usage: Option<TextureUsage>,
8896    pub width: Option<u32>,
8897    pub height: Option<u32>,
8898    pub view_formats: Option<Vec<TextureFormat>>,
8899    pub alpha_mode: Option<CompositeAlphaMode>,
8900    pub present_mode: Option<PresentMode>,
8901}
8902impl Default for SurfaceConfiguration {
8903    fn default() -> Self {
8904        Self {
8905            extensions: Vec::new(),
8906            device: None,
8907            format: None,
8908            usage: Some(TextureUsage::RENDER_ATTACHMENT),
8909            width: None,
8910            height: None,
8911            view_formats: None,
8912            alpha_mode: Some(CompositeAlphaMode::Auto),
8913            present_mode: Some(PresentMode::Fifo),
8914        }
8915    }
8916}
8917impl SurfaceConfiguration {
8918    pub fn new() -> Self {
8919        Self::default()
8920    }
8921    pub(crate) fn to_ffi(
8922        &self,
8923    ) -> (ffi::WGPUSurfaceConfiguration, ChainedStructStorage) {
8924        let mut storage = ChainedStructStorage::new();
8925        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
8926        for ext in self.extensions.iter().rev() {
8927            next = ext.push_chain(&mut storage, next);
8928        }
8929        let mut raw: ffi::WGPUSurfaceConfiguration = unsafe { std::mem::zeroed() };
8930        raw.nextInChain = next;
8931        raw.device = self
8932            .device
8933            .as_ref()
8934            .map(|v| v.as_raw())
8935            .unwrap_or(std::ptr::null_mut());
8936        if let Some(value) = self.format {
8937            raw.format = value.into();
8938        } else {
8939            raw.format = 0 as ffi::WGPUTextureFormat;
8940        }
8941        if let Some(value) = self.usage {
8942            raw.usage = value.into();
8943        } else {
8944            raw.usage = 0 as ffi::WGPUTextureUsage;
8945        }
8946        if let Some(value) = self.width {
8947            raw.width = value;
8948        }
8949        if let Some(value) = self.height {
8950            raw.height = value;
8951        }
8952        raw.viewFormatCount = self.view_formats.as_ref().map(|v| v.len()).unwrap_or(0);
8953        if let Some(values) = &self.view_formats {
8954            let len_value = values.len();
8955            let raw_vec: Vec<ffi::WGPUTextureFormat> = values
8956                .iter()
8957                .map(|v| (*v).into())
8958                .collect();
8959            let ptr = storage.push_vec(raw_vec);
8960            raw.viewFormats = ptr;
8961            raw.viewFormatCount = len_value;
8962        } else {
8963            raw.viewFormats = std::ptr::null();
8964            raw.viewFormatCount = 0;
8965        }
8966        if let Some(value) = self.alpha_mode {
8967            raw.alphaMode = value.into();
8968        } else {
8969            raw.alphaMode = 0 as ffi::WGPUCompositeAlphaMode;
8970        }
8971        if let Some(value) = self.present_mode {
8972            raw.presentMode = value.into();
8973        } else {
8974            raw.presentMode = 0 as ffi::WGPUPresentMode;
8975        }
8976        (raw, storage)
8977    }
8978    pub fn with_extension(mut self, extension: SurfaceConfigurationExtension) -> Self {
8979        self.extensions.push(extension);
8980        self
8981    }
8982    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceConfiguration) -> Self {
8983        Self {
8984            extensions: Vec::new(),
8985            device: Some(unsafe { Device::from_raw(value.device) }),
8986            format: Some(value.format.into()),
8987            usage: Some(value.usage.into()),
8988            width: Some(value.width),
8989            height: Some(value.height),
8990            view_formats: if value.viewFormats.is_null() {
8991                None
8992            } else {
8993                Some(
8994                    unsafe {
8995                        std::slice::from_raw_parts(
8996                            value.viewFormats,
8997                            value.viewFormatCount as usize,
8998                        )
8999                    }
9000                        .iter()
9001                        .map(|raw| TextureFormat::from(*raw))
9002                        .collect(),
9003                )
9004            },
9005            alpha_mode: Some(value.alphaMode.into()),
9006            present_mode: Some(value.presentMode.into()),
9007        }
9008    }
9009}
9010pub struct SurfaceDescriptor {
9011    pub(crate) extensions: Vec<SurfaceDescriptorExtension>,
9012    pub label: Option<String>,
9013}
9014impl Default for SurfaceDescriptor {
9015    fn default() -> Self {
9016        Self {
9017            extensions: Vec::new(),
9018            label: None,
9019        }
9020    }
9021}
9022impl SurfaceDescriptor {
9023    pub fn new() -> Self {
9024        Self::default()
9025    }
9026    pub(crate) fn to_ffi(&self) -> (ffi::WGPUSurfaceDescriptor, ChainedStructStorage) {
9027        let mut storage = ChainedStructStorage::new();
9028        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
9029        for ext in self.extensions.iter().rev() {
9030            next = ext.push_chain(&mut storage, next);
9031        }
9032        let mut raw: ffi::WGPUSurfaceDescriptor = unsafe { std::mem::zeroed() };
9033        raw.nextInChain = next;
9034        if let Some(value) = &self.label {
9035            raw.label = ffi::WGPUStringView {
9036                data: value.as_ptr().cast(),
9037                length: value.len(),
9038            };
9039        } else {
9040            raw.label = ffi::WGPUStringView {
9041                data: std::ptr::null(),
9042                length: 0,
9043            };
9044        }
9045        (raw, storage)
9046    }
9047    pub fn with_extension(mut self, extension: SurfaceDescriptorExtension) -> Self {
9048        self.extensions.push(extension);
9049        self
9050    }
9051    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceDescriptor) -> Self {
9052        Self {
9053            extensions: Vec::new(),
9054            label: if value.label.data.is_null() || value.label.length == 0 {
9055                None
9056            } else {
9057                Some(string_view_to_string(value.label))
9058            },
9059        }
9060    }
9061}
9062pub struct SurfaceDescriptorFromWindowsUWPSwapChainPanel {
9063    pub swap_chain_panel: Option<*mut std::ffi::c_void>,
9064}
9065impl Default for SurfaceDescriptorFromWindowsUWPSwapChainPanel {
9066    fn default() -> Self {
9067        Self { swap_chain_panel: None }
9068    }
9069}
9070impl SurfaceDescriptorFromWindowsUWPSwapChainPanel {
9071    pub fn new() -> Self {
9072        Self::default()
9073    }
9074    pub(crate) fn to_ffi(
9075        &self,
9076    ) -> (ffi::WGPUSurfaceDescriptorFromWindowsUWPSwapChainPanel, ChainedStructStorage) {
9077        let mut storage = ChainedStructStorage::new();
9078        let mut raw: ffi::WGPUSurfaceDescriptorFromWindowsUWPSwapChainPanel = unsafe {
9079            std::mem::zeroed()
9080        };
9081        if let Some(value) = self.swap_chain_panel {
9082            raw.swapChainPanel = value;
9083        }
9084        (raw, storage)
9085    }
9086    pub(crate) fn from_ffi(
9087        value: ffi::WGPUSurfaceDescriptorFromWindowsUWPSwapChainPanel,
9088    ) -> Self {
9089        Self {
9090            swap_chain_panel: Some(value.swapChainPanel),
9091        }
9092    }
9093}
9094pub struct SurfaceDescriptorFromWindowsWinUISwapChainPanel {
9095    pub swap_chain_panel: Option<*mut std::ffi::c_void>,
9096}
9097impl Default for SurfaceDescriptorFromWindowsWinUISwapChainPanel {
9098    fn default() -> Self {
9099        Self { swap_chain_panel: None }
9100    }
9101}
9102impl SurfaceDescriptorFromWindowsWinUISwapChainPanel {
9103    pub fn new() -> Self {
9104        Self::default()
9105    }
9106    pub(crate) fn to_ffi(
9107        &self,
9108    ) -> (
9109        ffi::WGPUSurfaceDescriptorFromWindowsWinUISwapChainPanel,
9110        ChainedStructStorage,
9111    ) {
9112        let mut storage = ChainedStructStorage::new();
9113        let mut raw: ffi::WGPUSurfaceDescriptorFromWindowsWinUISwapChainPanel = unsafe {
9114            std::mem::zeroed()
9115        };
9116        if let Some(value) = self.swap_chain_panel {
9117            raw.swapChainPanel = value;
9118        }
9119        (raw, storage)
9120    }
9121    pub(crate) fn from_ffi(
9122        value: ffi::WGPUSurfaceDescriptorFromWindowsWinUISwapChainPanel,
9123    ) -> Self {
9124        Self {
9125            swap_chain_panel: Some(value.swapChainPanel),
9126        }
9127    }
9128}
9129pub struct SurfaceDescriptorFromWindowsCoreWindow {
9130    pub core_window: Option<*mut std::ffi::c_void>,
9131}
9132impl Default for SurfaceDescriptorFromWindowsCoreWindow {
9133    fn default() -> Self {
9134        Self { core_window: None }
9135    }
9136}
9137impl SurfaceDescriptorFromWindowsCoreWindow {
9138    pub fn new() -> Self {
9139        Self::default()
9140    }
9141    pub(crate) fn to_ffi(
9142        &self,
9143    ) -> (ffi::WGPUSurfaceDescriptorFromWindowsCoreWindow, ChainedStructStorage) {
9144        let mut storage = ChainedStructStorage::new();
9145        let mut raw: ffi::WGPUSurfaceDescriptorFromWindowsCoreWindow = unsafe {
9146            std::mem::zeroed()
9147        };
9148        if let Some(value) = self.core_window {
9149            raw.coreWindow = value;
9150        }
9151        (raw, storage)
9152    }
9153    pub(crate) fn from_ffi(
9154        value: ffi::WGPUSurfaceDescriptorFromWindowsCoreWindow,
9155    ) -> Self {
9156        Self {
9157            core_window: Some(value.coreWindow),
9158        }
9159    }
9160}
9161pub struct SurfaceSourceXCBWindow {
9162    pub connection: Option<*mut std::ffi::c_void>,
9163    pub window: Option<u32>,
9164}
9165impl Default for SurfaceSourceXCBWindow {
9166    fn default() -> Self {
9167        Self {
9168            connection: None,
9169            window: None,
9170        }
9171    }
9172}
9173impl SurfaceSourceXCBWindow {
9174    pub fn new() -> Self {
9175        Self::default()
9176    }
9177    pub(crate) fn to_ffi(
9178        &self,
9179    ) -> (ffi::WGPUSurfaceSourceXCBWindow, ChainedStructStorage) {
9180        let mut storage = ChainedStructStorage::new();
9181        let mut raw: ffi::WGPUSurfaceSourceXCBWindow = unsafe { std::mem::zeroed() };
9182        if let Some(value) = self.connection {
9183            raw.connection = value;
9184        }
9185        if let Some(value) = self.window {
9186            raw.window = value;
9187        }
9188        (raw, storage)
9189    }
9190    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceSourceXCBWindow) -> Self {
9191        Self {
9192            connection: Some(value.connection),
9193            window: Some(value.window),
9194        }
9195    }
9196}
9197pub struct SurfaceSourceAndroidNativeWindow {
9198    pub window: Option<*mut std::ffi::c_void>,
9199}
9200impl Default for SurfaceSourceAndroidNativeWindow {
9201    fn default() -> Self {
9202        Self { window: None }
9203    }
9204}
9205impl SurfaceSourceAndroidNativeWindow {
9206    pub fn new() -> Self {
9207        Self::default()
9208    }
9209    pub(crate) fn to_ffi(
9210        &self,
9211    ) -> (ffi::WGPUSurfaceSourceAndroidNativeWindow, ChainedStructStorage) {
9212        let mut storage = ChainedStructStorage::new();
9213        let mut raw: ffi::WGPUSurfaceSourceAndroidNativeWindow = unsafe {
9214            std::mem::zeroed()
9215        };
9216        if let Some(value) = self.window {
9217            raw.window = value;
9218        }
9219        (raw, storage)
9220    }
9221    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceSourceAndroidNativeWindow) -> Self {
9222        Self { window: Some(value.window) }
9223    }
9224}
9225pub struct SurfaceSourceMetalLayer {
9226    pub layer: Option<*mut std::ffi::c_void>,
9227}
9228impl Default for SurfaceSourceMetalLayer {
9229    fn default() -> Self {
9230        Self { layer: None }
9231    }
9232}
9233impl SurfaceSourceMetalLayer {
9234    pub fn new() -> Self {
9235        Self::default()
9236    }
9237    pub(crate) fn to_ffi(
9238        &self,
9239    ) -> (ffi::WGPUSurfaceSourceMetalLayer, ChainedStructStorage) {
9240        let mut storage = ChainedStructStorage::new();
9241        let mut raw: ffi::WGPUSurfaceSourceMetalLayer = unsafe { std::mem::zeroed() };
9242        if let Some(value) = self.layer {
9243            raw.layer = value;
9244        }
9245        (raw, storage)
9246    }
9247    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceSourceMetalLayer) -> Self {
9248        Self { layer: Some(value.layer) }
9249    }
9250}
9251pub struct SurfaceSourceWaylandSurface {
9252    pub display: Option<*mut std::ffi::c_void>,
9253    pub surface: Option<*mut std::ffi::c_void>,
9254}
9255impl Default for SurfaceSourceWaylandSurface {
9256    fn default() -> Self {
9257        Self {
9258            display: None,
9259            surface: None,
9260        }
9261    }
9262}
9263impl SurfaceSourceWaylandSurface {
9264    pub fn new() -> Self {
9265        Self::default()
9266    }
9267    pub(crate) fn to_ffi(
9268        &self,
9269    ) -> (ffi::WGPUSurfaceSourceWaylandSurface, ChainedStructStorage) {
9270        let mut storage = ChainedStructStorage::new();
9271        let mut raw: ffi::WGPUSurfaceSourceWaylandSurface = unsafe {
9272            std::mem::zeroed()
9273        };
9274        if let Some(value) = self.display {
9275            raw.display = value;
9276        }
9277        if let Some(value) = self.surface {
9278            raw.surface = value;
9279        }
9280        (raw, storage)
9281    }
9282    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceSourceWaylandSurface) -> Self {
9283        Self {
9284            display: Some(value.display),
9285            surface: Some(value.surface),
9286        }
9287    }
9288}
9289pub struct SurfaceSourceWindowsHWND {
9290    pub hinstance: Option<*mut std::ffi::c_void>,
9291    pub hwnd: Option<*mut std::ffi::c_void>,
9292}
9293impl Default for SurfaceSourceWindowsHWND {
9294    fn default() -> Self {
9295        Self {
9296            hinstance: None,
9297            hwnd: None,
9298        }
9299    }
9300}
9301impl SurfaceSourceWindowsHWND {
9302    pub fn new() -> Self {
9303        Self::default()
9304    }
9305    pub(crate) fn to_ffi(
9306        &self,
9307    ) -> (ffi::WGPUSurfaceSourceWindowsHWND, ChainedStructStorage) {
9308        let mut storage = ChainedStructStorage::new();
9309        let mut raw: ffi::WGPUSurfaceSourceWindowsHWND = unsafe { std::mem::zeroed() };
9310        if let Some(value) = self.hinstance {
9311            raw.hinstance = value;
9312        }
9313        if let Some(value) = self.hwnd {
9314            raw.hwnd = value;
9315        }
9316        (raw, storage)
9317    }
9318    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceSourceWindowsHWND) -> Self {
9319        Self {
9320            hinstance: Some(value.hinstance),
9321            hwnd: Some(value.hwnd),
9322        }
9323    }
9324}
9325pub struct SurfaceSourceXlibWindow {
9326    pub display: Option<*mut std::ffi::c_void>,
9327    pub window: Option<u64>,
9328}
9329impl Default for SurfaceSourceXlibWindow {
9330    fn default() -> Self {
9331        Self {
9332            display: None,
9333            window: None,
9334        }
9335    }
9336}
9337impl SurfaceSourceXlibWindow {
9338    pub fn new() -> Self {
9339        Self::default()
9340    }
9341    pub(crate) fn to_ffi(
9342        &self,
9343    ) -> (ffi::WGPUSurfaceSourceXlibWindow, ChainedStructStorage) {
9344        let mut storage = ChainedStructStorage::new();
9345        let mut raw: ffi::WGPUSurfaceSourceXlibWindow = unsafe { std::mem::zeroed() };
9346        if let Some(value) = self.display {
9347            raw.display = value;
9348        }
9349        if let Some(value) = self.window {
9350            raw.window = value;
9351        }
9352        (raw, storage)
9353    }
9354    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceSourceXlibWindow) -> Self {
9355        Self {
9356            display: Some(value.display),
9357            window: Some(value.window),
9358        }
9359    }
9360}
9361pub struct SurfaceTexture {
9362    pub(crate) extensions: Vec<SurfaceTextureExtension>,
9363    pub texture: Option<Texture>,
9364    pub status: Option<SurfaceGetCurrentTextureStatus>,
9365}
9366impl Default for SurfaceTexture {
9367    fn default() -> Self {
9368        Self {
9369            extensions: Vec::new(),
9370            texture: None,
9371            status: None,
9372        }
9373    }
9374}
9375impl SurfaceTexture {
9376    pub fn new() -> Self {
9377        Self::default()
9378    }
9379    pub(crate) fn to_ffi(&self) -> (ffi::WGPUSurfaceTexture, ChainedStructStorage) {
9380        let mut storage = ChainedStructStorage::new();
9381        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
9382        for ext in self.extensions.iter().rev() {
9383            next = ext.push_chain(&mut storage, next);
9384        }
9385        let mut raw: ffi::WGPUSurfaceTexture = unsafe { std::mem::zeroed() };
9386        raw.nextInChain = next;
9387        raw.texture = self
9388            .texture
9389            .as_ref()
9390            .map(|v| v.as_raw())
9391            .unwrap_or(std::ptr::null_mut());
9392        if let Some(value) = self.status {
9393            raw.status = value.into();
9394        } else {
9395            raw.status = 0 as ffi::WGPUSurfaceGetCurrentTextureStatus;
9396        }
9397        (raw, storage)
9398    }
9399    pub fn with_extension(mut self, extension: SurfaceTextureExtension) -> Self {
9400        self.extensions.push(extension);
9401        self
9402    }
9403    pub(crate) fn from_ffi(value: ffi::WGPUSurfaceTexture) -> Self {
9404        Self {
9405            extensions: Vec::new(),
9406            texture: Some(unsafe { Texture::from_raw(value.texture) }),
9407            status: Some(value.status.into()),
9408        }
9409    }
9410}
9411pub struct TexelBufferBindingEntry {
9412    pub texel_buffer_view: Option<TexelBufferView>,
9413}
9414impl Default for TexelBufferBindingEntry {
9415    fn default() -> Self {
9416        Self { texel_buffer_view: None }
9417    }
9418}
9419impl TexelBufferBindingEntry {
9420    pub fn new() -> Self {
9421        Self::default()
9422    }
9423    pub(crate) fn to_ffi(
9424        &self,
9425    ) -> (ffi::WGPUTexelBufferBindingEntry, ChainedStructStorage) {
9426        let mut storage = ChainedStructStorage::new();
9427        let mut raw: ffi::WGPUTexelBufferBindingEntry = unsafe { std::mem::zeroed() };
9428        raw.texelBufferView = self
9429            .texel_buffer_view
9430            .as_ref()
9431            .map(|v| v.as_raw())
9432            .unwrap_or(std::ptr::null_mut());
9433        (raw, storage)
9434    }
9435    pub(crate) fn from_ffi(value: ffi::WGPUTexelBufferBindingEntry) -> Self {
9436        Self {
9437            texel_buffer_view: Some(unsafe {
9438                TexelBufferView::from_raw(value.texelBufferView)
9439            }),
9440        }
9441    }
9442}
9443pub struct TexelBufferBindingLayout {
9444    pub access: Option<TexelBufferAccess>,
9445    pub format: Option<TextureFormat>,
9446}
9447impl Default for TexelBufferBindingLayout {
9448    fn default() -> Self {
9449        Self {
9450            access: Some(TexelBufferAccess::ReadWrite),
9451            format: None,
9452        }
9453    }
9454}
9455impl TexelBufferBindingLayout {
9456    pub fn new() -> Self {
9457        Self::default()
9458    }
9459    pub(crate) fn to_ffi(
9460        &self,
9461    ) -> (ffi::WGPUTexelBufferBindingLayout, ChainedStructStorage) {
9462        let mut storage = ChainedStructStorage::new();
9463        let mut raw: ffi::WGPUTexelBufferBindingLayout = unsafe { std::mem::zeroed() };
9464        if let Some(value) = self.access {
9465            raw.access = value.into();
9466        } else {
9467            raw.access = 0 as ffi::WGPUTexelBufferAccess;
9468        }
9469        if let Some(value) = self.format {
9470            raw.format = value.into();
9471        } else {
9472            raw.format = 0 as ffi::WGPUTextureFormat;
9473        }
9474        (raw, storage)
9475    }
9476    pub(crate) fn from_ffi(value: ffi::WGPUTexelBufferBindingLayout) -> Self {
9477        Self {
9478            access: Some(value.access.into()),
9479            format: Some(value.format.into()),
9480        }
9481    }
9482}
9483pub struct TexelBufferViewDescriptor {
9484    pub(crate) extensions: Vec<TexelBufferViewDescriptorExtension>,
9485    pub label: Option<String>,
9486    pub format: Option<TextureFormat>,
9487    pub offset: Option<u64>,
9488    pub size: Option<u64>,
9489}
9490impl Default for TexelBufferViewDescriptor {
9491    fn default() -> Self {
9492        Self {
9493            extensions: Vec::new(),
9494            label: None,
9495            format: None,
9496            offset: Some(0),
9497            size: Some(WHOLE_SIZE),
9498        }
9499    }
9500}
9501impl TexelBufferViewDescriptor {
9502    pub fn new() -> Self {
9503        Self::default()
9504    }
9505    pub(crate) fn to_ffi(
9506        &self,
9507    ) -> (ffi::WGPUTexelBufferViewDescriptor, ChainedStructStorage) {
9508        let mut storage = ChainedStructStorage::new();
9509        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
9510        for ext in self.extensions.iter().rev() {
9511            next = ext.push_chain(&mut storage, next);
9512        }
9513        let mut raw: ffi::WGPUTexelBufferViewDescriptor = unsafe { std::mem::zeroed() };
9514        raw.nextInChain = next;
9515        if let Some(value) = &self.label {
9516            raw.label = ffi::WGPUStringView {
9517                data: value.as_ptr().cast(),
9518                length: value.len(),
9519            };
9520        } else {
9521            raw.label = ffi::WGPUStringView {
9522                data: std::ptr::null(),
9523                length: 0,
9524            };
9525        }
9526        if let Some(value) = self.format {
9527            raw.format = value.into();
9528        } else {
9529            raw.format = 0 as ffi::WGPUTextureFormat;
9530        }
9531        if let Some(value) = self.offset {
9532            raw.offset = value;
9533        }
9534        if let Some(value) = self.size {
9535            raw.size = value;
9536        }
9537        (raw, storage)
9538    }
9539    pub fn with_extension(
9540        mut self,
9541        extension: TexelBufferViewDescriptorExtension,
9542    ) -> Self {
9543        self.extensions.push(extension);
9544        self
9545    }
9546    pub(crate) fn from_ffi(value: ffi::WGPUTexelBufferViewDescriptor) -> Self {
9547        Self {
9548            extensions: Vec::new(),
9549            label: if value.label.data.is_null() || value.label.length == 0 {
9550                None
9551            } else {
9552                Some(string_view_to_string(value.label))
9553            },
9554            format: Some(value.format.into()),
9555            offset: Some(value.offset),
9556            size: Some(value.size),
9557        }
9558    }
9559}
9560pub struct TexelCopyBufferInfo {
9561    pub layout: Option<TexelCopyBufferLayout>,
9562    pub buffer: Option<Buffer>,
9563}
9564impl Default for TexelCopyBufferInfo {
9565    fn default() -> Self {
9566        Self { layout: None, buffer: None }
9567    }
9568}
9569impl TexelCopyBufferInfo {
9570    pub fn new() -> Self {
9571        Self::default()
9572    }
9573    pub(crate) fn to_ffi(&self) -> (ffi::WGPUTexelCopyBufferInfo, ChainedStructStorage) {
9574        let mut storage = ChainedStructStorage::new();
9575        let mut raw: ffi::WGPUTexelCopyBufferInfo = unsafe { std::mem::zeroed() };
9576        if let Some(value) = &self.layout {
9577            let (raw_value, storage_value) = value.to_ffi();
9578            raw.layout = raw_value;
9579            storage.push_storage(storage_value);
9580        }
9581        raw.buffer = self
9582            .buffer
9583            .as_ref()
9584            .map(|v| v.as_raw())
9585            .unwrap_or(std::ptr::null_mut());
9586        (raw, storage)
9587    }
9588    pub(crate) fn from_ffi(value: ffi::WGPUTexelCopyBufferInfo) -> Self {
9589        Self {
9590            layout: Some(TexelCopyBufferLayout::from_ffi(value.layout)),
9591            buffer: Some(unsafe { Buffer::from_raw(value.buffer) }),
9592        }
9593    }
9594}
9595pub struct TexelCopyBufferLayout {
9596    pub offset: Option<u64>,
9597    pub bytes_per_row: Option<u32>,
9598    pub rows_per_image: Option<u32>,
9599}
9600impl Default for TexelCopyBufferLayout {
9601    fn default() -> Self {
9602        Self {
9603            offset: Some(0),
9604            bytes_per_row: Some(COPY_STRIDE_UNDEFINED),
9605            rows_per_image: Some(COPY_STRIDE_UNDEFINED),
9606        }
9607    }
9608}
9609impl TexelCopyBufferLayout {
9610    pub fn new() -> Self {
9611        Self::default()
9612    }
9613    pub(crate) fn to_ffi(
9614        &self,
9615    ) -> (ffi::WGPUTexelCopyBufferLayout, ChainedStructStorage) {
9616        let mut storage = ChainedStructStorage::new();
9617        let mut raw: ffi::WGPUTexelCopyBufferLayout = unsafe { std::mem::zeroed() };
9618        if let Some(value) = self.offset {
9619            raw.offset = value;
9620        }
9621        if let Some(value) = self.bytes_per_row {
9622            raw.bytesPerRow = value;
9623        }
9624        if let Some(value) = self.rows_per_image {
9625            raw.rowsPerImage = value;
9626        }
9627        (raw, storage)
9628    }
9629    pub(crate) fn from_ffi(value: ffi::WGPUTexelCopyBufferLayout) -> Self {
9630        Self {
9631            offset: Some(value.offset),
9632            bytes_per_row: Some(value.bytesPerRow),
9633            rows_per_image: Some(value.rowsPerImage),
9634        }
9635    }
9636}
9637pub struct TexelCopyTextureInfo {
9638    pub texture: Option<Texture>,
9639    pub mip_level: Option<u32>,
9640    pub origin: Option<Origin3D>,
9641    pub aspect: Option<TextureAspect>,
9642}
9643impl Default for TexelCopyTextureInfo {
9644    fn default() -> Self {
9645        Self {
9646            texture: None,
9647            mip_level: Some(0),
9648            origin: None,
9649            aspect: Some(TextureAspect::All),
9650        }
9651    }
9652}
9653impl TexelCopyTextureInfo {
9654    pub fn new() -> Self {
9655        Self::default()
9656    }
9657    pub(crate) fn to_ffi(
9658        &self,
9659    ) -> (ffi::WGPUTexelCopyTextureInfo, ChainedStructStorage) {
9660        let mut storage = ChainedStructStorage::new();
9661        let mut raw: ffi::WGPUTexelCopyTextureInfo = unsafe { std::mem::zeroed() };
9662        raw.texture = self
9663            .texture
9664            .as_ref()
9665            .map(|v| v.as_raw())
9666            .unwrap_or(std::ptr::null_mut());
9667        if let Some(value) = self.mip_level {
9668            raw.mipLevel = value;
9669        }
9670        if let Some(value) = &self.origin {
9671            let (raw_value, storage_value) = value.to_ffi();
9672            raw.origin = raw_value;
9673            storage.push_storage(storage_value);
9674        }
9675        if let Some(value) = self.aspect {
9676            raw.aspect = value.into();
9677        } else {
9678            raw.aspect = 0 as ffi::WGPUTextureAspect;
9679        }
9680        (raw, storage)
9681    }
9682    pub(crate) fn from_ffi(value: ffi::WGPUTexelCopyTextureInfo) -> Self {
9683        Self {
9684            texture: Some(unsafe { Texture::from_raw(value.texture) }),
9685            mip_level: Some(value.mipLevel),
9686            origin: Some(Origin3D::from_ffi(value.origin)),
9687            aspect: Some(value.aspect.into()),
9688        }
9689    }
9690}
9691pub struct TextureBindingLayout {
9692    pub(crate) extensions: Vec<TextureBindingLayoutExtension>,
9693    pub sample_type: Option<TextureSampleType>,
9694    pub view_dimension: Option<TextureViewDimension>,
9695    pub multisampled: Option<bool>,
9696}
9697impl Default for TextureBindingLayout {
9698    fn default() -> Self {
9699        Self {
9700            extensions: Vec::new(),
9701            sample_type: Some(TextureSampleType::Float),
9702            view_dimension: Some(TextureViewDimension::D2),
9703            multisampled: None,
9704        }
9705    }
9706}
9707impl TextureBindingLayout {
9708    pub fn new() -> Self {
9709        Self::default()
9710    }
9711    pub(crate) fn to_ffi(
9712        &self,
9713    ) -> (ffi::WGPUTextureBindingLayout, ChainedStructStorage) {
9714        let mut storage = ChainedStructStorage::new();
9715        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
9716        for ext in self.extensions.iter().rev() {
9717            next = ext.push_chain(&mut storage, next);
9718        }
9719        let mut raw: ffi::WGPUTextureBindingLayout = unsafe { std::mem::zeroed() };
9720        raw.nextInChain = next;
9721        if let Some(value) = self.sample_type {
9722            raw.sampleType = value.into();
9723        } else {
9724            raw.sampleType = 0 as ffi::WGPUTextureSampleType;
9725        }
9726        if let Some(value) = self.view_dimension {
9727            raw.viewDimension = value.into();
9728        } else {
9729            raw.viewDimension = 0 as ffi::WGPUTextureViewDimension;
9730        }
9731        raw.multisampled = if self.multisampled.unwrap_or(false) { 1 } else { 0 };
9732        (raw, storage)
9733    }
9734    pub fn with_extension(mut self, extension: TextureBindingLayoutExtension) -> Self {
9735        self.extensions.push(extension);
9736        self
9737    }
9738    pub(crate) fn from_ffi(value: ffi::WGPUTextureBindingLayout) -> Self {
9739        Self {
9740            extensions: Vec::new(),
9741            sample_type: Some(value.sampleType.into()),
9742            view_dimension: Some(value.viewDimension.into()),
9743            multisampled: Some(value.multisampled != 0),
9744        }
9745    }
9746}
9747pub struct TextureBindingViewDimensionDescriptor {
9748    pub texture_binding_view_dimension: Option<TextureViewDimension>,
9749}
9750impl Default for TextureBindingViewDimensionDescriptor {
9751    fn default() -> Self {
9752        Self {
9753            texture_binding_view_dimension: None,
9754        }
9755    }
9756}
9757impl TextureBindingViewDimensionDescriptor {
9758    pub fn new() -> Self {
9759        Self::default()
9760    }
9761    pub(crate) fn to_ffi(
9762        &self,
9763    ) -> (ffi::WGPUTextureBindingViewDimensionDescriptor, ChainedStructStorage) {
9764        let mut storage = ChainedStructStorage::new();
9765        let mut raw: ffi::WGPUTextureBindingViewDimensionDescriptor = unsafe {
9766            std::mem::zeroed()
9767        };
9768        if let Some(value) = self.texture_binding_view_dimension {
9769            raw.textureBindingViewDimension = value.into();
9770        } else {
9771            raw.textureBindingViewDimension = 0 as ffi::WGPUTextureViewDimension;
9772        }
9773        (raw, storage)
9774    }
9775    pub(crate) fn from_ffi(
9776        value: ffi::WGPUTextureBindingViewDimensionDescriptor,
9777    ) -> Self {
9778        Self {
9779            texture_binding_view_dimension: Some(
9780                value.textureBindingViewDimension.into(),
9781            ),
9782        }
9783    }
9784}
9785pub struct TextureComponentSwizzle {
9786    pub r: Option<ComponentSwizzle>,
9787    pub g: Option<ComponentSwizzle>,
9788    pub b: Option<ComponentSwizzle>,
9789    pub a: Option<ComponentSwizzle>,
9790}
9791impl Default for TextureComponentSwizzle {
9792    fn default() -> Self {
9793        Self {
9794            r: Some(ComponentSwizzle::R),
9795            g: Some(ComponentSwizzle::G),
9796            b: Some(ComponentSwizzle::B),
9797            a: Some(ComponentSwizzle::A),
9798        }
9799    }
9800}
9801impl TextureComponentSwizzle {
9802    pub fn new() -> Self {
9803        Self::default()
9804    }
9805    pub(crate) fn to_ffi(
9806        &self,
9807    ) -> (ffi::WGPUTextureComponentSwizzle, ChainedStructStorage) {
9808        let mut storage = ChainedStructStorage::new();
9809        let mut raw: ffi::WGPUTextureComponentSwizzle = unsafe { std::mem::zeroed() };
9810        if let Some(value) = self.r {
9811            raw.r = value.into();
9812        } else {
9813            raw.r = 0 as ffi::WGPUComponentSwizzle;
9814        }
9815        if let Some(value) = self.g {
9816            raw.g = value.into();
9817        } else {
9818            raw.g = 0 as ffi::WGPUComponentSwizzle;
9819        }
9820        if let Some(value) = self.b {
9821            raw.b = value.into();
9822        } else {
9823            raw.b = 0 as ffi::WGPUComponentSwizzle;
9824        }
9825        if let Some(value) = self.a {
9826            raw.a = value.into();
9827        } else {
9828            raw.a = 0 as ffi::WGPUComponentSwizzle;
9829        }
9830        (raw, storage)
9831    }
9832    pub(crate) fn from_ffi(value: ffi::WGPUTextureComponentSwizzle) -> Self {
9833        Self {
9834            r: Some(value.r.into()),
9835            g: Some(value.g.into()),
9836            b: Some(value.b.into()),
9837            a: Some(value.a.into()),
9838        }
9839    }
9840}
9841pub struct TextureComponentSwizzleDescriptor {
9842    pub swizzle: Option<TextureComponentSwizzle>,
9843}
9844impl Default for TextureComponentSwizzleDescriptor {
9845    fn default() -> Self {
9846        Self { swizzle: None }
9847    }
9848}
9849impl TextureComponentSwizzleDescriptor {
9850    pub fn new() -> Self {
9851        Self::default()
9852    }
9853    pub(crate) fn to_ffi(
9854        &self,
9855    ) -> (ffi::WGPUTextureComponentSwizzleDescriptor, ChainedStructStorage) {
9856        let mut storage = ChainedStructStorage::new();
9857        let mut raw: ffi::WGPUTextureComponentSwizzleDescriptor = unsafe {
9858            std::mem::zeroed()
9859        };
9860        if let Some(value) = &self.swizzle {
9861            let (raw_value, storage_value) = value.to_ffi();
9862            raw.swizzle = raw_value;
9863            storage.push_storage(storage_value);
9864        }
9865        (raw, storage)
9866    }
9867    pub(crate) fn from_ffi(value: ffi::WGPUTextureComponentSwizzleDescriptor) -> Self {
9868        Self {
9869            swizzle: Some(TextureComponentSwizzle::from_ffi(value.swizzle)),
9870        }
9871    }
9872}
9873pub struct TextureDescriptor {
9874    pub(crate) extensions: Vec<TextureDescriptorExtension>,
9875    pub label: Option<String>,
9876    pub usage: Option<TextureUsage>,
9877    pub dimension: Option<TextureDimension>,
9878    pub size: Option<Extent3D>,
9879    pub format: Option<TextureFormat>,
9880    pub mip_level_count: Option<u32>,
9881    pub sample_count: Option<u32>,
9882    pub view_formats: Option<Vec<TextureFormat>>,
9883}
9884impl Default for TextureDescriptor {
9885    fn default() -> Self {
9886        Self {
9887            extensions: Vec::new(),
9888            label: None,
9889            usage: None,
9890            dimension: Some(TextureDimension::D2),
9891            size: None,
9892            format: None,
9893            mip_level_count: Some(1),
9894            sample_count: Some(1),
9895            view_formats: None,
9896        }
9897    }
9898}
9899impl TextureDescriptor {
9900    pub fn new() -> Self {
9901        Self::default()
9902    }
9903    pub(crate) fn to_ffi(&self) -> (ffi::WGPUTextureDescriptor, ChainedStructStorage) {
9904        let mut storage = ChainedStructStorage::new();
9905        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
9906        for ext in self.extensions.iter().rev() {
9907            next = ext.push_chain(&mut storage, next);
9908        }
9909        let mut raw: ffi::WGPUTextureDescriptor = unsafe { std::mem::zeroed() };
9910        raw.nextInChain = next;
9911        if let Some(value) = &self.label {
9912            raw.label = ffi::WGPUStringView {
9913                data: value.as_ptr().cast(),
9914                length: value.len(),
9915            };
9916        } else {
9917            raw.label = ffi::WGPUStringView {
9918                data: std::ptr::null(),
9919                length: 0,
9920            };
9921        }
9922        if let Some(value) = self.usage {
9923            raw.usage = value.into();
9924        } else {
9925            raw.usage = 0 as ffi::WGPUTextureUsage;
9926        }
9927        if let Some(value) = self.dimension {
9928            raw.dimension = value.into();
9929        } else {
9930            raw.dimension = 0 as ffi::WGPUTextureDimension;
9931        }
9932        if let Some(value) = &self.size {
9933            let (raw_value, storage_value) = value.to_ffi();
9934            raw.size = raw_value;
9935            storage.push_storage(storage_value);
9936        }
9937        if let Some(value) = self.format {
9938            raw.format = value.into();
9939        } else {
9940            raw.format = 0 as ffi::WGPUTextureFormat;
9941        }
9942        if let Some(value) = self.mip_level_count {
9943            raw.mipLevelCount = value;
9944        }
9945        if let Some(value) = self.sample_count {
9946            raw.sampleCount = value;
9947        }
9948        raw.viewFormatCount = self.view_formats.as_ref().map(|v| v.len()).unwrap_or(0);
9949        if let Some(values) = &self.view_formats {
9950            let len_value = values.len();
9951            let raw_vec: Vec<ffi::WGPUTextureFormat> = values
9952                .iter()
9953                .map(|v| (*v).into())
9954                .collect();
9955            let ptr = storage.push_vec(raw_vec);
9956            raw.viewFormats = ptr;
9957            raw.viewFormatCount = len_value;
9958        } else {
9959            raw.viewFormats = std::ptr::null();
9960            raw.viewFormatCount = 0;
9961        }
9962        (raw, storage)
9963    }
9964    pub fn with_extension(mut self, extension: TextureDescriptorExtension) -> Self {
9965        self.extensions.push(extension);
9966        self
9967    }
9968    pub(crate) fn from_ffi(value: ffi::WGPUTextureDescriptor) -> Self {
9969        Self {
9970            extensions: Vec::new(),
9971            label: if value.label.data.is_null() || value.label.length == 0 {
9972                None
9973            } else {
9974                Some(string_view_to_string(value.label))
9975            },
9976            usage: Some(value.usage.into()),
9977            dimension: Some(value.dimension.into()),
9978            size: Some(Extent3D::from_ffi(value.size)),
9979            format: Some(value.format.into()),
9980            mip_level_count: Some(value.mipLevelCount),
9981            sample_count: Some(value.sampleCount),
9982            view_formats: if value.viewFormats.is_null() {
9983                None
9984            } else {
9985                Some(
9986                    unsafe {
9987                        std::slice::from_raw_parts(
9988                            value.viewFormats,
9989                            value.viewFormatCount as usize,
9990                        )
9991                    }
9992                        .iter()
9993                        .map(|raw| TextureFormat::from(*raw))
9994                        .collect(),
9995                )
9996            },
9997        }
9998    }
9999}
10000pub struct TextureViewDescriptor {
10001    pub(crate) extensions: Vec<TextureViewDescriptorExtension>,
10002    pub label: Option<String>,
10003    pub format: Option<TextureFormat>,
10004    pub dimension: Option<TextureViewDimension>,
10005    pub base_mip_level: Option<u32>,
10006    pub mip_level_count: Option<u32>,
10007    pub base_array_layer: Option<u32>,
10008    pub array_layer_count: Option<u32>,
10009    pub aspect: Option<TextureAspect>,
10010    pub usage: Option<TextureUsage>,
10011}
10012impl Default for TextureViewDescriptor {
10013    fn default() -> Self {
10014        Self {
10015            extensions: Vec::new(),
10016            label: None,
10017            format: None,
10018            dimension: None,
10019            base_mip_level: Some(0),
10020            mip_level_count: Some(MIP_LEVEL_COUNT_UNDEFINED),
10021            base_array_layer: Some(0),
10022            array_layer_count: Some(ARRAY_LAYER_COUNT_UNDEFINED),
10023            aspect: Some(TextureAspect::All),
10024            usage: None,
10025        }
10026    }
10027}
10028impl TextureViewDescriptor {
10029    pub fn new() -> Self {
10030        Self::default()
10031    }
10032    pub(crate) fn to_ffi(
10033        &self,
10034    ) -> (ffi::WGPUTextureViewDescriptor, ChainedStructStorage) {
10035        let mut storage = ChainedStructStorage::new();
10036        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
10037        for ext in self.extensions.iter().rev() {
10038            next = ext.push_chain(&mut storage, next);
10039        }
10040        let mut raw: ffi::WGPUTextureViewDescriptor = unsafe { std::mem::zeroed() };
10041        raw.nextInChain = next;
10042        if let Some(value) = &self.label {
10043            raw.label = ffi::WGPUStringView {
10044                data: value.as_ptr().cast(),
10045                length: value.len(),
10046            };
10047        } else {
10048            raw.label = ffi::WGPUStringView {
10049                data: std::ptr::null(),
10050                length: 0,
10051            };
10052        }
10053        if let Some(value) = self.format {
10054            raw.format = value.into();
10055        } else {
10056            raw.format = 0 as ffi::WGPUTextureFormat;
10057        }
10058        if let Some(value) = self.dimension {
10059            raw.dimension = value.into();
10060        } else {
10061            raw.dimension = 0 as ffi::WGPUTextureViewDimension;
10062        }
10063        if let Some(value) = self.base_mip_level {
10064            raw.baseMipLevel = value;
10065        }
10066        if let Some(value) = self.mip_level_count {
10067            raw.mipLevelCount = value;
10068        }
10069        if let Some(value) = self.base_array_layer {
10070            raw.baseArrayLayer = value;
10071        }
10072        if let Some(value) = self.array_layer_count {
10073            raw.arrayLayerCount = value;
10074        }
10075        if let Some(value) = self.aspect {
10076            raw.aspect = value.into();
10077        } else {
10078            raw.aspect = 0 as ffi::WGPUTextureAspect;
10079        }
10080        if let Some(value) = self.usage {
10081            raw.usage = value.into();
10082        } else {
10083            raw.usage = 0 as ffi::WGPUTextureUsage;
10084        }
10085        (raw, storage)
10086    }
10087    pub fn with_extension(mut self, extension: TextureViewDescriptorExtension) -> Self {
10088        self.extensions.push(extension);
10089        self
10090    }
10091    pub(crate) fn from_ffi(value: ffi::WGPUTextureViewDescriptor) -> Self {
10092        Self {
10093            extensions: Vec::new(),
10094            label: if value.label.data.is_null() || value.label.length == 0 {
10095                None
10096            } else {
10097                Some(string_view_to_string(value.label))
10098            },
10099            format: Some(value.format.into()),
10100            dimension: Some(value.dimension.into()),
10101            base_mip_level: Some(value.baseMipLevel),
10102            mip_level_count: Some(value.mipLevelCount),
10103            base_array_layer: Some(value.baseArrayLayer),
10104            array_layer_count: Some(value.arrayLayerCount),
10105            aspect: Some(value.aspect.into()),
10106            usage: Some(value.usage.into()),
10107        }
10108    }
10109}
10110pub struct VertexAttribute {
10111    pub(crate) extensions: Vec<VertexAttributeExtension>,
10112    pub format: Option<VertexFormat>,
10113    pub offset: Option<u64>,
10114    pub shader_location: Option<u32>,
10115}
10116impl Default for VertexAttribute {
10117    fn default() -> Self {
10118        Self {
10119            extensions: Vec::new(),
10120            format: None,
10121            offset: None,
10122            shader_location: None,
10123        }
10124    }
10125}
10126impl VertexAttribute {
10127    pub fn new() -> Self {
10128        Self::default()
10129    }
10130    pub(crate) fn to_ffi(&self) -> (ffi::WGPUVertexAttribute, ChainedStructStorage) {
10131        let mut storage = ChainedStructStorage::new();
10132        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
10133        for ext in self.extensions.iter().rev() {
10134            next = ext.push_chain(&mut storage, next);
10135        }
10136        let mut raw: ffi::WGPUVertexAttribute = unsafe { std::mem::zeroed() };
10137        raw.nextInChain = next;
10138        if let Some(value) = self.format {
10139            raw.format = value.into();
10140        } else {
10141            raw.format = 0 as ffi::WGPUVertexFormat;
10142        }
10143        if let Some(value) = self.offset {
10144            raw.offset = value;
10145        }
10146        if let Some(value) = self.shader_location {
10147            raw.shaderLocation = value;
10148        }
10149        (raw, storage)
10150    }
10151    pub fn with_extension(mut self, extension: VertexAttributeExtension) -> Self {
10152        self.extensions.push(extension);
10153        self
10154    }
10155    pub(crate) fn from_ffi(value: ffi::WGPUVertexAttribute) -> Self {
10156        Self {
10157            extensions: Vec::new(),
10158            format: Some(value.format.into()),
10159            offset: Some(value.offset),
10160            shader_location: Some(value.shaderLocation),
10161        }
10162    }
10163}
10164pub struct VertexBufferLayout {
10165    pub(crate) extensions: Vec<VertexBufferLayoutExtension>,
10166    pub step_mode: Option<VertexStepMode>,
10167    pub array_stride: Option<u64>,
10168    pub attributes: Option<Vec<VertexAttribute>>,
10169}
10170impl Default for VertexBufferLayout {
10171    fn default() -> Self {
10172        Self {
10173            extensions: Vec::new(),
10174            step_mode: None,
10175            array_stride: None,
10176            attributes: None,
10177        }
10178    }
10179}
10180impl VertexBufferLayout {
10181    pub fn new() -> Self {
10182        Self::default()
10183    }
10184    pub(crate) fn to_ffi(&self) -> (ffi::WGPUVertexBufferLayout, ChainedStructStorage) {
10185        let mut storage = ChainedStructStorage::new();
10186        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
10187        for ext in self.extensions.iter().rev() {
10188            next = ext.push_chain(&mut storage, next);
10189        }
10190        let mut raw: ffi::WGPUVertexBufferLayout = unsafe { std::mem::zeroed() };
10191        raw.nextInChain = next;
10192        if let Some(value) = self.step_mode {
10193            raw.stepMode = value.into();
10194        } else {
10195            raw.stepMode = 0 as ffi::WGPUVertexStepMode;
10196        }
10197        if let Some(value) = self.array_stride {
10198            raw.arrayStride = value;
10199        }
10200        raw.attributeCount = self.attributes.as_ref().map(|v| v.len()).unwrap_or(0);
10201        if let Some(values) = &self.attributes {
10202            let len_value = values.len();
10203            let mut raw_vec: Vec<ffi::WGPUVertexAttribute> = Vec::with_capacity(
10204                values.len(),
10205            );
10206            for item in values.iter() {
10207                let (raw_item, storage_item) = item.to_ffi();
10208                raw_vec.push(raw_item);
10209                storage.push_storage(storage_item);
10210            }
10211            let ptr = storage.push_vec(raw_vec);
10212            raw.attributes = ptr;
10213            raw.attributeCount = len_value;
10214        } else {
10215            raw.attributes = std::ptr::null();
10216            raw.attributeCount = 0;
10217        }
10218        (raw, storage)
10219    }
10220    pub fn with_extension(mut self, extension: VertexBufferLayoutExtension) -> Self {
10221        self.extensions.push(extension);
10222        self
10223    }
10224    pub(crate) fn from_ffi(value: ffi::WGPUVertexBufferLayout) -> Self {
10225        Self {
10226            extensions: Vec::new(),
10227            step_mode: Some(value.stepMode.into()),
10228            array_stride: Some(value.arrayStride),
10229            attributes: if value.attributes.is_null() {
10230                None
10231            } else {
10232                Some(
10233                    unsafe {
10234                        std::slice::from_raw_parts(
10235                            value.attributes,
10236                            value.attributeCount as usize,
10237                        )
10238                    }
10239                        .iter()
10240                        .map(|raw| VertexAttribute::from_ffi(*raw))
10241                        .collect(),
10242                )
10243            },
10244        }
10245    }
10246}
10247pub struct VertexState {
10248    pub(crate) extensions: Vec<VertexStateExtension>,
10249    pub module: Option<ShaderModule>,
10250    pub entry_point: Option<String>,
10251    pub constants: Option<Vec<ConstantEntry>>,
10252    pub buffers: Option<Vec<VertexBufferLayout>>,
10253}
10254impl Default for VertexState {
10255    fn default() -> Self {
10256        Self {
10257            extensions: Vec::new(),
10258            module: None,
10259            entry_point: None,
10260            constants: None,
10261            buffers: None,
10262        }
10263    }
10264}
10265impl VertexState {
10266    pub fn new() -> Self {
10267        Self::default()
10268    }
10269    pub(crate) fn to_ffi(&self) -> (ffi::WGPUVertexState, ChainedStructStorage) {
10270        let mut storage = ChainedStructStorage::new();
10271        let mut next: *mut ffi::WGPUChainedStruct = std::ptr::null_mut();
10272        for ext in self.extensions.iter().rev() {
10273            next = ext.push_chain(&mut storage, next);
10274        }
10275        let mut raw: ffi::WGPUVertexState = unsafe { std::mem::zeroed() };
10276        raw.nextInChain = next;
10277        raw.module = self
10278            .module
10279            .as_ref()
10280            .map(|v| v.as_raw())
10281            .unwrap_or(std::ptr::null_mut());
10282        if let Some(value) = &self.entry_point {
10283            raw.entryPoint = ffi::WGPUStringView {
10284                data: value.as_ptr().cast(),
10285                length: value.len(),
10286            };
10287        } else {
10288            raw.entryPoint = ffi::WGPUStringView {
10289                data: std::ptr::null(),
10290                length: 0,
10291            };
10292        }
10293        raw.constantCount = self.constants.as_ref().map(|v| v.len()).unwrap_or(0);
10294        if let Some(values) = &self.constants {
10295            let len_value = values.len();
10296            let mut raw_vec: Vec<ffi::WGPUConstantEntry> = Vec::with_capacity(
10297                values.len(),
10298            );
10299            for item in values.iter() {
10300                let (raw_item, storage_item) = item.to_ffi();
10301                raw_vec.push(raw_item);
10302                storage.push_storage(storage_item);
10303            }
10304            let ptr = storage.push_vec(raw_vec);
10305            raw.constants = ptr;
10306            raw.constantCount = len_value;
10307        } else {
10308            raw.constants = std::ptr::null();
10309            raw.constantCount = 0;
10310        }
10311        raw.bufferCount = self.buffers.as_ref().map(|v| v.len()).unwrap_or(0);
10312        if let Some(values) = &self.buffers {
10313            let len_value = values.len();
10314            let mut raw_vec: Vec<ffi::WGPUVertexBufferLayout> = Vec::with_capacity(
10315                values.len(),
10316            );
10317            for item in values.iter() {
10318                let (raw_item, storage_item) = item.to_ffi();
10319                raw_vec.push(raw_item);
10320                storage.push_storage(storage_item);
10321            }
10322            let ptr = storage.push_vec(raw_vec);
10323            raw.buffers = ptr;
10324            raw.bufferCount = len_value;
10325        } else {
10326            raw.buffers = std::ptr::null();
10327            raw.bufferCount = 0;
10328        }
10329        (raw, storage)
10330    }
10331    pub fn with_extension(mut self, extension: VertexStateExtension) -> Self {
10332        self.extensions.push(extension);
10333        self
10334    }
10335    pub(crate) fn from_ffi(value: ffi::WGPUVertexState) -> Self {
10336        Self {
10337            extensions: Vec::new(),
10338            module: Some(unsafe { ShaderModule::from_raw(value.module) }),
10339            entry_point: if value.entryPoint.data.is_null()
10340                || value.entryPoint.length == 0
10341            {
10342                None
10343            } else {
10344                Some(string_view_to_string(value.entryPoint))
10345            },
10346            constants: if value.constants.is_null() {
10347                None
10348            } else {
10349                Some(
10350                    unsafe {
10351                        std::slice::from_raw_parts(
10352                            value.constants,
10353                            value.constantCount as usize,
10354                        )
10355                    }
10356                        .iter()
10357                        .map(|raw| ConstantEntry::from_ffi(*raw))
10358                        .collect(),
10359                )
10360            },
10361            buffers: if value.buffers.is_null() {
10362                None
10363            } else {
10364                Some(
10365                    unsafe {
10366                        std::slice::from_raw_parts(
10367                            value.buffers,
10368                            value.bufferCount as usize,
10369                        )
10370                    }
10371                        .iter()
10372                        .map(|raw| VertexBufferLayout::from_ffi(*raw))
10373                        .collect(),
10374                )
10375            },
10376        }
10377    }
10378}
10379pub struct YCbCrVkDescriptor {
10380    pub vk_format: Option<u32>,
10381    pub vk_y_cb_cr_model: Option<u32>,
10382    pub vk_y_cb_cr_range: Option<u32>,
10383    pub vk_component_swizzle_red: Option<u32>,
10384    pub vk_component_swizzle_green: Option<u32>,
10385    pub vk_component_swizzle_blue: Option<u32>,
10386    pub vk_component_swizzle_alpha: Option<u32>,
10387    pub vk_x_chroma_offset: Option<u32>,
10388    pub vk_y_chroma_offset: Option<u32>,
10389    pub vk_chroma_filter: Option<FilterMode>,
10390    pub force_explicit_reconstruction: Option<bool>,
10391    pub external_format: Option<u64>,
10392}
10393impl Default for YCbCrVkDescriptor {
10394    fn default() -> Self {
10395        Self {
10396            vk_format: Some(0),
10397            vk_y_cb_cr_model: Some(0),
10398            vk_y_cb_cr_range: Some(0),
10399            vk_component_swizzle_red: Some(0),
10400            vk_component_swizzle_green: Some(0),
10401            vk_component_swizzle_blue: Some(0),
10402            vk_component_swizzle_alpha: Some(0),
10403            vk_x_chroma_offset: Some(0),
10404            vk_y_chroma_offset: Some(0),
10405            vk_chroma_filter: Some(FilterMode::Nearest),
10406            force_explicit_reconstruction: None,
10407            external_format: Some(0),
10408        }
10409    }
10410}
10411impl YCbCrVkDescriptor {
10412    pub fn new() -> Self {
10413        Self::default()
10414    }
10415    pub(crate) fn to_ffi(&self) -> (ffi::WGPUYCbCrVkDescriptor, ChainedStructStorage) {
10416        let mut storage = ChainedStructStorage::new();
10417        let mut raw: ffi::WGPUYCbCrVkDescriptor = unsafe { std::mem::zeroed() };
10418        if let Some(value) = self.vk_format {
10419            raw.vkFormat = value;
10420        }
10421        if let Some(value) = self.vk_y_cb_cr_model {
10422            raw.vkYCbCrModel = value;
10423        }
10424        if let Some(value) = self.vk_y_cb_cr_range {
10425            raw.vkYCbCrRange = value;
10426        }
10427        if let Some(value) = self.vk_component_swizzle_red {
10428            raw.vkComponentSwizzleRed = value;
10429        }
10430        if let Some(value) = self.vk_component_swizzle_green {
10431            raw.vkComponentSwizzleGreen = value;
10432        }
10433        if let Some(value) = self.vk_component_swizzle_blue {
10434            raw.vkComponentSwizzleBlue = value;
10435        }
10436        if let Some(value) = self.vk_component_swizzle_alpha {
10437            raw.vkComponentSwizzleAlpha = value;
10438        }
10439        if let Some(value) = self.vk_x_chroma_offset {
10440            raw.vkXChromaOffset = value;
10441        }
10442        if let Some(value) = self.vk_y_chroma_offset {
10443            raw.vkYChromaOffset = value;
10444        }
10445        if let Some(value) = self.vk_chroma_filter {
10446            raw.vkChromaFilter = value.into();
10447        } else {
10448            raw.vkChromaFilter = 0 as ffi::WGPUFilterMode;
10449        }
10450        raw.forceExplicitReconstruction = if self
10451            .force_explicit_reconstruction
10452            .unwrap_or(false)
10453        {
10454            1
10455        } else {
10456            0
10457        };
10458        if let Some(value) = self.external_format {
10459            raw.externalFormat = value;
10460        }
10461        (raw, storage)
10462    }
10463    pub(crate) fn from_ffi(value: ffi::WGPUYCbCrVkDescriptor) -> Self {
10464        Self {
10465            vk_format: Some(value.vkFormat),
10466            vk_y_cb_cr_model: Some(value.vkYCbCrModel),
10467            vk_y_cb_cr_range: Some(value.vkYCbCrRange),
10468            vk_component_swizzle_red: Some(value.vkComponentSwizzleRed),
10469            vk_component_swizzle_green: Some(value.vkComponentSwizzleGreen),
10470            vk_component_swizzle_blue: Some(value.vkComponentSwizzleBlue),
10471            vk_component_swizzle_alpha: Some(value.vkComponentSwizzleAlpha),
10472            vk_x_chroma_offset: Some(value.vkXChromaOffset),
10473            vk_y_chroma_offset: Some(value.vkYChromaOffset),
10474            vk_chroma_filter: Some(value.vkChromaFilter.into()),
10475            force_explicit_reconstruction: Some(value.forceExplicitReconstruction != 0),
10476            external_format: Some(value.externalFormat),
10477        }
10478    }
10479}