Skip to main content

dawn_rs/generated/
objects.rs

1#![allow(dead_code, unused_imports)]
2use crate::ffi;
3use super::*;
4#[derive(Debug)]
5pub struct Adapter {
6    raw: ffi::WGPUAdapter,
7    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
8}
9impl Adapter {
10    pub(crate) unsafe fn from_raw(raw: ffi::WGPUAdapter) -> Self {
11        Self {
12            raw,
13            _not_sync: std::marker::PhantomData,
14        }
15    }
16    pub fn as_raw(&self) -> ffi::WGPUAdapter {
17        self.raw
18    }
19    pub fn get_instance(&self) -> Instance {
20        let result = unsafe { ffi::wgpuAdapterGetInstance(self.raw) };
21        unsafe { Instance::from_raw(result) }
22    }
23    pub fn get_limits(&self, limits: &mut Limits) -> Status {
24        let (mut limits_ffi, _limits_storage) = limits.to_ffi();
25        let limits_ptr = std::ptr::addr_of_mut!(limits_ffi);
26        let result = unsafe { ffi::wgpuAdapterGetLimits(self.raw, limits_ptr) };
27        *limits = Limits::from_ffi(limits_ffi);
28        result.into()
29    }
30    pub fn get_info(&self, info: &mut AdapterInfo) -> Status {
31        let (mut info_ffi, _info_storage) = info.to_ffi();
32        let info_ptr = std::ptr::addr_of_mut!(info_ffi);
33        let result = unsafe { ffi::wgpuAdapterGetInfo(self.raw, info_ptr) };
34        *info = AdapterInfo::from_ffi(info_ffi);
35        result.into()
36    }
37    pub fn has_feature(&self, feature: FeatureName) -> bool {
38        let feature_ffi: ffi::WGPUFeatureName = feature.into();
39        let result = unsafe { ffi::wgpuAdapterHasFeature(self.raw, feature_ffi) };
40        result != 0
41    }
42    pub fn get_features(&self, features: &mut SupportedFeatures) -> () {
43        let (mut features_ffi, _features_storage) = features.to_ffi();
44        let features_ptr = std::ptr::addr_of_mut!(features_ffi);
45        unsafe { ffi::wgpuAdapterGetFeatures(self.raw, features_ptr) };
46        *features = SupportedFeatures::from_ffi(features_ffi);
47        ()
48    }
49    pub fn request_device(
50        &self,
51        descriptor: Option<&DeviceDescriptor>,
52        callback: impl FnMut(
53            RequestDeviceStatus,
54            Option<Device>,
55            String,
56        ) + Send + 'static,
57    ) -> Future {
58        let mut descriptor_storage = ChainedStructStorage::new();
59        let descriptor_ptr = if let Some(value) = &descriptor {
60            let (descriptor_ffi, storage) = value.to_ffi();
61            descriptor_storage = storage;
62            std::ptr::addr_of!(descriptor_ffi)
63        } else {
64            std::ptr::null()
65        };
66        let callback_box: RequestDeviceCallback = Box::new(callback);
67        let callback_box = Box::new(Some(callback_box));
68        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
69        let callback_info_ffi = ffi::WGPURequestDeviceCallbackInfo {
70            nextInChain: std::ptr::null_mut(),
71            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
72            callback: Some(request_device_callback_trampoline),
73            userdata1: callback_userdata,
74            userdata2: std::ptr::null_mut(),
75        };
76        let result = unsafe {
77            ffi::wgpuAdapterRequestDevice(self.raw, descriptor_ptr, callback_info_ffi)
78        };
79        Future::from_ffi(result)
80    }
81    pub fn create_device(&self, descriptor: Option<&DeviceDescriptor>) -> Device {
82        let mut descriptor_storage = ChainedStructStorage::new();
83        let descriptor_ptr = if let Some(value) = &descriptor {
84            let (descriptor_ffi, storage) = value.to_ffi();
85            descriptor_storage = storage;
86            std::ptr::addr_of!(descriptor_ffi)
87        } else {
88            std::ptr::null()
89        };
90        let result = unsafe { ffi::wgpuAdapterCreateDevice(self.raw, descriptor_ptr) };
91        unsafe { Device::from_raw(result) }
92    }
93    pub fn get_format_capabilities(
94        &self,
95        format: TextureFormat,
96        capabilities: &mut DawnFormatCapabilities,
97    ) -> Status {
98        let format_ffi: ffi::WGPUTextureFormat = format.into();
99        let (mut capabilities_ffi, _capabilities_storage) = capabilities.to_ffi();
100        let capabilities_ptr = std::ptr::addr_of_mut!(capabilities_ffi);
101        let result = unsafe {
102            ffi::wgpuAdapterGetFormatCapabilities(self.raw, format_ffi, capabilities_ptr)
103        };
104        *capabilities = DawnFormatCapabilities::from_ffi(capabilities_ffi);
105        result.into()
106    }
107}
108impl Drop for Adapter {
109    fn drop(&mut self) {
110        if self.as_raw().is_null() {
111            return;
112        }
113        unsafe { ffi::wgpuAdapterRelease(self.raw) };
114    }
115}
116impl Clone for Adapter {
117    fn clone(&self) -> Self {
118        unsafe { ffi::wgpuAdapterAddRef(self.raw) };
119        Self {
120            raw: self.raw,
121            _not_sync: std::marker::PhantomData,
122        }
123    }
124}
125#[derive(Debug)]
126pub struct BindGroup {
127    raw: ffi::WGPUBindGroup,
128}
129impl BindGroup {
130    pub(crate) unsafe fn from_raw(raw: ffi::WGPUBindGroup) -> Self {
131        Self { raw }
132    }
133    pub fn as_raw(&self) -> ffi::WGPUBindGroup {
134        self.raw
135    }
136    pub fn set_label(&self, label: String) -> () {
137        let label_ffi = ffi::WGPUStringView {
138            data: label.as_ptr().cast(),
139            length: label.len(),
140        };
141        unsafe { ffi::wgpuBindGroupSetLabel(self.raw, label_ffi) };
142        ()
143    }
144}
145impl Drop for BindGroup {
146    fn drop(&mut self) {
147        if self.as_raw().is_null() {
148            return;
149        }
150        unsafe { ffi::wgpuBindGroupRelease(self.raw) };
151    }
152}
153impl Clone for BindGroup {
154    fn clone(&self) -> Self {
155        unsafe { ffi::wgpuBindGroupAddRef(self.raw) };
156        Self { raw: self.raw }
157    }
158}
159unsafe impl Send for BindGroup {}
160unsafe impl Sync for BindGroup {}
161#[derive(Debug)]
162pub struct BindGroupLayout {
163    raw: ffi::WGPUBindGroupLayout,
164}
165impl BindGroupLayout {
166    pub(crate) unsafe fn from_raw(raw: ffi::WGPUBindGroupLayout) -> Self {
167        Self { raw }
168    }
169    pub fn as_raw(&self) -> ffi::WGPUBindGroupLayout {
170        self.raw
171    }
172    pub fn set_label(&self, label: String) -> () {
173        let label_ffi = ffi::WGPUStringView {
174            data: label.as_ptr().cast(),
175            length: label.len(),
176        };
177        unsafe { ffi::wgpuBindGroupLayoutSetLabel(self.raw, label_ffi) };
178        ()
179    }
180}
181impl Drop for BindGroupLayout {
182    fn drop(&mut self) {
183        if self.as_raw().is_null() {
184            return;
185        }
186        unsafe { ffi::wgpuBindGroupLayoutRelease(self.raw) };
187    }
188}
189impl Clone for BindGroupLayout {
190    fn clone(&self) -> Self {
191        unsafe { ffi::wgpuBindGroupLayoutAddRef(self.raw) };
192        Self { raw: self.raw }
193    }
194}
195unsafe impl Send for BindGroupLayout {}
196unsafe impl Sync for BindGroupLayout {}
197#[derive(Debug)]
198pub struct Buffer {
199    raw: ffi::WGPUBuffer,
200}
201impl Buffer {
202    pub(crate) unsafe fn from_raw(raw: ffi::WGPUBuffer) -> Self {
203        Self { raw }
204    }
205    pub fn as_raw(&self) -> ffi::WGPUBuffer {
206        self.raw
207    }
208    pub fn map_async(
209        &self,
210        mode: MapMode,
211        offset: usize,
212        size: usize,
213        callback: impl FnMut(MapAsyncStatus, String) + Send + 'static,
214    ) -> Future {
215        let mode_ffi: ffi::WGPUMapMode = mode.into();
216        let callback_box: BufferMapCallback = Box::new(callback);
217        let callback_box = Box::new(Some(callback_box));
218        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
219        let callback_info_ffi = ffi::WGPUBufferMapCallbackInfo {
220            nextInChain: std::ptr::null_mut(),
221            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
222            callback: Some(buffer_map_callback_trampoline),
223            userdata1: callback_userdata,
224            userdata2: std::ptr::null_mut(),
225        };
226        let result = unsafe {
227            ffi::wgpuBufferMapAsync(self.raw, mode_ffi, offset, size, callback_info_ffi)
228        };
229        Future::from_ffi(result)
230    }
231    pub fn get_mapped_range(&self, offset: usize, size: usize) -> *mut std::ffi::c_void {
232        let result = unsafe { ffi::wgpuBufferGetMappedRange(self.raw, offset, size) };
233        result
234    }
235    pub fn get_const_mapped_range(
236        &self,
237        offset: usize,
238        size: usize,
239    ) -> *const std::ffi::c_void {
240        let result = unsafe {
241            ffi::wgpuBufferGetConstMappedRange(self.raw, offset, size)
242        };
243        result
244    }
245    pub fn write_mapped_range(
246        &self,
247        offset: usize,
248        data: &[std::ffi::c_void],
249    ) -> Status {
250        let data_ptr = data.as_ptr();
251        let result = unsafe {
252            ffi::wgpuBufferWriteMappedRange(self.raw, offset, data_ptr, data.len())
253        };
254        result.into()
255    }
256    pub fn read_mapped_range(
257        &self,
258        offset: usize,
259        mut data: &mut [std::ffi::c_void],
260    ) -> Status {
261        let data_ptr = data.as_mut_ptr();
262        let result = unsafe {
263            ffi::wgpuBufferReadMappedRange(self.raw, offset, data_ptr, data.len())
264        };
265        result.into()
266    }
267    pub fn create_texel_view(
268        &self,
269        descriptor: &TexelBufferViewDescriptor,
270    ) -> TexelBufferView {
271        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
272        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
273        let result = unsafe { ffi::wgpuBufferCreateTexelView(self.raw, descriptor_ptr) };
274        unsafe { TexelBufferView::from_raw(result) }
275    }
276    pub fn set_label(&self, label: String) -> () {
277        let label_ffi = ffi::WGPUStringView {
278            data: label.as_ptr().cast(),
279            length: label.len(),
280        };
281        unsafe { ffi::wgpuBufferSetLabel(self.raw, label_ffi) };
282        ()
283    }
284    pub fn get_usage(&self) -> BufferUsage {
285        let result = unsafe { ffi::wgpuBufferGetUsage(self.raw) };
286        result.into()
287    }
288    pub fn get_size(&self) -> u64 {
289        let result = unsafe { ffi::wgpuBufferGetSize(self.raw) };
290        result
291    }
292    pub fn get_map_state(&self) -> BufferMapState {
293        let result = unsafe { ffi::wgpuBufferGetMapState(self.raw) };
294        result.into()
295    }
296    pub fn unmap(&self) -> () {
297        unsafe { ffi::wgpuBufferUnmap(self.raw) };
298        ()
299    }
300    pub fn destroy(&self) -> () {
301        unsafe { ffi::wgpuBufferDestroy(self.raw) };
302        ()
303    }
304}
305impl Drop for Buffer {
306    fn drop(&mut self) {
307        if self.as_raw().is_null() {
308            return;
309        }
310        unsafe { ffi::wgpuBufferRelease(self.raw) };
311    }
312}
313impl Clone for Buffer {
314    fn clone(&self) -> Self {
315        unsafe { ffi::wgpuBufferAddRef(self.raw) };
316        Self { raw: self.raw }
317    }
318}
319unsafe impl Send for Buffer {}
320unsafe impl Sync for Buffer {}
321#[derive(Debug)]
322pub struct CommandBuffer {
323    raw: ffi::WGPUCommandBuffer,
324}
325impl CommandBuffer {
326    pub(crate) unsafe fn from_raw(raw: ffi::WGPUCommandBuffer) -> Self {
327        Self { raw }
328    }
329    pub fn as_raw(&self) -> ffi::WGPUCommandBuffer {
330        self.raw
331    }
332    pub fn set_label(&self, label: String) -> () {
333        let label_ffi = ffi::WGPUStringView {
334            data: label.as_ptr().cast(),
335            length: label.len(),
336        };
337        unsafe { ffi::wgpuCommandBufferSetLabel(self.raw, label_ffi) };
338        ()
339    }
340}
341impl Drop for CommandBuffer {
342    fn drop(&mut self) {
343        if self.as_raw().is_null() {
344            return;
345        }
346        unsafe { ffi::wgpuCommandBufferRelease(self.raw) };
347    }
348}
349impl Clone for CommandBuffer {
350    fn clone(&self) -> Self {
351        unsafe { ffi::wgpuCommandBufferAddRef(self.raw) };
352        Self { raw: self.raw }
353    }
354}
355unsafe impl Send for CommandBuffer {}
356unsafe impl Sync for CommandBuffer {}
357#[derive(Debug)]
358pub struct CommandEncoder {
359    raw: ffi::WGPUCommandEncoder,
360    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
361}
362impl CommandEncoder {
363    pub(crate) unsafe fn from_raw(raw: ffi::WGPUCommandEncoder) -> Self {
364        Self {
365            raw,
366            _not_sync: std::marker::PhantomData,
367        }
368    }
369    pub fn as_raw(&self) -> ffi::WGPUCommandEncoder {
370        self.raw
371    }
372    pub fn finish(&self, descriptor: Option<&CommandBufferDescriptor>) -> CommandBuffer {
373        let mut descriptor_storage = ChainedStructStorage::new();
374        let descriptor_ptr = if let Some(value) = &descriptor {
375            let (descriptor_ffi, storage) = value.to_ffi();
376            descriptor_storage = storage;
377            std::ptr::addr_of!(descriptor_ffi)
378        } else {
379            std::ptr::null()
380        };
381        let result = unsafe { ffi::wgpuCommandEncoderFinish(self.raw, descriptor_ptr) };
382        unsafe { CommandBuffer::from_raw(result) }
383    }
384    pub fn begin_compute_pass(
385        &self,
386        descriptor: Option<&ComputePassDescriptor>,
387    ) -> ComputePassEncoder {
388        let mut descriptor_storage = ChainedStructStorage::new();
389        let descriptor_ptr = if let Some(value) = &descriptor {
390            let (descriptor_ffi, storage) = value.to_ffi();
391            descriptor_storage = storage;
392            std::ptr::addr_of!(descriptor_ffi)
393        } else {
394            std::ptr::null()
395        };
396        let result = unsafe {
397            ffi::wgpuCommandEncoderBeginComputePass(self.raw, descriptor_ptr)
398        };
399        unsafe { ComputePassEncoder::from_raw(result) }
400    }
401    pub fn begin_render_pass(
402        &self,
403        descriptor: &RenderPassDescriptor,
404    ) -> RenderPassEncoder {
405        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
406        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
407        let result = unsafe {
408            ffi::wgpuCommandEncoderBeginRenderPass(self.raw, descriptor_ptr)
409        };
410        unsafe { RenderPassEncoder::from_raw(result) }
411    }
412    pub fn copy_buffer_to_buffer(
413        &self,
414        source: Buffer,
415        source_offset: u64,
416        destination: Buffer,
417        destination_offset: u64,
418        size: u64,
419    ) -> () {
420        unsafe {
421            ffi::wgpuCommandEncoderCopyBufferToBuffer(
422                self.raw,
423                source.as_raw(),
424                source_offset,
425                destination.as_raw(),
426                destination_offset,
427                size,
428            )
429        };
430        ()
431    }
432    pub fn copy_buffer_to_texture(
433        &self,
434        source: &TexelCopyBufferInfo,
435        destination: &TexelCopyTextureInfo,
436        copy_size: &Extent3D,
437    ) -> () {
438        let (source_ffi, _source_storage) = source.to_ffi();
439        let source_ptr = std::ptr::addr_of!(source_ffi);
440        let (destination_ffi, _destination_storage) = destination.to_ffi();
441        let destination_ptr = std::ptr::addr_of!(destination_ffi);
442        let (copy_size_ffi, _copy_size_storage) = copy_size.to_ffi();
443        let copy_size_ptr = std::ptr::addr_of!(copy_size_ffi);
444        unsafe {
445            ffi::wgpuCommandEncoderCopyBufferToTexture(
446                self.raw,
447                source_ptr,
448                destination_ptr,
449                copy_size_ptr,
450            )
451        };
452        ()
453    }
454    pub fn copy_texture_to_buffer(
455        &self,
456        source: &TexelCopyTextureInfo,
457        destination: &TexelCopyBufferInfo,
458        copy_size: &Extent3D,
459    ) -> () {
460        let (source_ffi, _source_storage) = source.to_ffi();
461        let source_ptr = std::ptr::addr_of!(source_ffi);
462        let (destination_ffi, _destination_storage) = destination.to_ffi();
463        let destination_ptr = std::ptr::addr_of!(destination_ffi);
464        let (copy_size_ffi, _copy_size_storage) = copy_size.to_ffi();
465        let copy_size_ptr = std::ptr::addr_of!(copy_size_ffi);
466        unsafe {
467            ffi::wgpuCommandEncoderCopyTextureToBuffer(
468                self.raw,
469                source_ptr,
470                destination_ptr,
471                copy_size_ptr,
472            )
473        };
474        ()
475    }
476    pub fn copy_texture_to_texture(
477        &self,
478        source: &TexelCopyTextureInfo,
479        destination: &TexelCopyTextureInfo,
480        copy_size: &Extent3D,
481    ) -> () {
482        let (source_ffi, _source_storage) = source.to_ffi();
483        let source_ptr = std::ptr::addr_of!(source_ffi);
484        let (destination_ffi, _destination_storage) = destination.to_ffi();
485        let destination_ptr = std::ptr::addr_of!(destination_ffi);
486        let (copy_size_ffi, _copy_size_storage) = copy_size.to_ffi();
487        let copy_size_ptr = std::ptr::addr_of!(copy_size_ffi);
488        unsafe {
489            ffi::wgpuCommandEncoderCopyTextureToTexture(
490                self.raw,
491                source_ptr,
492                destination_ptr,
493                copy_size_ptr,
494            )
495        };
496        ()
497    }
498    pub fn clear_buffer(&self, buffer: Buffer, offset: u64, size: u64) -> () {
499        unsafe {
500            ffi::wgpuCommandEncoderClearBuffer(self.raw, buffer.as_raw(), offset, size)
501        };
502        ()
503    }
504    pub fn inject_validation_error(&self, message: String) -> () {
505        let message_ffi = ffi::WGPUStringView {
506            data: message.as_ptr().cast(),
507            length: message.len(),
508        };
509        unsafe { ffi::wgpuCommandEncoderInjectValidationError(self.raw, message_ffi) };
510        ()
511    }
512    pub fn insert_debug_marker(&self, marker_label: String) -> () {
513        let marker_label_ffi = ffi::WGPUStringView {
514            data: marker_label.as_ptr().cast(),
515            length: marker_label.len(),
516        };
517        unsafe { ffi::wgpuCommandEncoderInsertDebugMarker(self.raw, marker_label_ffi) };
518        ()
519    }
520    pub fn pop_debug_group(&self) -> () {
521        unsafe { ffi::wgpuCommandEncoderPopDebugGroup(self.raw) };
522        ()
523    }
524    pub fn push_debug_group(&self, group_label: String) -> () {
525        let group_label_ffi = ffi::WGPUStringView {
526            data: group_label.as_ptr().cast(),
527            length: group_label.len(),
528        };
529        unsafe { ffi::wgpuCommandEncoderPushDebugGroup(self.raw, group_label_ffi) };
530        ()
531    }
532    pub fn resolve_query_set(
533        &self,
534        query_set: QuerySet,
535        first_query: u32,
536        query_count: u32,
537        destination: Buffer,
538        destination_offset: u64,
539    ) -> () {
540        unsafe {
541            ffi::wgpuCommandEncoderResolveQuerySet(
542                self.raw,
543                query_set.as_raw(),
544                first_query,
545                query_count,
546                destination.as_raw(),
547                destination_offset,
548            )
549        };
550        ()
551    }
552    pub fn write_buffer(&self, buffer: Buffer, buffer_offset: u64, data: &[u8]) -> () {
553        let data_ptr = data.as_ptr();
554        unsafe {
555            ffi::wgpuCommandEncoderWriteBuffer(
556                self.raw,
557                buffer.as_raw(),
558                buffer_offset,
559                data_ptr,
560                (data.len()) as u64,
561            )
562        };
563        ()
564    }
565    pub fn write_timestamp(&self, query_set: QuerySet, query_index: u32) -> () {
566        unsafe {
567            ffi::wgpuCommandEncoderWriteTimestamp(
568                self.raw,
569                query_set.as_raw(),
570                query_index,
571            )
572        };
573        ()
574    }
575    pub fn set_label(&self, label: String) -> () {
576        let label_ffi = ffi::WGPUStringView {
577            data: label.as_ptr().cast(),
578            length: label.len(),
579        };
580        unsafe { ffi::wgpuCommandEncoderSetLabel(self.raw, label_ffi) };
581        ()
582    }
583    pub fn set_resource_table(&self, table: Option<ResourceTable>) -> () {
584        let table_raw = table
585            .as_ref()
586            .map(|v| v.as_raw())
587            .unwrap_or(std::ptr::null_mut());
588        unsafe { ffi::wgpuCommandEncoderSetResourceTable(self.raw, table_raw) };
589        ()
590    }
591}
592impl Drop for CommandEncoder {
593    fn drop(&mut self) {
594        if self.as_raw().is_null() {
595            return;
596        }
597        unsafe { ffi::wgpuCommandEncoderRelease(self.raw) };
598    }
599}
600impl Clone for CommandEncoder {
601    fn clone(&self) -> Self {
602        unsafe { ffi::wgpuCommandEncoderAddRef(self.raw) };
603        Self {
604            raw: self.raw,
605            _not_sync: std::marker::PhantomData,
606        }
607    }
608}
609#[derive(Debug)]
610pub struct ComputePassEncoder {
611    raw: ffi::WGPUComputePassEncoder,
612    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
613}
614impl ComputePassEncoder {
615    pub(crate) unsafe fn from_raw(raw: ffi::WGPUComputePassEncoder) -> Self {
616        Self {
617            raw,
618            _not_sync: std::marker::PhantomData,
619        }
620    }
621    pub fn as_raw(&self) -> ffi::WGPUComputePassEncoder {
622        self.raw
623    }
624    pub fn insert_debug_marker(&self, marker_label: String) -> () {
625        let marker_label_ffi = ffi::WGPUStringView {
626            data: marker_label.as_ptr().cast(),
627            length: marker_label.len(),
628        };
629        unsafe {
630            ffi::wgpuComputePassEncoderInsertDebugMarker(self.raw, marker_label_ffi)
631        };
632        ()
633    }
634    pub fn pop_debug_group(&self) -> () {
635        unsafe { ffi::wgpuComputePassEncoderPopDebugGroup(self.raw) };
636        ()
637    }
638    pub fn push_debug_group(&self, group_label: String) -> () {
639        let group_label_ffi = ffi::WGPUStringView {
640            data: group_label.as_ptr().cast(),
641            length: group_label.len(),
642        };
643        unsafe { ffi::wgpuComputePassEncoderPushDebugGroup(self.raw, group_label_ffi) };
644        ()
645    }
646    pub fn set_pipeline(&self, pipeline: ComputePipeline) -> () {
647        unsafe { ffi::wgpuComputePassEncoderSetPipeline(self.raw, pipeline.as_raw()) };
648        ()
649    }
650    pub fn set_bind_group(
651        &self,
652        group_index: u32,
653        group: Option<BindGroup>,
654        dynamic_offsets: &[u32],
655    ) -> () {
656        let group_raw = group
657            .as_ref()
658            .map(|v| v.as_raw())
659            .unwrap_or(std::ptr::null_mut());
660        let dynamic_offsets_ptr = dynamic_offsets.as_ptr();
661        unsafe {
662            ffi::wgpuComputePassEncoderSetBindGroup(
663                self.raw,
664                group_index,
665                group_raw,
666                dynamic_offsets.len(),
667                dynamic_offsets_ptr,
668            )
669        };
670        ()
671    }
672    pub fn write_timestamp(&self, query_set: QuerySet, query_index: u32) -> () {
673        unsafe {
674            ffi::wgpuComputePassEncoderWriteTimestamp(
675                self.raw,
676                query_set.as_raw(),
677                query_index,
678            )
679        };
680        ()
681    }
682    pub fn dispatch_workgroups(
683        &self,
684        workgroup_count_x: u32,
685        workgroup_count_y: u32,
686        workgroup_count_z: u32,
687    ) -> () {
688        unsafe {
689            ffi::wgpuComputePassEncoderDispatchWorkgroups(
690                self.raw,
691                workgroup_count_x,
692                workgroup_count_y,
693                workgroup_count_z,
694            )
695        };
696        ()
697    }
698    pub fn dispatch_workgroups_indirect(
699        &self,
700        indirect_buffer: Buffer,
701        indirect_offset: u64,
702    ) -> () {
703        unsafe {
704            ffi::wgpuComputePassEncoderDispatchWorkgroupsIndirect(
705                self.raw,
706                indirect_buffer.as_raw(),
707                indirect_offset,
708            )
709        };
710        ()
711    }
712    pub fn end(&self) -> () {
713        unsafe { ffi::wgpuComputePassEncoderEnd(self.raw) };
714        ()
715    }
716    pub fn set_label(&self, label: String) -> () {
717        let label_ffi = ffi::WGPUStringView {
718            data: label.as_ptr().cast(),
719            length: label.len(),
720        };
721        unsafe { ffi::wgpuComputePassEncoderSetLabel(self.raw, label_ffi) };
722        ()
723    }
724    pub fn set_immediates(&self, offset: u32, data: &[std::ffi::c_void]) -> () {
725        let data_ptr = data.as_ptr();
726        unsafe {
727            ffi::wgpuComputePassEncoderSetImmediates(
728                self.raw,
729                offset,
730                data_ptr,
731                data.len(),
732            )
733        };
734        ()
735    }
736}
737impl Drop for ComputePassEncoder {
738    fn drop(&mut self) {
739        if self.as_raw().is_null() {
740            return;
741        }
742        unsafe { ffi::wgpuComputePassEncoderRelease(self.raw) };
743    }
744}
745impl Clone for ComputePassEncoder {
746    fn clone(&self) -> Self {
747        unsafe { ffi::wgpuComputePassEncoderAddRef(self.raw) };
748        Self {
749            raw: self.raw,
750            _not_sync: std::marker::PhantomData,
751        }
752    }
753}
754#[derive(Debug)]
755pub struct ComputePipeline {
756    raw: ffi::WGPUComputePipeline,
757}
758impl ComputePipeline {
759    pub(crate) unsafe fn from_raw(raw: ffi::WGPUComputePipeline) -> Self {
760        Self { raw }
761    }
762    pub fn as_raw(&self) -> ffi::WGPUComputePipeline {
763        self.raw
764    }
765    pub fn get_bind_group_layout(&self, group_index: u32) -> BindGroupLayout {
766        let result = unsafe {
767            ffi::wgpuComputePipelineGetBindGroupLayout(self.raw, group_index)
768        };
769        unsafe { BindGroupLayout::from_raw(result) }
770    }
771    pub fn set_label(&self, label: String) -> () {
772        let label_ffi = ffi::WGPUStringView {
773            data: label.as_ptr().cast(),
774            length: label.len(),
775        };
776        unsafe { ffi::wgpuComputePipelineSetLabel(self.raw, label_ffi) };
777        ()
778    }
779}
780impl Drop for ComputePipeline {
781    fn drop(&mut self) {
782        if self.as_raw().is_null() {
783            return;
784        }
785        unsafe { ffi::wgpuComputePipelineRelease(self.raw) };
786    }
787}
788impl Clone for ComputePipeline {
789    fn clone(&self) -> Self {
790        unsafe { ffi::wgpuComputePipelineAddRef(self.raw) };
791        Self { raw: self.raw }
792    }
793}
794unsafe impl Send for ComputePipeline {}
795unsafe impl Sync for ComputePipeline {}
796#[derive(Debug)]
797pub struct Device {
798    raw: ffi::WGPUDevice,
799}
800impl Device {
801    pub(crate) unsafe fn from_raw(raw: ffi::WGPUDevice) -> Self {
802        Self { raw }
803    }
804    pub fn as_raw(&self) -> ffi::WGPUDevice {
805        self.raw
806    }
807    pub fn create_bind_group(&self, descriptor: &BindGroupDescriptor) -> BindGroup {
808        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
809        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
810        let result = unsafe { ffi::wgpuDeviceCreateBindGroup(self.raw, descriptor_ptr) };
811        unsafe { BindGroup::from_raw(result) }
812    }
813    pub fn create_bind_group_layout(
814        &self,
815        descriptor: &BindGroupLayoutDescriptor,
816    ) -> BindGroupLayout {
817        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
818        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
819        let result = unsafe {
820            ffi::wgpuDeviceCreateBindGroupLayout(self.raw, descriptor_ptr)
821        };
822        unsafe { BindGroupLayout::from_raw(result) }
823    }
824    pub fn create_buffer(&self, descriptor: &BufferDescriptor) -> Option<Buffer> {
825        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
826        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
827        let result = unsafe { ffi::wgpuDeviceCreateBuffer(self.raw, descriptor_ptr) };
828        if result.is_null() { None } else { Some(unsafe { Buffer::from_raw(result) }) }
829    }
830    pub fn create_error_buffer(&self, descriptor: &BufferDescriptor) -> Buffer {
831        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
832        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
833        let result = unsafe {
834            ffi::wgpuDeviceCreateErrorBuffer(self.raw, descriptor_ptr)
835        };
836        unsafe { Buffer::from_raw(result) }
837    }
838    pub fn create_command_encoder(
839        &self,
840        descriptor: Option<&CommandEncoderDescriptor>,
841    ) -> CommandEncoder {
842        let mut descriptor_storage = ChainedStructStorage::new();
843        let descriptor_ptr = if let Some(value) = &descriptor {
844            let (descriptor_ffi, storage) = value.to_ffi();
845            descriptor_storage = storage;
846            std::ptr::addr_of!(descriptor_ffi)
847        } else {
848            std::ptr::null()
849        };
850        let result = unsafe {
851            ffi::wgpuDeviceCreateCommandEncoder(self.raw, descriptor_ptr)
852        };
853        unsafe { CommandEncoder::from_raw(result) }
854    }
855    pub fn create_compute_pipeline(
856        &self,
857        descriptor: &ComputePipelineDescriptor,
858    ) -> ComputePipeline {
859        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
860        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
861        let result = unsafe {
862            ffi::wgpuDeviceCreateComputePipeline(self.raw, descriptor_ptr)
863        };
864        unsafe { ComputePipeline::from_raw(result) }
865    }
866    pub fn create_compute_pipeline_async(
867        &self,
868        descriptor: &ComputePipelineDescriptor,
869        callback: impl FnMut(
870            CreatePipelineAsyncStatus,
871            Option<ComputePipeline>,
872            String,
873        ) + Send + 'static,
874    ) -> Future {
875        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
876        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
877        let callback_box: CreateComputePipelineAsyncCallback = Box::new(callback);
878        let callback_box = Box::new(Some(callback_box));
879        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
880        let callback_info_ffi = ffi::WGPUCreateComputePipelineAsyncCallbackInfo {
881            nextInChain: std::ptr::null_mut(),
882            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
883            callback: Some(create_compute_pipeline_async_callback_trampoline),
884            userdata1: callback_userdata,
885            userdata2: std::ptr::null_mut(),
886        };
887        let result = unsafe {
888            ffi::wgpuDeviceCreateComputePipelineAsync(
889                self.raw,
890                descriptor_ptr,
891                callback_info_ffi,
892            )
893        };
894        Future::from_ffi(result)
895    }
896    pub fn create_external_texture(
897        &self,
898        external_texture_descriptor: &ExternalTextureDescriptor,
899    ) -> ExternalTexture {
900        let (external_texture_descriptor_ffi, _external_texture_descriptor_storage) = external_texture_descriptor
901            .to_ffi();
902        let external_texture_descriptor_ptr = std::ptr::addr_of!(
903            external_texture_descriptor_ffi
904        );
905        let result = unsafe {
906            ffi::wgpuDeviceCreateExternalTexture(
907                self.raw,
908                external_texture_descriptor_ptr,
909            )
910        };
911        unsafe { ExternalTexture::from_raw(result) }
912    }
913    pub fn create_error_external_texture(&self) -> ExternalTexture {
914        let result = unsafe { ffi::wgpuDeviceCreateErrorExternalTexture(self.raw) };
915        unsafe { ExternalTexture::from_raw(result) }
916    }
917    pub fn create_pipeline_layout(
918        &self,
919        descriptor: &PipelineLayoutDescriptor,
920    ) -> PipelineLayout {
921        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
922        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
923        let result = unsafe {
924            ffi::wgpuDeviceCreatePipelineLayout(self.raw, descriptor_ptr)
925        };
926        unsafe { PipelineLayout::from_raw(result) }
927    }
928    pub fn create_query_set(&self, descriptor: &QuerySetDescriptor) -> QuerySet {
929        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
930        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
931        let result = unsafe { ffi::wgpuDeviceCreateQuerySet(self.raw, descriptor_ptr) };
932        unsafe { QuerySet::from_raw(result) }
933    }
934    pub fn create_render_pipeline_async(
935        &self,
936        descriptor: &RenderPipelineDescriptor,
937        callback: impl FnMut(
938            CreatePipelineAsyncStatus,
939            Option<RenderPipeline>,
940            String,
941        ) + Send + 'static,
942    ) -> Future {
943        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
944        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
945        let callback_box: CreateRenderPipelineAsyncCallback = Box::new(callback);
946        let callback_box = Box::new(Some(callback_box));
947        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
948        let callback_info_ffi = ffi::WGPUCreateRenderPipelineAsyncCallbackInfo {
949            nextInChain: std::ptr::null_mut(),
950            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
951            callback: Some(create_render_pipeline_async_callback_trampoline),
952            userdata1: callback_userdata,
953            userdata2: std::ptr::null_mut(),
954        };
955        let result = unsafe {
956            ffi::wgpuDeviceCreateRenderPipelineAsync(
957                self.raw,
958                descriptor_ptr,
959                callback_info_ffi,
960            )
961        };
962        Future::from_ffi(result)
963    }
964    pub fn create_render_bundle_encoder(
965        &self,
966        descriptor: &RenderBundleEncoderDescriptor,
967    ) -> RenderBundleEncoder {
968        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
969        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
970        let result = unsafe {
971            ffi::wgpuDeviceCreateRenderBundleEncoder(self.raw, descriptor_ptr)
972        };
973        unsafe { RenderBundleEncoder::from_raw(result) }
974    }
975    pub fn create_render_pipeline(
976        &self,
977        descriptor: &RenderPipelineDescriptor,
978    ) -> RenderPipeline {
979        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
980        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
981        let result = unsafe {
982            ffi::wgpuDeviceCreateRenderPipeline(self.raw, descriptor_ptr)
983        };
984        unsafe { RenderPipeline::from_raw(result) }
985    }
986    pub fn create_sampler(&self, descriptor: Option<&SamplerDescriptor>) -> Sampler {
987        let mut descriptor_storage = ChainedStructStorage::new();
988        let descriptor_ptr = if let Some(value) = &descriptor {
989            let (descriptor_ffi, storage) = value.to_ffi();
990            descriptor_storage = storage;
991            std::ptr::addr_of!(descriptor_ffi)
992        } else {
993            std::ptr::null()
994        };
995        let result = unsafe { ffi::wgpuDeviceCreateSampler(self.raw, descriptor_ptr) };
996        unsafe { Sampler::from_raw(result) }
997    }
998    pub fn create_shader_module(
999        &self,
1000        descriptor: &ShaderModuleDescriptor,
1001    ) -> ShaderModule {
1002        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1003        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1004        let result = unsafe {
1005            ffi::wgpuDeviceCreateShaderModule(self.raw, descriptor_ptr)
1006        };
1007        unsafe { ShaderModule::from_raw(result) }
1008    }
1009    pub fn create_error_shader_module(
1010        &self,
1011        descriptor: &ShaderModuleDescriptor,
1012        error_message: String,
1013    ) -> ShaderModule {
1014        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1015        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1016        let error_message_ffi = ffi::WGPUStringView {
1017            data: error_message.as_ptr().cast(),
1018            length: error_message.len(),
1019        };
1020        let result = unsafe {
1021            ffi::wgpuDeviceCreateErrorShaderModule(
1022                self.raw,
1023                descriptor_ptr,
1024                error_message_ffi,
1025            )
1026        };
1027        unsafe { ShaderModule::from_raw(result) }
1028    }
1029    pub fn create_texture(&self, descriptor: &TextureDescriptor) -> Texture {
1030        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1031        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1032        let result = unsafe { ffi::wgpuDeviceCreateTexture(self.raw, descriptor_ptr) };
1033        unsafe { Texture::from_raw(result) }
1034    }
1035    pub fn create_resource_table(
1036        &self,
1037        descriptor: &ResourceTableDescriptor,
1038    ) -> ResourceTable {
1039        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1040        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1041        let result = unsafe {
1042            ffi::wgpuDeviceCreateResourceTable(self.raw, descriptor_ptr)
1043        };
1044        unsafe { ResourceTable::from_raw(result) }
1045    }
1046    pub fn import_shared_buffer_memory(
1047        &self,
1048        descriptor: &SharedBufferMemoryDescriptor,
1049    ) -> SharedBufferMemory {
1050        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1051        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1052        let result = unsafe {
1053            ffi::wgpuDeviceImportSharedBufferMemory(self.raw, descriptor_ptr)
1054        };
1055        unsafe { SharedBufferMemory::from_raw(result) }
1056    }
1057    pub fn import_shared_texture_memory(
1058        &self,
1059        descriptor: &SharedTextureMemoryDescriptor,
1060    ) -> SharedTextureMemory {
1061        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1062        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1063        let result = unsafe {
1064            ffi::wgpuDeviceImportSharedTextureMemory(self.raw, descriptor_ptr)
1065        };
1066        unsafe { SharedTextureMemory::from_raw(result) }
1067    }
1068    pub fn import_shared_fence(
1069        &self,
1070        descriptor: &SharedFenceDescriptor,
1071    ) -> SharedFence {
1072        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1073        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1074        let result = unsafe {
1075            ffi::wgpuDeviceImportSharedFence(self.raw, descriptor_ptr)
1076        };
1077        unsafe { SharedFence::from_raw(result) }
1078    }
1079    pub fn create_error_texture(&self, descriptor: &TextureDescriptor) -> Texture {
1080        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1081        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1082        let result = unsafe {
1083            ffi::wgpuDeviceCreateErrorTexture(self.raw, descriptor_ptr)
1084        };
1085        unsafe { Texture::from_raw(result) }
1086    }
1087    pub fn destroy(&self) -> () {
1088        unsafe { ffi::wgpuDeviceDestroy(self.raw) };
1089        ()
1090    }
1091    pub fn get_a_hardware_buffer_properties(
1092        &self,
1093        handle: *mut std::ffi::c_void,
1094        properties: &mut AHardwareBufferProperties,
1095    ) -> Status {
1096        let (mut properties_ffi, _properties_storage) = properties.to_ffi();
1097        let properties_ptr = std::ptr::addr_of_mut!(properties_ffi);
1098        let result = unsafe {
1099            ffi::wgpuDeviceGetAHardwareBufferProperties(self.raw, handle, properties_ptr)
1100        };
1101        *properties = AHardwareBufferProperties::from_ffi(properties_ffi);
1102        result.into()
1103    }
1104    pub fn get_limits(&self, limits: &mut Limits) -> Status {
1105        let (mut limits_ffi, _limits_storage) = limits.to_ffi();
1106        let limits_ptr = std::ptr::addr_of_mut!(limits_ffi);
1107        let result = unsafe { ffi::wgpuDeviceGetLimits(self.raw, limits_ptr) };
1108        *limits = Limits::from_ffi(limits_ffi);
1109        result.into()
1110    }
1111    pub fn get_lost_future(&self) -> Future {
1112        let result = unsafe { ffi::wgpuDeviceGetLostFuture(self.raw) };
1113        Future::from_ffi(result)
1114    }
1115    pub fn has_feature(&self, feature: FeatureName) -> bool {
1116        let feature_ffi: ffi::WGPUFeatureName = feature.into();
1117        let result = unsafe { ffi::wgpuDeviceHasFeature(self.raw, feature_ffi) };
1118        result != 0
1119    }
1120    pub fn get_features(&self, features: &mut SupportedFeatures) -> () {
1121        let (mut features_ffi, _features_storage) = features.to_ffi();
1122        let features_ptr = std::ptr::addr_of_mut!(features_ffi);
1123        unsafe { ffi::wgpuDeviceGetFeatures(self.raw, features_ptr) };
1124        *features = SupportedFeatures::from_ffi(features_ffi);
1125        ()
1126    }
1127    pub fn get_adapter_info(&self, adapter_info: &mut AdapterInfo) -> Status {
1128        let (mut adapter_info_ffi, _adapter_info_storage) = adapter_info.to_ffi();
1129        let adapter_info_ptr = std::ptr::addr_of_mut!(adapter_info_ffi);
1130        let result = unsafe {
1131            ffi::wgpuDeviceGetAdapterInfo(self.raw, adapter_info_ptr)
1132        };
1133        *adapter_info = AdapterInfo::from_ffi(adapter_info_ffi);
1134        result.into()
1135    }
1136    pub fn get_adapter(&self) -> Adapter {
1137        let result = unsafe { ffi::wgpuDeviceGetAdapter(self.raw) };
1138        unsafe { Adapter::from_raw(result) }
1139    }
1140    pub fn get_queue(&self) -> Queue {
1141        let result = unsafe { ffi::wgpuDeviceGetQueue(self.raw) };
1142        unsafe { Queue::from_raw(result) }
1143    }
1144    pub fn inject_error(&self, r#type: ErrorType, message: String) -> () {
1145        let r#type_ffi: ffi::WGPUErrorType = r#type.into();
1146        let message_ffi = ffi::WGPUStringView {
1147            data: message.as_ptr().cast(),
1148            length: message.len(),
1149        };
1150        unsafe { ffi::wgpuDeviceInjectError(self.raw, r#type_ffi, message_ffi) };
1151        ()
1152    }
1153    pub fn force_loss(&self, r#type: DeviceLostReason, message: String) -> () {
1154        let r#type_ffi: ffi::WGPUDeviceLostReason = r#type.into();
1155        let message_ffi = ffi::WGPUStringView {
1156            data: message.as_ptr().cast(),
1157            length: message.len(),
1158        };
1159        unsafe { ffi::wgpuDeviceForceLoss(self.raw, r#type_ffi, message_ffi) };
1160        ()
1161    }
1162    pub fn tick(&self) -> () {
1163        unsafe { ffi::wgpuDeviceTick(self.raw) };
1164        ()
1165    }
1166    pub fn set_logging_callback(
1167        &self,
1168        callback: impl FnMut(LoggingType, String) + Send + 'static,
1169    ) -> () {
1170        let callback_box: LoggingCallback = Box::new(callback);
1171        let callback_box = Box::new(Some(callback_box));
1172        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
1173        let callback_info_ffi = ffi::WGPULoggingCallbackInfo {
1174            nextInChain: std::ptr::null_mut(),
1175            callback: Some(logging_callback_trampoline),
1176            userdata1: callback_userdata,
1177            userdata2: std::ptr::null_mut(),
1178        };
1179        unsafe { ffi::wgpuDeviceSetLoggingCallback(self.raw, callback_info_ffi) };
1180        ()
1181    }
1182    pub fn push_error_scope(&self, filter: ErrorFilter) -> () {
1183        let filter_ffi: ffi::WGPUErrorFilter = filter.into();
1184        unsafe { ffi::wgpuDevicePushErrorScope(self.raw, filter_ffi) };
1185        ()
1186    }
1187    pub fn pop_error_scope(
1188        &self,
1189        callback: impl FnMut(PopErrorScopeStatus, ErrorType, String) + Send + 'static,
1190    ) -> Future {
1191        let callback_box: PopErrorScopeCallback = Box::new(callback);
1192        let callback_box = Box::new(Some(callback_box));
1193        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
1194        let callback_info_ffi = ffi::WGPUPopErrorScopeCallbackInfo {
1195            nextInChain: std::ptr::null_mut(),
1196            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
1197            callback: Some(pop_error_scope_callback_trampoline),
1198            userdata1: callback_userdata,
1199            userdata2: std::ptr::null_mut(),
1200        };
1201        let result = unsafe {
1202            ffi::wgpuDevicePopErrorScope(self.raw, callback_info_ffi)
1203        };
1204        Future::from_ffi(result)
1205    }
1206    pub fn set_label(&self, label: String) -> () {
1207        let label_ffi = ffi::WGPUStringView {
1208            data: label.as_ptr().cast(),
1209            length: label.len(),
1210        };
1211        unsafe { ffi::wgpuDeviceSetLabel(self.raw, label_ffi) };
1212        ()
1213    }
1214    pub fn validate_texture_descriptor(&self, descriptor: &TextureDescriptor) -> () {
1215        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1216        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1217        unsafe { ffi::wgpuDeviceValidateTextureDescriptor(self.raw, descriptor_ptr) };
1218        ()
1219    }
1220}
1221impl Drop for Device {
1222    fn drop(&mut self) {
1223        if self.as_raw().is_null() {
1224            return;
1225        }
1226        unsafe { ffi::wgpuDeviceRelease(self.raw) };
1227    }
1228}
1229impl Clone for Device {
1230    fn clone(&self) -> Self {
1231        unsafe { ffi::wgpuDeviceAddRef(self.raw) };
1232        Self { raw: self.raw }
1233    }
1234}
1235unsafe impl Send for Device {}
1236unsafe impl Sync for Device {}
1237#[derive(Debug)]
1238pub struct ExternalTexture {
1239    raw: ffi::WGPUExternalTexture,
1240}
1241impl ExternalTexture {
1242    pub(crate) unsafe fn from_raw(raw: ffi::WGPUExternalTexture) -> Self {
1243        Self { raw }
1244    }
1245    pub fn as_raw(&self) -> ffi::WGPUExternalTexture {
1246        self.raw
1247    }
1248    pub fn set_label(&self, label: String) -> () {
1249        let label_ffi = ffi::WGPUStringView {
1250            data: label.as_ptr().cast(),
1251            length: label.len(),
1252        };
1253        unsafe { ffi::wgpuExternalTextureSetLabel(self.raw, label_ffi) };
1254        ()
1255    }
1256    pub fn destroy(&self) -> () {
1257        unsafe { ffi::wgpuExternalTextureDestroy(self.raw) };
1258        ()
1259    }
1260    pub fn expire(&self) -> () {
1261        unsafe { ffi::wgpuExternalTextureExpire(self.raw) };
1262        ()
1263    }
1264    pub fn refresh(&self) -> () {
1265        unsafe { ffi::wgpuExternalTextureRefresh(self.raw) };
1266        ()
1267    }
1268}
1269impl Drop for ExternalTexture {
1270    fn drop(&mut self) {
1271        if self.as_raw().is_null() {
1272            return;
1273        }
1274        unsafe { ffi::wgpuExternalTextureRelease(self.raw) };
1275    }
1276}
1277impl Clone for ExternalTexture {
1278    fn clone(&self) -> Self {
1279        unsafe { ffi::wgpuExternalTextureAddRef(self.raw) };
1280        Self { raw: self.raw }
1281    }
1282}
1283unsafe impl Send for ExternalTexture {}
1284unsafe impl Sync for ExternalTexture {}
1285#[derive(Debug)]
1286pub struct Instance {
1287    raw: ffi::WGPUInstance,
1288    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
1289}
1290impl Instance {
1291    pub(crate) unsafe fn from_raw(raw: ffi::WGPUInstance) -> Self {
1292        Self {
1293            raw,
1294            _not_sync: std::marker::PhantomData,
1295        }
1296    }
1297    pub fn as_raw(&self) -> ffi::WGPUInstance {
1298        self.raw
1299    }
1300    pub fn new(descriptor: Option<&InstanceDescriptor>) -> Self {
1301        let mut descriptor_storage = ChainedStructStorage::new();
1302        let descriptor_ptr = if let Some(value) = &descriptor {
1303            let (descriptor_ffi, storage) = value.to_ffi();
1304            descriptor_storage = storage;
1305            std::ptr::addr_of!(descriptor_ffi)
1306        } else {
1307            std::ptr::null()
1308        };
1309        let result = unsafe { ffi::wgpuCreateInstance(descriptor_ptr) };
1310        unsafe { Instance::from_raw(result) }
1311    }
1312    pub fn create_surface(&self, descriptor: &SurfaceDescriptor) -> Surface {
1313        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
1314        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
1315        let result = unsafe { ffi::wgpuInstanceCreateSurface(self.raw, descriptor_ptr) };
1316        unsafe { Surface::from_raw(result) }
1317    }
1318    pub fn process_events(&self) -> () {
1319        unsafe { ffi::wgpuInstanceProcessEvents(self.raw) };
1320        ()
1321    }
1322    pub fn wait_any(
1323        &self,
1324        mut futures: Option<&mut [FutureWaitInfo]>,
1325        timeout_ns: u64,
1326    ) -> WaitStatus {
1327        let mut futures_raw: Vec<ffi::WGPUFutureWaitInfo> = Vec::new();
1328        let mut futures_storage: Vec<ChainedStructStorage> = Vec::new();
1329        let futures_ptr = if let Some(value) = futures.as_deref() {
1330            for item in value {
1331                let (raw, storage) = item.to_ffi();
1332                futures_raw.push(raw);
1333                futures_storage.push(storage);
1334            }
1335            futures_raw.as_mut_ptr()
1336        } else {
1337            std::ptr::null_mut()
1338        };
1339        let result = unsafe {
1340            ffi::wgpuInstanceWaitAny(
1341                self.raw,
1342                futures.as_deref().map(|v| v.len()).unwrap_or(0),
1343                futures_ptr,
1344                timeout_ns,
1345            )
1346        };
1347        result.into()
1348    }
1349    pub fn request_adapter(
1350        &self,
1351        options: Option<&RequestAdapterOptions>,
1352        callback: impl FnMut(
1353            RequestAdapterStatus,
1354            Option<Adapter>,
1355            String,
1356        ) + Send + 'static,
1357    ) -> Future {
1358        let mut options_storage = ChainedStructStorage::new();
1359        let options_ptr = if let Some(value) = &options {
1360            let (options_ffi, storage) = value.to_ffi();
1361            options_storage = storage;
1362            std::ptr::addr_of!(options_ffi)
1363        } else {
1364            std::ptr::null()
1365        };
1366        let callback_box: RequestAdapterCallback = Box::new(callback);
1367        let callback_box = Box::new(Some(callback_box));
1368        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
1369        let callback_info_ffi = ffi::WGPURequestAdapterCallbackInfo {
1370            nextInChain: std::ptr::null_mut(),
1371            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
1372            callback: Some(request_adapter_callback_trampoline),
1373            userdata1: callback_userdata,
1374            userdata2: std::ptr::null_mut(),
1375        };
1376        let result = unsafe {
1377            ffi::wgpuInstanceRequestAdapter(self.raw, options_ptr, callback_info_ffi)
1378        };
1379        Future::from_ffi(result)
1380    }
1381    pub fn has_wgsl_language_feature(&self, feature: WGSLLanguageFeatureName) -> bool {
1382        let feature_ffi: ffi::WGPUWGSLLanguageFeatureName = feature.into();
1383        let result = unsafe {
1384            ffi::wgpuInstanceHasWGSLLanguageFeature(self.raw, feature_ffi)
1385        };
1386        result != 0
1387    }
1388    pub fn get_wgsl_language_features(
1389        &self,
1390        features: &mut SupportedWGSLLanguageFeatures,
1391    ) -> () {
1392        let (mut features_ffi, _features_storage) = features.to_ffi();
1393        let features_ptr = std::ptr::addr_of_mut!(features_ffi);
1394        unsafe { ffi::wgpuInstanceGetWGSLLanguageFeatures(self.raw, features_ptr) };
1395        *features = SupportedWGSLLanguageFeatures::from_ffi(features_ffi);
1396        ()
1397    }
1398}
1399impl Drop for Instance {
1400    fn drop(&mut self) {
1401        if self.as_raw().is_null() {
1402            return;
1403        }
1404        unsafe { ffi::wgpuInstanceRelease(self.raw) };
1405    }
1406}
1407impl Clone for Instance {
1408    fn clone(&self) -> Self {
1409        unsafe { ffi::wgpuInstanceAddRef(self.raw) };
1410        Self {
1411            raw: self.raw,
1412            _not_sync: std::marker::PhantomData,
1413        }
1414    }
1415}
1416#[derive(Debug)]
1417pub struct PipelineLayout {
1418    raw: ffi::WGPUPipelineLayout,
1419}
1420impl PipelineLayout {
1421    pub(crate) unsafe fn from_raw(raw: ffi::WGPUPipelineLayout) -> Self {
1422        Self { raw }
1423    }
1424    pub fn as_raw(&self) -> ffi::WGPUPipelineLayout {
1425        self.raw
1426    }
1427    pub fn set_label(&self, label: String) -> () {
1428        let label_ffi = ffi::WGPUStringView {
1429            data: label.as_ptr().cast(),
1430            length: label.len(),
1431        };
1432        unsafe { ffi::wgpuPipelineLayoutSetLabel(self.raw, label_ffi) };
1433        ()
1434    }
1435}
1436impl Drop for PipelineLayout {
1437    fn drop(&mut self) {
1438        if self.as_raw().is_null() {
1439            return;
1440        }
1441        unsafe { ffi::wgpuPipelineLayoutRelease(self.raw) };
1442    }
1443}
1444impl Clone for PipelineLayout {
1445    fn clone(&self) -> Self {
1446        unsafe { ffi::wgpuPipelineLayoutAddRef(self.raw) };
1447        Self { raw: self.raw }
1448    }
1449}
1450unsafe impl Send for PipelineLayout {}
1451unsafe impl Sync for PipelineLayout {}
1452#[derive(Debug)]
1453pub struct QuerySet {
1454    raw: ffi::WGPUQuerySet,
1455}
1456impl QuerySet {
1457    pub(crate) unsafe fn from_raw(raw: ffi::WGPUQuerySet) -> Self {
1458        Self { raw }
1459    }
1460    pub fn as_raw(&self) -> ffi::WGPUQuerySet {
1461        self.raw
1462    }
1463    pub fn set_label(&self, label: String) -> () {
1464        let label_ffi = ffi::WGPUStringView {
1465            data: label.as_ptr().cast(),
1466            length: label.len(),
1467        };
1468        unsafe { ffi::wgpuQuerySetSetLabel(self.raw, label_ffi) };
1469        ()
1470    }
1471    pub fn get_type(&self) -> QueryType {
1472        let result = unsafe { ffi::wgpuQuerySetGetType(self.raw) };
1473        result.into()
1474    }
1475    pub fn get_count(&self) -> u32 {
1476        let result = unsafe { ffi::wgpuQuerySetGetCount(self.raw) };
1477        result
1478    }
1479    pub fn destroy(&self) -> () {
1480        unsafe { ffi::wgpuQuerySetDestroy(self.raw) };
1481        ()
1482    }
1483}
1484impl Drop for QuerySet {
1485    fn drop(&mut self) {
1486        if self.as_raw().is_null() {
1487            return;
1488        }
1489        unsafe { ffi::wgpuQuerySetRelease(self.raw) };
1490    }
1491}
1492impl Clone for QuerySet {
1493    fn clone(&self) -> Self {
1494        unsafe { ffi::wgpuQuerySetAddRef(self.raw) };
1495        Self { raw: self.raw }
1496    }
1497}
1498unsafe impl Send for QuerySet {}
1499unsafe impl Sync for QuerySet {}
1500#[derive(Debug)]
1501pub struct Queue {
1502    raw: ffi::WGPUQueue,
1503}
1504impl Queue {
1505    pub(crate) unsafe fn from_raw(raw: ffi::WGPUQueue) -> Self {
1506        Self { raw }
1507    }
1508    pub fn as_raw(&self) -> ffi::WGPUQueue {
1509        self.raw
1510    }
1511    pub fn submit(&self, commands: &[CommandBuffer]) -> () {
1512        let mut commands_raw: Vec<ffi::WGPUCommandBuffer> = commands
1513            .iter()
1514            .map(|v| v.as_raw())
1515            .collect();
1516        let commands_ptr = commands_raw.as_ptr();
1517        unsafe { ffi::wgpuQueueSubmit(self.raw, commands.len(), commands_ptr) };
1518        ()
1519    }
1520    pub fn on_submitted_work_done(
1521        &self,
1522        callback: impl FnMut(QueueWorkDoneStatus, String) + Send + 'static,
1523    ) -> Future {
1524        let callback_box: QueueWorkDoneCallback = Box::new(callback);
1525        let callback_box = Box::new(Some(callback_box));
1526        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
1527        let callback_info_ffi = ffi::WGPUQueueWorkDoneCallbackInfo {
1528            nextInChain: std::ptr::null_mut(),
1529            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
1530            callback: Some(queue_work_done_callback_trampoline),
1531            userdata1: callback_userdata,
1532            userdata2: std::ptr::null_mut(),
1533        };
1534        let result = unsafe {
1535            ffi::wgpuQueueOnSubmittedWorkDone(self.raw, callback_info_ffi)
1536        };
1537        Future::from_ffi(result)
1538    }
1539    pub fn write_buffer(
1540        &self,
1541        buffer: Buffer,
1542        buffer_offset: u64,
1543        data: &[std::ffi::c_void],
1544    ) -> () {
1545        let data_ptr = data.as_ptr();
1546        unsafe {
1547            ffi::wgpuQueueWriteBuffer(
1548                self.raw,
1549                buffer.as_raw(),
1550                buffer_offset,
1551                data_ptr,
1552                data.len(),
1553            )
1554        };
1555        ()
1556    }
1557    pub fn write_texture(
1558        &self,
1559        destination: &TexelCopyTextureInfo,
1560        data: &[std::ffi::c_void],
1561        data_layout: &TexelCopyBufferLayout,
1562        write_size: &Extent3D,
1563    ) -> () {
1564        let (destination_ffi, _destination_storage) = destination.to_ffi();
1565        let destination_ptr = std::ptr::addr_of!(destination_ffi);
1566        let data_ptr = data.as_ptr();
1567        let (data_layout_ffi, _data_layout_storage) = data_layout.to_ffi();
1568        let data_layout_ptr = std::ptr::addr_of!(data_layout_ffi);
1569        let (write_size_ffi, _write_size_storage) = write_size.to_ffi();
1570        let write_size_ptr = std::ptr::addr_of!(write_size_ffi);
1571        unsafe {
1572            ffi::wgpuQueueWriteTexture(
1573                self.raw,
1574                destination_ptr,
1575                data_ptr,
1576                data.len(),
1577                data_layout_ptr,
1578                write_size_ptr,
1579            )
1580        };
1581        ()
1582    }
1583    pub fn copy_texture_for_browser(
1584        &self,
1585        source: &TexelCopyTextureInfo,
1586        destination: &TexelCopyTextureInfo,
1587        copy_size: &Extent3D,
1588        options: &CopyTextureForBrowserOptions,
1589    ) -> () {
1590        let (source_ffi, _source_storage) = source.to_ffi();
1591        let source_ptr = std::ptr::addr_of!(source_ffi);
1592        let (destination_ffi, _destination_storage) = destination.to_ffi();
1593        let destination_ptr = std::ptr::addr_of!(destination_ffi);
1594        let (copy_size_ffi, _copy_size_storage) = copy_size.to_ffi();
1595        let copy_size_ptr = std::ptr::addr_of!(copy_size_ffi);
1596        let (options_ffi, _options_storage) = options.to_ffi();
1597        let options_ptr = std::ptr::addr_of!(options_ffi);
1598        unsafe {
1599            ffi::wgpuQueueCopyTextureForBrowser(
1600                self.raw,
1601                source_ptr,
1602                destination_ptr,
1603                copy_size_ptr,
1604                options_ptr,
1605            )
1606        };
1607        ()
1608    }
1609    pub fn copy_external_texture_for_browser(
1610        &self,
1611        source: &ImageCopyExternalTexture,
1612        destination: &TexelCopyTextureInfo,
1613        copy_size: &Extent3D,
1614        options: &CopyTextureForBrowserOptions,
1615    ) -> () {
1616        let (source_ffi, _source_storage) = source.to_ffi();
1617        let source_ptr = std::ptr::addr_of!(source_ffi);
1618        let (destination_ffi, _destination_storage) = destination.to_ffi();
1619        let destination_ptr = std::ptr::addr_of!(destination_ffi);
1620        let (copy_size_ffi, _copy_size_storage) = copy_size.to_ffi();
1621        let copy_size_ptr = std::ptr::addr_of!(copy_size_ffi);
1622        let (options_ffi, _options_storage) = options.to_ffi();
1623        let options_ptr = std::ptr::addr_of!(options_ffi);
1624        unsafe {
1625            ffi::wgpuQueueCopyExternalTextureForBrowser(
1626                self.raw,
1627                source_ptr,
1628                destination_ptr,
1629                copy_size_ptr,
1630                options_ptr,
1631            )
1632        };
1633        ()
1634    }
1635    pub fn set_label(&self, label: String) -> () {
1636        let label_ffi = ffi::WGPUStringView {
1637            data: label.as_ptr().cast(),
1638            length: label.len(),
1639        };
1640        unsafe { ffi::wgpuQueueSetLabel(self.raw, label_ffi) };
1641        ()
1642    }
1643}
1644impl Drop for Queue {
1645    fn drop(&mut self) {
1646        if self.as_raw().is_null() {
1647            return;
1648        }
1649        unsafe { ffi::wgpuQueueRelease(self.raw) };
1650    }
1651}
1652impl Clone for Queue {
1653    fn clone(&self) -> Self {
1654        unsafe { ffi::wgpuQueueAddRef(self.raw) };
1655        Self { raw: self.raw }
1656    }
1657}
1658unsafe impl Send for Queue {}
1659unsafe impl Sync for Queue {}
1660#[derive(Debug)]
1661pub struct RenderBundle {
1662    raw: ffi::WGPURenderBundle,
1663}
1664impl RenderBundle {
1665    pub(crate) unsafe fn from_raw(raw: ffi::WGPURenderBundle) -> Self {
1666        Self { raw }
1667    }
1668    pub fn as_raw(&self) -> ffi::WGPURenderBundle {
1669        self.raw
1670    }
1671    pub fn set_label(&self, label: String) -> () {
1672        let label_ffi = ffi::WGPUStringView {
1673            data: label.as_ptr().cast(),
1674            length: label.len(),
1675        };
1676        unsafe { ffi::wgpuRenderBundleSetLabel(self.raw, label_ffi) };
1677        ()
1678    }
1679}
1680impl Drop for RenderBundle {
1681    fn drop(&mut self) {
1682        if self.as_raw().is_null() {
1683            return;
1684        }
1685        unsafe { ffi::wgpuRenderBundleRelease(self.raw) };
1686    }
1687}
1688impl Clone for RenderBundle {
1689    fn clone(&self) -> Self {
1690        unsafe { ffi::wgpuRenderBundleAddRef(self.raw) };
1691        Self { raw: self.raw }
1692    }
1693}
1694unsafe impl Send for RenderBundle {}
1695unsafe impl Sync for RenderBundle {}
1696#[derive(Debug)]
1697pub struct RenderBundleEncoder {
1698    raw: ffi::WGPURenderBundleEncoder,
1699    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
1700}
1701impl RenderBundleEncoder {
1702    pub(crate) unsafe fn from_raw(raw: ffi::WGPURenderBundleEncoder) -> Self {
1703        Self {
1704            raw,
1705            _not_sync: std::marker::PhantomData,
1706        }
1707    }
1708    pub fn as_raw(&self) -> ffi::WGPURenderBundleEncoder {
1709        self.raw
1710    }
1711    pub fn set_pipeline(&self, pipeline: RenderPipeline) -> () {
1712        unsafe { ffi::wgpuRenderBundleEncoderSetPipeline(self.raw, pipeline.as_raw()) };
1713        ()
1714    }
1715    pub fn set_bind_group(
1716        &self,
1717        group_index: u32,
1718        group: Option<BindGroup>,
1719        dynamic_offsets: &[u32],
1720    ) -> () {
1721        let group_raw = group
1722            .as_ref()
1723            .map(|v| v.as_raw())
1724            .unwrap_or(std::ptr::null_mut());
1725        let dynamic_offsets_ptr = dynamic_offsets.as_ptr();
1726        unsafe {
1727            ffi::wgpuRenderBundleEncoderSetBindGroup(
1728                self.raw,
1729                group_index,
1730                group_raw,
1731                dynamic_offsets.len(),
1732                dynamic_offsets_ptr,
1733            )
1734        };
1735        ()
1736    }
1737    pub fn draw(
1738        &self,
1739        vertex_count: u32,
1740        instance_count: u32,
1741        first_vertex: u32,
1742        first_instance: u32,
1743    ) -> () {
1744        unsafe {
1745            ffi::wgpuRenderBundleEncoderDraw(
1746                self.raw,
1747                vertex_count,
1748                instance_count,
1749                first_vertex,
1750                first_instance,
1751            )
1752        };
1753        ()
1754    }
1755    pub fn draw_indexed(
1756        &self,
1757        index_count: u32,
1758        instance_count: u32,
1759        first_index: u32,
1760        base_vertex: i32,
1761        first_instance: u32,
1762    ) -> () {
1763        unsafe {
1764            ffi::wgpuRenderBundleEncoderDrawIndexed(
1765                self.raw,
1766                index_count,
1767                instance_count,
1768                first_index,
1769                base_vertex,
1770                first_instance,
1771            )
1772        };
1773        ()
1774    }
1775    pub fn draw_indirect(&self, indirect_buffer: Buffer, indirect_offset: u64) -> () {
1776        unsafe {
1777            ffi::wgpuRenderBundleEncoderDrawIndirect(
1778                self.raw,
1779                indirect_buffer.as_raw(),
1780                indirect_offset,
1781            )
1782        };
1783        ()
1784    }
1785    pub fn draw_indexed_indirect(
1786        &self,
1787        indirect_buffer: Buffer,
1788        indirect_offset: u64,
1789    ) -> () {
1790        unsafe {
1791            ffi::wgpuRenderBundleEncoderDrawIndexedIndirect(
1792                self.raw,
1793                indirect_buffer.as_raw(),
1794                indirect_offset,
1795            )
1796        };
1797        ()
1798    }
1799    pub fn insert_debug_marker(&self, marker_label: String) -> () {
1800        let marker_label_ffi = ffi::WGPUStringView {
1801            data: marker_label.as_ptr().cast(),
1802            length: marker_label.len(),
1803        };
1804        unsafe {
1805            ffi::wgpuRenderBundleEncoderInsertDebugMarker(self.raw, marker_label_ffi)
1806        };
1807        ()
1808    }
1809    pub fn pop_debug_group(&self) -> () {
1810        unsafe { ffi::wgpuRenderBundleEncoderPopDebugGroup(self.raw) };
1811        ()
1812    }
1813    pub fn push_debug_group(&self, group_label: String) -> () {
1814        let group_label_ffi = ffi::WGPUStringView {
1815            data: group_label.as_ptr().cast(),
1816            length: group_label.len(),
1817        };
1818        unsafe { ffi::wgpuRenderBundleEncoderPushDebugGroup(self.raw, group_label_ffi) };
1819        ()
1820    }
1821    pub fn set_vertex_buffer(
1822        &self,
1823        slot: u32,
1824        buffer: Option<Buffer>,
1825        offset: u64,
1826        size: u64,
1827    ) -> () {
1828        let buffer_raw = buffer
1829            .as_ref()
1830            .map(|v| v.as_raw())
1831            .unwrap_or(std::ptr::null_mut());
1832        unsafe {
1833            ffi::wgpuRenderBundleEncoderSetVertexBuffer(
1834                self.raw,
1835                slot,
1836                buffer_raw,
1837                offset,
1838                size,
1839            )
1840        };
1841        ()
1842    }
1843    pub fn set_index_buffer(
1844        &self,
1845        buffer: Buffer,
1846        format: IndexFormat,
1847        offset: u64,
1848        size: u64,
1849    ) -> () {
1850        let format_ffi: ffi::WGPUIndexFormat = format.into();
1851        unsafe {
1852            ffi::wgpuRenderBundleEncoderSetIndexBuffer(
1853                self.raw,
1854                buffer.as_raw(),
1855                format_ffi,
1856                offset,
1857                size,
1858            )
1859        };
1860        ()
1861    }
1862    pub fn finish(&self, descriptor: Option<&RenderBundleDescriptor>) -> RenderBundle {
1863        let mut descriptor_storage = ChainedStructStorage::new();
1864        let descriptor_ptr = if let Some(value) = &descriptor {
1865            let (descriptor_ffi, storage) = value.to_ffi();
1866            descriptor_storage = storage;
1867            std::ptr::addr_of!(descriptor_ffi)
1868        } else {
1869            std::ptr::null()
1870        };
1871        let result = unsafe {
1872            ffi::wgpuRenderBundleEncoderFinish(self.raw, descriptor_ptr)
1873        };
1874        unsafe { RenderBundle::from_raw(result) }
1875    }
1876    pub fn set_label(&self, label: String) -> () {
1877        let label_ffi = ffi::WGPUStringView {
1878            data: label.as_ptr().cast(),
1879            length: label.len(),
1880        };
1881        unsafe { ffi::wgpuRenderBundleEncoderSetLabel(self.raw, label_ffi) };
1882        ()
1883    }
1884    pub fn set_immediates(&self, offset: u32, data: &[std::ffi::c_void]) -> () {
1885        let data_ptr = data.as_ptr();
1886        unsafe {
1887            ffi::wgpuRenderBundleEncoderSetImmediates(
1888                self.raw,
1889                offset,
1890                data_ptr,
1891                data.len(),
1892            )
1893        };
1894        ()
1895    }
1896}
1897impl Drop for RenderBundleEncoder {
1898    fn drop(&mut self) {
1899        if self.as_raw().is_null() {
1900            return;
1901        }
1902        unsafe { ffi::wgpuRenderBundleEncoderRelease(self.raw) };
1903    }
1904}
1905impl Clone for RenderBundleEncoder {
1906    fn clone(&self) -> Self {
1907        unsafe { ffi::wgpuRenderBundleEncoderAddRef(self.raw) };
1908        Self {
1909            raw: self.raw,
1910            _not_sync: std::marker::PhantomData,
1911        }
1912    }
1913}
1914#[derive(Debug)]
1915pub struct RenderPassEncoder {
1916    raw: ffi::WGPURenderPassEncoder,
1917    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
1918}
1919impl RenderPassEncoder {
1920    pub(crate) unsafe fn from_raw(raw: ffi::WGPURenderPassEncoder) -> Self {
1921        Self {
1922            raw,
1923            _not_sync: std::marker::PhantomData,
1924        }
1925    }
1926    pub fn as_raw(&self) -> ffi::WGPURenderPassEncoder {
1927        self.raw
1928    }
1929    pub fn set_pipeline(&self, pipeline: RenderPipeline) -> () {
1930        unsafe { ffi::wgpuRenderPassEncoderSetPipeline(self.raw, pipeline.as_raw()) };
1931        ()
1932    }
1933    pub fn set_bind_group(
1934        &self,
1935        group_index: u32,
1936        group: Option<BindGroup>,
1937        dynamic_offsets: &[u32],
1938    ) -> () {
1939        let group_raw = group
1940            .as_ref()
1941            .map(|v| v.as_raw())
1942            .unwrap_or(std::ptr::null_mut());
1943        let dynamic_offsets_ptr = dynamic_offsets.as_ptr();
1944        unsafe {
1945            ffi::wgpuRenderPassEncoderSetBindGroup(
1946                self.raw,
1947                group_index,
1948                group_raw,
1949                dynamic_offsets.len(),
1950                dynamic_offsets_ptr,
1951            )
1952        };
1953        ()
1954    }
1955    pub fn draw(
1956        &self,
1957        vertex_count: u32,
1958        instance_count: u32,
1959        first_vertex: u32,
1960        first_instance: u32,
1961    ) -> () {
1962        unsafe {
1963            ffi::wgpuRenderPassEncoderDraw(
1964                self.raw,
1965                vertex_count,
1966                instance_count,
1967                first_vertex,
1968                first_instance,
1969            )
1970        };
1971        ()
1972    }
1973    pub fn draw_indexed(
1974        &self,
1975        index_count: u32,
1976        instance_count: u32,
1977        first_index: u32,
1978        base_vertex: i32,
1979        first_instance: u32,
1980    ) -> () {
1981        unsafe {
1982            ffi::wgpuRenderPassEncoderDrawIndexed(
1983                self.raw,
1984                index_count,
1985                instance_count,
1986                first_index,
1987                base_vertex,
1988                first_instance,
1989            )
1990        };
1991        ()
1992    }
1993    pub fn draw_indirect(&self, indirect_buffer: Buffer, indirect_offset: u64) -> () {
1994        unsafe {
1995            ffi::wgpuRenderPassEncoderDrawIndirect(
1996                self.raw,
1997                indirect_buffer.as_raw(),
1998                indirect_offset,
1999            )
2000        };
2001        ()
2002    }
2003    pub fn draw_indexed_indirect(
2004        &self,
2005        indirect_buffer: Buffer,
2006        indirect_offset: u64,
2007    ) -> () {
2008        unsafe {
2009            ffi::wgpuRenderPassEncoderDrawIndexedIndirect(
2010                self.raw,
2011                indirect_buffer.as_raw(),
2012                indirect_offset,
2013            )
2014        };
2015        ()
2016    }
2017    pub fn multi_draw_indirect(
2018        &self,
2019        indirect_buffer: Buffer,
2020        indirect_offset: u64,
2021        max_draw_count: u32,
2022        draw_count_buffer: Option<Buffer>,
2023        draw_count_buffer_offset: u64,
2024    ) -> () {
2025        let draw_count_buffer_raw = draw_count_buffer
2026            .as_ref()
2027            .map(|v| v.as_raw())
2028            .unwrap_or(std::ptr::null_mut());
2029        unsafe {
2030            ffi::wgpuRenderPassEncoderMultiDrawIndirect(
2031                self.raw,
2032                indirect_buffer.as_raw(),
2033                indirect_offset,
2034                max_draw_count,
2035                draw_count_buffer_raw,
2036                draw_count_buffer_offset,
2037            )
2038        };
2039        ()
2040    }
2041    pub fn multi_draw_indexed_indirect(
2042        &self,
2043        indirect_buffer: Buffer,
2044        indirect_offset: u64,
2045        max_draw_count: u32,
2046        draw_count_buffer: Option<Buffer>,
2047        draw_count_buffer_offset: u64,
2048    ) -> () {
2049        let draw_count_buffer_raw = draw_count_buffer
2050            .as_ref()
2051            .map(|v| v.as_raw())
2052            .unwrap_or(std::ptr::null_mut());
2053        unsafe {
2054            ffi::wgpuRenderPassEncoderMultiDrawIndexedIndirect(
2055                self.raw,
2056                indirect_buffer.as_raw(),
2057                indirect_offset,
2058                max_draw_count,
2059                draw_count_buffer_raw,
2060                draw_count_buffer_offset,
2061            )
2062        };
2063        ()
2064    }
2065    pub fn execute_bundles(&self, bundles: &[RenderBundle]) -> () {
2066        let mut bundles_raw: Vec<ffi::WGPURenderBundle> = bundles
2067            .iter()
2068            .map(|v| v.as_raw())
2069            .collect();
2070        let bundles_ptr = bundles_raw.as_ptr();
2071        unsafe {
2072            ffi::wgpuRenderPassEncoderExecuteBundles(
2073                self.raw,
2074                bundles.len(),
2075                bundles_ptr,
2076            )
2077        };
2078        ()
2079    }
2080    pub fn insert_debug_marker(&self, marker_label: String) -> () {
2081        let marker_label_ffi = ffi::WGPUStringView {
2082            data: marker_label.as_ptr().cast(),
2083            length: marker_label.len(),
2084        };
2085        unsafe {
2086            ffi::wgpuRenderPassEncoderInsertDebugMarker(self.raw, marker_label_ffi)
2087        };
2088        ()
2089    }
2090    pub fn pop_debug_group(&self) -> () {
2091        unsafe { ffi::wgpuRenderPassEncoderPopDebugGroup(self.raw) };
2092        ()
2093    }
2094    pub fn push_debug_group(&self, group_label: String) -> () {
2095        let group_label_ffi = ffi::WGPUStringView {
2096            data: group_label.as_ptr().cast(),
2097            length: group_label.len(),
2098        };
2099        unsafe { ffi::wgpuRenderPassEncoderPushDebugGroup(self.raw, group_label_ffi) };
2100        ()
2101    }
2102    pub fn set_stencil_reference(&self, reference: u32) -> () {
2103        unsafe { ffi::wgpuRenderPassEncoderSetStencilReference(self.raw, reference) };
2104        ()
2105    }
2106    pub fn set_blend_constant(&self, color: &Color) -> () {
2107        let (color_ffi, _color_storage) = color.to_ffi();
2108        let color_ptr = std::ptr::addr_of!(color_ffi);
2109        unsafe { ffi::wgpuRenderPassEncoderSetBlendConstant(self.raw, color_ptr) };
2110        ()
2111    }
2112    pub fn set_viewport(
2113        &self,
2114        x: f32,
2115        y: f32,
2116        width: f32,
2117        height: f32,
2118        min_depth: f32,
2119        max_depth: f32,
2120    ) -> () {
2121        unsafe {
2122            ffi::wgpuRenderPassEncoderSetViewport(
2123                self.raw,
2124                x,
2125                y,
2126                width,
2127                height,
2128                min_depth,
2129                max_depth,
2130            )
2131        };
2132        ()
2133    }
2134    pub fn set_scissor_rect(&self, x: u32, y: u32, width: u32, height: u32) -> () {
2135        unsafe {
2136            ffi::wgpuRenderPassEncoderSetScissorRect(self.raw, x, y, width, height)
2137        };
2138        ()
2139    }
2140    pub fn set_vertex_buffer(
2141        &self,
2142        slot: u32,
2143        buffer: Option<Buffer>,
2144        offset: u64,
2145        size: u64,
2146    ) -> () {
2147        let buffer_raw = buffer
2148            .as_ref()
2149            .map(|v| v.as_raw())
2150            .unwrap_or(std::ptr::null_mut());
2151        unsafe {
2152            ffi::wgpuRenderPassEncoderSetVertexBuffer(
2153                self.raw,
2154                slot,
2155                buffer_raw,
2156                offset,
2157                size,
2158            )
2159        };
2160        ()
2161    }
2162    pub fn set_index_buffer(
2163        &self,
2164        buffer: Buffer,
2165        format: IndexFormat,
2166        offset: u64,
2167        size: u64,
2168    ) -> () {
2169        let format_ffi: ffi::WGPUIndexFormat = format.into();
2170        unsafe {
2171            ffi::wgpuRenderPassEncoderSetIndexBuffer(
2172                self.raw,
2173                buffer.as_raw(),
2174                format_ffi,
2175                offset,
2176                size,
2177            )
2178        };
2179        ()
2180    }
2181    pub fn begin_occlusion_query(&self, query_index: u32) -> () {
2182        unsafe { ffi::wgpuRenderPassEncoderBeginOcclusionQuery(self.raw, query_index) };
2183        ()
2184    }
2185    pub fn end_occlusion_query(&self) -> () {
2186        unsafe { ffi::wgpuRenderPassEncoderEndOcclusionQuery(self.raw) };
2187        ()
2188    }
2189    pub fn write_timestamp(&self, query_set: QuerySet, query_index: u32) -> () {
2190        unsafe {
2191            ffi::wgpuRenderPassEncoderWriteTimestamp(
2192                self.raw,
2193                query_set.as_raw(),
2194                query_index,
2195            )
2196        };
2197        ()
2198    }
2199    pub fn pixel_local_storage_barrier(&self) -> () {
2200        unsafe { ffi::wgpuRenderPassEncoderPixelLocalStorageBarrier(self.raw) };
2201        ()
2202    }
2203    pub fn end(&self) -> () {
2204        unsafe { ffi::wgpuRenderPassEncoderEnd(self.raw) };
2205        ()
2206    }
2207    pub fn set_label(&self, label: String) -> () {
2208        let label_ffi = ffi::WGPUStringView {
2209            data: label.as_ptr().cast(),
2210            length: label.len(),
2211        };
2212        unsafe { ffi::wgpuRenderPassEncoderSetLabel(self.raw, label_ffi) };
2213        ()
2214    }
2215    pub fn set_immediates(&self, offset: u32, data: &[std::ffi::c_void]) -> () {
2216        let data_ptr = data.as_ptr();
2217        unsafe {
2218            ffi::wgpuRenderPassEncoderSetImmediates(
2219                self.raw,
2220                offset,
2221                data_ptr,
2222                data.len(),
2223            )
2224        };
2225        ()
2226    }
2227}
2228impl Drop for RenderPassEncoder {
2229    fn drop(&mut self) {
2230        if self.as_raw().is_null() {
2231            return;
2232        }
2233        unsafe { ffi::wgpuRenderPassEncoderRelease(self.raw) };
2234    }
2235}
2236impl Clone for RenderPassEncoder {
2237    fn clone(&self) -> Self {
2238        unsafe { ffi::wgpuRenderPassEncoderAddRef(self.raw) };
2239        Self {
2240            raw: self.raw,
2241            _not_sync: std::marker::PhantomData,
2242        }
2243    }
2244}
2245#[derive(Debug)]
2246pub struct RenderPipeline {
2247    raw: ffi::WGPURenderPipeline,
2248}
2249impl RenderPipeline {
2250    pub(crate) unsafe fn from_raw(raw: ffi::WGPURenderPipeline) -> Self {
2251        Self { raw }
2252    }
2253    pub fn as_raw(&self) -> ffi::WGPURenderPipeline {
2254        self.raw
2255    }
2256    pub fn get_bind_group_layout(&self, group_index: u32) -> BindGroupLayout {
2257        let result = unsafe {
2258            ffi::wgpuRenderPipelineGetBindGroupLayout(self.raw, group_index)
2259        };
2260        unsafe { BindGroupLayout::from_raw(result) }
2261    }
2262    pub fn set_label(&self, label: String) -> () {
2263        let label_ffi = ffi::WGPUStringView {
2264            data: label.as_ptr().cast(),
2265            length: label.len(),
2266        };
2267        unsafe { ffi::wgpuRenderPipelineSetLabel(self.raw, label_ffi) };
2268        ()
2269    }
2270}
2271impl Drop for RenderPipeline {
2272    fn drop(&mut self) {
2273        if self.as_raw().is_null() {
2274            return;
2275        }
2276        unsafe { ffi::wgpuRenderPipelineRelease(self.raw) };
2277    }
2278}
2279impl Clone for RenderPipeline {
2280    fn clone(&self) -> Self {
2281        unsafe { ffi::wgpuRenderPipelineAddRef(self.raw) };
2282        Self { raw: self.raw }
2283    }
2284}
2285unsafe impl Send for RenderPipeline {}
2286unsafe impl Sync for RenderPipeline {}
2287#[derive(Debug)]
2288pub struct ResourceTable {
2289    raw: ffi::WGPUResourceTable,
2290}
2291impl ResourceTable {
2292    pub(crate) unsafe fn from_raw(raw: ffi::WGPUResourceTable) -> Self {
2293        Self { raw }
2294    }
2295    pub fn as_raw(&self) -> ffi::WGPUResourceTable {
2296        self.raw
2297    }
2298    pub fn get_size(&self) -> u32 {
2299        let result = unsafe { ffi::wgpuResourceTableGetSize(self.raw) };
2300        result
2301    }
2302    pub fn destroy(&self) -> () {
2303        unsafe { ffi::wgpuResourceTableDestroy(self.raw) };
2304        ()
2305    }
2306    pub fn update(&self, slot: u32, resource: &BindingResource) -> Status {
2307        let (resource_ffi, _resource_storage) = resource.to_ffi();
2308        let resource_ptr = std::ptr::addr_of!(resource_ffi);
2309        let result = unsafe {
2310            ffi::wgpuResourceTableUpdate(self.raw, slot, resource_ptr)
2311        };
2312        result.into()
2313    }
2314    pub fn insert_binding(&self, resource: &BindingResource) -> u32 {
2315        let (resource_ffi, _resource_storage) = resource.to_ffi();
2316        let resource_ptr = std::ptr::addr_of!(resource_ffi);
2317        let result = unsafe {
2318            ffi::wgpuResourceTableInsertBinding(self.raw, resource_ptr)
2319        };
2320        result
2321    }
2322    pub fn remove_binding(&self, slot: u32) -> Status {
2323        let result = unsafe { ffi::wgpuResourceTableRemoveBinding(self.raw, slot) };
2324        result.into()
2325    }
2326}
2327impl Drop for ResourceTable {
2328    fn drop(&mut self) {
2329        if self.as_raw().is_null() {
2330            return;
2331        }
2332        unsafe { ffi::wgpuResourceTableRelease(self.raw) };
2333    }
2334}
2335impl Clone for ResourceTable {
2336    fn clone(&self) -> Self {
2337        unsafe { ffi::wgpuResourceTableAddRef(self.raw) };
2338        Self { raw: self.raw }
2339    }
2340}
2341unsafe impl Send for ResourceTable {}
2342unsafe impl Sync for ResourceTable {}
2343#[derive(Debug)]
2344pub struct Sampler {
2345    raw: ffi::WGPUSampler,
2346}
2347impl Sampler {
2348    pub(crate) unsafe fn from_raw(raw: ffi::WGPUSampler) -> Self {
2349        Self { raw }
2350    }
2351    pub fn as_raw(&self) -> ffi::WGPUSampler {
2352        self.raw
2353    }
2354    pub fn set_label(&self, label: String) -> () {
2355        let label_ffi = ffi::WGPUStringView {
2356            data: label.as_ptr().cast(),
2357            length: label.len(),
2358        };
2359        unsafe { ffi::wgpuSamplerSetLabel(self.raw, label_ffi) };
2360        ()
2361    }
2362}
2363impl Drop for Sampler {
2364    fn drop(&mut self) {
2365        if self.as_raw().is_null() {
2366            return;
2367        }
2368        unsafe { ffi::wgpuSamplerRelease(self.raw) };
2369    }
2370}
2371impl Clone for Sampler {
2372    fn clone(&self) -> Self {
2373        unsafe { ffi::wgpuSamplerAddRef(self.raw) };
2374        Self { raw: self.raw }
2375    }
2376}
2377unsafe impl Send for Sampler {}
2378unsafe impl Sync for Sampler {}
2379#[derive(Debug)]
2380pub struct ShaderModule {
2381    raw: ffi::WGPUShaderModule,
2382}
2383impl ShaderModule {
2384    pub(crate) unsafe fn from_raw(raw: ffi::WGPUShaderModule) -> Self {
2385        Self { raw }
2386    }
2387    pub fn as_raw(&self) -> ffi::WGPUShaderModule {
2388        self.raw
2389    }
2390    pub fn get_compilation_info(
2391        &self,
2392        callback: impl FnMut(
2393            CompilationInfoRequestStatus,
2394            &CompilationInfo,
2395        ) + Send + 'static,
2396    ) -> Future {
2397        let callback_box: CompilationInfoCallback = Box::new(callback);
2398        let callback_box = Box::new(Some(callback_box));
2399        let callback_userdata = Box::into_raw(callback_box).cast::<std::ffi::c_void>();
2400        let callback_info_ffi = ffi::WGPUCompilationInfoCallbackInfo {
2401            nextInChain: std::ptr::null_mut(),
2402            mode: ffi::WGPUCallbackMode_WGPUCallbackMode_AllowSpontaneous,
2403            callback: Some(compilation_info_callback_trampoline),
2404            userdata1: callback_userdata,
2405            userdata2: std::ptr::null_mut(),
2406        };
2407        let result = unsafe {
2408            ffi::wgpuShaderModuleGetCompilationInfo(self.raw, callback_info_ffi)
2409        };
2410        Future::from_ffi(result)
2411    }
2412    pub fn set_label(&self, label: String) -> () {
2413        let label_ffi = ffi::WGPUStringView {
2414            data: label.as_ptr().cast(),
2415            length: label.len(),
2416        };
2417        unsafe { ffi::wgpuShaderModuleSetLabel(self.raw, label_ffi) };
2418        ()
2419    }
2420}
2421impl Drop for ShaderModule {
2422    fn drop(&mut self) {
2423        if self.as_raw().is_null() {
2424            return;
2425        }
2426        unsafe { ffi::wgpuShaderModuleRelease(self.raw) };
2427    }
2428}
2429impl Clone for ShaderModule {
2430    fn clone(&self) -> Self {
2431        unsafe { ffi::wgpuShaderModuleAddRef(self.raw) };
2432        Self { raw: self.raw }
2433    }
2434}
2435unsafe impl Send for ShaderModule {}
2436unsafe impl Sync for ShaderModule {}
2437#[derive(Debug)]
2438pub struct SharedBufferMemory {
2439    raw: ffi::WGPUSharedBufferMemory,
2440}
2441impl SharedBufferMemory {
2442    pub(crate) unsafe fn from_raw(raw: ffi::WGPUSharedBufferMemory) -> Self {
2443        Self { raw }
2444    }
2445    pub fn as_raw(&self) -> ffi::WGPUSharedBufferMemory {
2446        self.raw
2447    }
2448    pub fn set_label(&self, label: String) -> () {
2449        let label_ffi = ffi::WGPUStringView {
2450            data: label.as_ptr().cast(),
2451            length: label.len(),
2452        };
2453        unsafe { ffi::wgpuSharedBufferMemorySetLabel(self.raw, label_ffi) };
2454        ()
2455    }
2456    pub fn get_properties(
2457        &self,
2458        properties: &mut SharedBufferMemoryProperties,
2459    ) -> Status {
2460        let (mut properties_ffi, _properties_storage) = properties.to_ffi();
2461        let properties_ptr = std::ptr::addr_of_mut!(properties_ffi);
2462        let result = unsafe {
2463            ffi::wgpuSharedBufferMemoryGetProperties(self.raw, properties_ptr)
2464        };
2465        *properties = SharedBufferMemoryProperties::from_ffi(properties_ffi);
2466        result.into()
2467    }
2468    pub fn create_buffer(&self, descriptor: Option<&BufferDescriptor>) -> Buffer {
2469        let mut descriptor_storage = ChainedStructStorage::new();
2470        let descriptor_ptr = if let Some(value) = &descriptor {
2471            let (descriptor_ffi, storage) = value.to_ffi();
2472            descriptor_storage = storage;
2473            std::ptr::addr_of!(descriptor_ffi)
2474        } else {
2475            std::ptr::null()
2476        };
2477        let result = unsafe {
2478            ffi::wgpuSharedBufferMemoryCreateBuffer(self.raw, descriptor_ptr)
2479        };
2480        unsafe { Buffer::from_raw(result) }
2481    }
2482    pub fn begin_access(
2483        &self,
2484        buffer: Buffer,
2485        descriptor: &SharedBufferMemoryBeginAccessDescriptor,
2486    ) -> Status {
2487        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
2488        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
2489        let result = unsafe {
2490            ffi::wgpuSharedBufferMemoryBeginAccess(
2491                self.raw,
2492                buffer.as_raw(),
2493                descriptor_ptr,
2494            )
2495        };
2496        result.into()
2497    }
2498    pub fn end_access(
2499        &self,
2500        buffer: Buffer,
2501        descriptor: &mut SharedBufferMemoryEndAccessState,
2502    ) -> Status {
2503        let (mut descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
2504        let descriptor_ptr = std::ptr::addr_of_mut!(descriptor_ffi);
2505        let result = unsafe {
2506            ffi::wgpuSharedBufferMemoryEndAccess(
2507                self.raw,
2508                buffer.as_raw(),
2509                descriptor_ptr,
2510            )
2511        };
2512        *descriptor = SharedBufferMemoryEndAccessState::from_ffi(descriptor_ffi);
2513        result.into()
2514    }
2515    pub fn is_device_lost(&self) -> bool {
2516        let result = unsafe { ffi::wgpuSharedBufferMemoryIsDeviceLost(self.raw) };
2517        result != 0
2518    }
2519}
2520impl Drop for SharedBufferMemory {
2521    fn drop(&mut self) {
2522        if self.as_raw().is_null() {
2523            return;
2524        }
2525        unsafe { ffi::wgpuSharedBufferMemoryRelease(self.raw) };
2526    }
2527}
2528impl Clone for SharedBufferMemory {
2529    fn clone(&self) -> Self {
2530        unsafe { ffi::wgpuSharedBufferMemoryAddRef(self.raw) };
2531        Self { raw: self.raw }
2532    }
2533}
2534unsafe impl Send for SharedBufferMemory {}
2535unsafe impl Sync for SharedBufferMemory {}
2536#[derive(Debug)]
2537pub struct SharedFence {
2538    raw: ffi::WGPUSharedFence,
2539}
2540impl SharedFence {
2541    pub(crate) unsafe fn from_raw(raw: ffi::WGPUSharedFence) -> Self {
2542        Self { raw }
2543    }
2544    pub fn as_raw(&self) -> ffi::WGPUSharedFence {
2545        self.raw
2546    }
2547    pub fn export_info(&self, info: &mut SharedFenceExportInfo) -> () {
2548        let (mut info_ffi, _info_storage) = info.to_ffi();
2549        let info_ptr = std::ptr::addr_of_mut!(info_ffi);
2550        unsafe { ffi::wgpuSharedFenceExportInfo(self.raw, info_ptr) };
2551        *info = SharedFenceExportInfo::from_ffi(info_ffi);
2552        ()
2553    }
2554}
2555impl Drop for SharedFence {
2556    fn drop(&mut self) {
2557        if self.as_raw().is_null() {
2558            return;
2559        }
2560        unsafe { ffi::wgpuSharedFenceRelease(self.raw) };
2561    }
2562}
2563impl Clone for SharedFence {
2564    fn clone(&self) -> Self {
2565        unsafe { ffi::wgpuSharedFenceAddRef(self.raw) };
2566        Self { raw: self.raw }
2567    }
2568}
2569unsafe impl Send for SharedFence {}
2570unsafe impl Sync for SharedFence {}
2571#[derive(Debug)]
2572pub struct SharedTextureMemory {
2573    raw: ffi::WGPUSharedTextureMemory,
2574}
2575impl SharedTextureMemory {
2576    pub(crate) unsafe fn from_raw(raw: ffi::WGPUSharedTextureMemory) -> Self {
2577        Self { raw }
2578    }
2579    pub fn as_raw(&self) -> ffi::WGPUSharedTextureMemory {
2580        self.raw
2581    }
2582    pub fn set_label(&self, label: String) -> () {
2583        let label_ffi = ffi::WGPUStringView {
2584            data: label.as_ptr().cast(),
2585            length: label.len(),
2586        };
2587        unsafe { ffi::wgpuSharedTextureMemorySetLabel(self.raw, label_ffi) };
2588        ()
2589    }
2590    pub fn get_properties(
2591        &self,
2592        properties: &mut SharedTextureMemoryProperties,
2593    ) -> Status {
2594        let (mut properties_ffi, _properties_storage) = properties.to_ffi();
2595        let properties_ptr = std::ptr::addr_of_mut!(properties_ffi);
2596        let result = unsafe {
2597            ffi::wgpuSharedTextureMemoryGetProperties(self.raw, properties_ptr)
2598        };
2599        *properties = SharedTextureMemoryProperties::from_ffi(properties_ffi);
2600        result.into()
2601    }
2602    pub fn create_texture(&self, descriptor: Option<&TextureDescriptor>) -> Texture {
2603        let mut descriptor_storage = ChainedStructStorage::new();
2604        let descriptor_ptr = if let Some(value) = &descriptor {
2605            let (descriptor_ffi, storage) = value.to_ffi();
2606            descriptor_storage = storage;
2607            std::ptr::addr_of!(descriptor_ffi)
2608        } else {
2609            std::ptr::null()
2610        };
2611        let result = unsafe {
2612            ffi::wgpuSharedTextureMemoryCreateTexture(self.raw, descriptor_ptr)
2613        };
2614        unsafe { Texture::from_raw(result) }
2615    }
2616    pub fn begin_access(
2617        &self,
2618        texture: Texture,
2619        descriptor: &SharedTextureMemoryBeginAccessDescriptor,
2620    ) -> Status {
2621        let (descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
2622        let descriptor_ptr = std::ptr::addr_of!(descriptor_ffi);
2623        let result = unsafe {
2624            ffi::wgpuSharedTextureMemoryBeginAccess(
2625                self.raw,
2626                texture.as_raw(),
2627                descriptor_ptr,
2628            )
2629        };
2630        result.into()
2631    }
2632    pub fn end_access(
2633        &self,
2634        texture: Texture,
2635        descriptor: &mut SharedTextureMemoryEndAccessState,
2636    ) -> Status {
2637        let (mut descriptor_ffi, _descriptor_storage) = descriptor.to_ffi();
2638        let descriptor_ptr = std::ptr::addr_of_mut!(descriptor_ffi);
2639        let result = unsafe {
2640            ffi::wgpuSharedTextureMemoryEndAccess(
2641                self.raw,
2642                texture.as_raw(),
2643                descriptor_ptr,
2644            )
2645        };
2646        *descriptor = SharedTextureMemoryEndAccessState::from_ffi(descriptor_ffi);
2647        result.into()
2648    }
2649    pub fn is_device_lost(&self) -> bool {
2650        let result = unsafe { ffi::wgpuSharedTextureMemoryIsDeviceLost(self.raw) };
2651        result != 0
2652    }
2653}
2654impl Drop for SharedTextureMemory {
2655    fn drop(&mut self) {
2656        if self.as_raw().is_null() {
2657            return;
2658        }
2659        unsafe { ffi::wgpuSharedTextureMemoryRelease(self.raw) };
2660    }
2661}
2662impl Clone for SharedTextureMemory {
2663    fn clone(&self) -> Self {
2664        unsafe { ffi::wgpuSharedTextureMemoryAddRef(self.raw) };
2665        Self { raw: self.raw }
2666    }
2667}
2668unsafe impl Send for SharedTextureMemory {}
2669unsafe impl Sync for SharedTextureMemory {}
2670#[derive(Debug)]
2671pub struct Surface {
2672    raw: ffi::WGPUSurface,
2673    _not_sync: std::marker::PhantomData<std::cell::Cell<()>>,
2674}
2675impl Surface {
2676    pub(crate) unsafe fn from_raw(raw: ffi::WGPUSurface) -> Self {
2677        Self {
2678            raw,
2679            _not_sync: std::marker::PhantomData,
2680        }
2681    }
2682    pub fn as_raw(&self) -> ffi::WGPUSurface {
2683        self.raw
2684    }
2685    pub fn configure(&self, config: &SurfaceConfiguration) -> () {
2686        let (config_ffi, _config_storage) = config.to_ffi();
2687        let config_ptr = std::ptr::addr_of!(config_ffi);
2688        unsafe { ffi::wgpuSurfaceConfigure(self.raw, config_ptr) };
2689        ()
2690    }
2691    pub fn get_capabilities(
2692        &self,
2693        adapter: Adapter,
2694        capabilities: &mut SurfaceCapabilities,
2695    ) -> Status {
2696        let (mut capabilities_ffi, _capabilities_storage) = capabilities.to_ffi();
2697        let capabilities_ptr = std::ptr::addr_of_mut!(capabilities_ffi);
2698        let result = unsafe {
2699            ffi::wgpuSurfaceGetCapabilities(self.raw, adapter.as_raw(), capabilities_ptr)
2700        };
2701        *capabilities = SurfaceCapabilities::from_ffi(capabilities_ffi);
2702        result.into()
2703    }
2704    pub fn get_current_texture(&self, surface_texture: &mut SurfaceTexture) -> () {
2705        let (mut surface_texture_ffi, _surface_texture_storage) = surface_texture
2706            .to_ffi();
2707        let surface_texture_ptr = std::ptr::addr_of_mut!(surface_texture_ffi);
2708        unsafe { ffi::wgpuSurfaceGetCurrentTexture(self.raw, surface_texture_ptr) };
2709        *surface_texture = SurfaceTexture::from_ffi(surface_texture_ffi);
2710        ()
2711    }
2712    pub fn present(&self) -> Status {
2713        let result = unsafe { ffi::wgpuSurfacePresent(self.raw) };
2714        result.into()
2715    }
2716    pub fn unconfigure(&self) -> () {
2717        unsafe { ffi::wgpuSurfaceUnconfigure(self.raw) };
2718        ()
2719    }
2720    pub fn set_label(&self, label: String) -> () {
2721        let label_ffi = ffi::WGPUStringView {
2722            data: label.as_ptr().cast(),
2723            length: label.len(),
2724        };
2725        unsafe { ffi::wgpuSurfaceSetLabel(self.raw, label_ffi) };
2726        ()
2727    }
2728}
2729impl Drop for Surface {
2730    fn drop(&mut self) {
2731        if self.as_raw().is_null() {
2732            return;
2733        }
2734        unsafe { ffi::wgpuSurfaceRelease(self.raw) };
2735    }
2736}
2737impl Clone for Surface {
2738    fn clone(&self) -> Self {
2739        unsafe { ffi::wgpuSurfaceAddRef(self.raw) };
2740        Self {
2741            raw: self.raw,
2742            _not_sync: std::marker::PhantomData,
2743        }
2744    }
2745}
2746#[derive(Debug)]
2747pub struct TexelBufferView {
2748    raw: ffi::WGPUTexelBufferView,
2749}
2750impl TexelBufferView {
2751    pub(crate) unsafe fn from_raw(raw: ffi::WGPUTexelBufferView) -> Self {
2752        Self { raw }
2753    }
2754    pub fn as_raw(&self) -> ffi::WGPUTexelBufferView {
2755        self.raw
2756    }
2757    pub fn set_label(&self, label: String) -> () {
2758        let label_ffi = ffi::WGPUStringView {
2759            data: label.as_ptr().cast(),
2760            length: label.len(),
2761        };
2762        unsafe { ffi::wgpuTexelBufferViewSetLabel(self.raw, label_ffi) };
2763        ()
2764    }
2765}
2766impl Drop for TexelBufferView {
2767    fn drop(&mut self) {
2768        if self.as_raw().is_null() {
2769            return;
2770        }
2771        unsafe { ffi::wgpuTexelBufferViewRelease(self.raw) };
2772    }
2773}
2774impl Clone for TexelBufferView {
2775    fn clone(&self) -> Self {
2776        unsafe { ffi::wgpuTexelBufferViewAddRef(self.raw) };
2777        Self { raw: self.raw }
2778    }
2779}
2780unsafe impl Send for TexelBufferView {}
2781unsafe impl Sync for TexelBufferView {}
2782#[derive(Debug)]
2783pub struct Texture {
2784    raw: ffi::WGPUTexture,
2785}
2786impl Texture {
2787    pub(crate) unsafe fn from_raw(raw: ffi::WGPUTexture) -> Self {
2788        Self { raw }
2789    }
2790    pub fn as_raw(&self) -> ffi::WGPUTexture {
2791        self.raw
2792    }
2793    pub fn create_view(
2794        &self,
2795        descriptor: Option<&TextureViewDescriptor>,
2796    ) -> TextureView {
2797        let mut descriptor_storage = ChainedStructStorage::new();
2798        let descriptor_ptr = if let Some(value) = &descriptor {
2799            let (descriptor_ffi, storage) = value.to_ffi();
2800            descriptor_storage = storage;
2801            std::ptr::addr_of!(descriptor_ffi)
2802        } else {
2803            std::ptr::null()
2804        };
2805        let result = unsafe { ffi::wgpuTextureCreateView(self.raw, descriptor_ptr) };
2806        unsafe { TextureView::from_raw(result) }
2807    }
2808    pub fn create_error_view(
2809        &self,
2810        descriptor: Option<&TextureViewDescriptor>,
2811    ) -> TextureView {
2812        let mut descriptor_storage = ChainedStructStorage::new();
2813        let descriptor_ptr = if let Some(value) = &descriptor {
2814            let (descriptor_ffi, storage) = value.to_ffi();
2815            descriptor_storage = storage;
2816            std::ptr::addr_of!(descriptor_ffi)
2817        } else {
2818            std::ptr::null()
2819        };
2820        let result = unsafe {
2821            ffi::wgpuTextureCreateErrorView(self.raw, descriptor_ptr)
2822        };
2823        unsafe { TextureView::from_raw(result) }
2824    }
2825    pub fn set_label(&self, label: String) -> () {
2826        let label_ffi = ffi::WGPUStringView {
2827            data: label.as_ptr().cast(),
2828            length: label.len(),
2829        };
2830        unsafe { ffi::wgpuTextureSetLabel(self.raw, label_ffi) };
2831        ()
2832    }
2833    pub fn get_width(&self) -> u32 {
2834        let result = unsafe { ffi::wgpuTextureGetWidth(self.raw) };
2835        result
2836    }
2837    pub fn get_height(&self) -> u32 {
2838        let result = unsafe { ffi::wgpuTextureGetHeight(self.raw) };
2839        result
2840    }
2841    pub fn get_depth_or_array_layers(&self) -> u32 {
2842        let result = unsafe { ffi::wgpuTextureGetDepthOrArrayLayers(self.raw) };
2843        result
2844    }
2845    pub fn get_mip_level_count(&self) -> u32 {
2846        let result = unsafe { ffi::wgpuTextureGetMipLevelCount(self.raw) };
2847        result
2848    }
2849    pub fn get_sample_count(&self) -> u32 {
2850        let result = unsafe { ffi::wgpuTextureGetSampleCount(self.raw) };
2851        result
2852    }
2853    pub fn get_dimension(&self) -> TextureDimension {
2854        let result = unsafe { ffi::wgpuTextureGetDimension(self.raw) };
2855        result.into()
2856    }
2857    pub fn get_format(&self) -> TextureFormat {
2858        let result = unsafe { ffi::wgpuTextureGetFormat(self.raw) };
2859        result.into()
2860    }
2861    pub fn get_usage(&self) -> TextureUsage {
2862        let result = unsafe { ffi::wgpuTextureGetUsage(self.raw) };
2863        result.into()
2864    }
2865    pub fn get_texture_binding_view_dimension(&self) -> TextureViewDimension {
2866        let result = unsafe { ffi::wgpuTextureGetTextureBindingViewDimension(self.raw) };
2867        result.into()
2868    }
2869    pub fn destroy(&self) -> () {
2870        unsafe { ffi::wgpuTextureDestroy(self.raw) };
2871        ()
2872    }
2873    pub fn pin(&self, usage: TextureUsage) -> () {
2874        let usage_ffi: ffi::WGPUTextureUsage = usage.into();
2875        unsafe { ffi::wgpuTexturePin(self.raw, usage_ffi) };
2876        ()
2877    }
2878    pub fn unpin(&self) -> () {
2879        unsafe { ffi::wgpuTextureUnpin(self.raw) };
2880        ()
2881    }
2882    pub fn set_ownership_for_memory_dump(&self, owner_guid: u64) -> () {
2883        unsafe { ffi::wgpuTextureSetOwnershipForMemoryDump(self.raw, owner_guid) };
2884        ()
2885    }
2886}
2887impl Drop for Texture {
2888    fn drop(&mut self) {
2889        if self.as_raw().is_null() {
2890            return;
2891        }
2892        unsafe { ffi::wgpuTextureRelease(self.raw) };
2893    }
2894}
2895impl Clone for Texture {
2896    fn clone(&self) -> Self {
2897        unsafe { ffi::wgpuTextureAddRef(self.raw) };
2898        Self { raw: self.raw }
2899    }
2900}
2901unsafe impl Send for Texture {}
2902unsafe impl Sync for Texture {}
2903#[derive(Debug)]
2904pub struct TextureView {
2905    raw: ffi::WGPUTextureView,
2906}
2907impl TextureView {
2908    pub(crate) unsafe fn from_raw(raw: ffi::WGPUTextureView) -> Self {
2909        Self { raw }
2910    }
2911    pub fn as_raw(&self) -> ffi::WGPUTextureView {
2912        self.raw
2913    }
2914    pub fn set_label(&self, label: String) -> () {
2915        let label_ffi = ffi::WGPUStringView {
2916            data: label.as_ptr().cast(),
2917            length: label.len(),
2918        };
2919        unsafe { ffi::wgpuTextureViewSetLabel(self.raw, label_ffi) };
2920        ()
2921    }
2922}
2923impl Drop for TextureView {
2924    fn drop(&mut self) {
2925        if self.as_raw().is_null() {
2926            return;
2927        }
2928        unsafe { ffi::wgpuTextureViewRelease(self.raw) };
2929    }
2930}
2931impl Clone for TextureView {
2932    fn clone(&self) -> Self {
2933        unsafe { ffi::wgpuTextureViewAddRef(self.raw) };
2934        Self { raw: self.raw }
2935    }
2936}
2937unsafe impl Send for TextureView {}
2938unsafe impl Sync for TextureView {}