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 {}