1#![doc(html_logo_url = "https://raw.githubusercontent.com/gfx-rs/wgpu-rs/master/logo.png")]
6#![warn(missing_docs)]
7
8mod backend;
9pub mod util;
10#[macro_use]
11mod macros;
12
13use std::{
14 future::Future,
15 marker::PhantomData,
16 ops::{Bound, Range, RangeBounds},
17 sync::Arc,
18 thread,
19};
20
21use futures::FutureExt as _;
22use parking_lot::Mutex;
23
24#[cfg(not(target_arch = "wasm32"))]
25pub use wgc::instance::{AdapterInfo, DeviceType};
26pub use wgt::{
27 AddressMode, Backend, BackendBit, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
28 BlendDescriptor, BlendFactor, BlendOperation, BufferAddress, BufferSize, BufferUsage, Color,
29 ColorStateDescriptor, ColorWrite, CommandBufferDescriptor, CompareFunction, CullMode,
30 DepthStencilStateDescriptor, DeviceDescriptor, DynamicOffset, Extent3d, Features, FilterMode,
31 FrontFace, IndexFormat, InputStepMode, Limits, Origin3d, PowerPreference, PresentMode,
32 PrimitiveTopology, RasterizationStateDescriptor, RenderBundleEncoderDescriptor, ShaderLocation,
33 ShaderStage, StencilOperation, StencilStateFaceDescriptor, SwapChainDescriptor,
34 SwapChainStatus, TextureAspect, TextureComponentType, TextureDataLayout, TextureDimension,
35 TextureFormat, TextureUsage, TextureViewDimension, VertexAttributeDescriptor,
36 VertexBufferDescriptor, VertexFormat, VertexStateDescriptor, BIND_BUFFER_ALIGNMENT,
37 COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT,
38};
39
40use backend::Context as C;
41
42trait ComputePassInner<Ctx: Context> {
43 fn set_pipeline(&mut self, pipeline: &Ctx::ComputePipelineId);
44 fn set_bind_group(
45 &mut self,
46 index: u32,
47 bind_group: &Ctx::BindGroupId,
48 offsets: &[DynamicOffset],
49 );
50 fn dispatch(&mut self, x: u32, y: u32, z: u32);
51 fn dispatch_indirect(
52 &mut self,
53 indirect_buffer: &Ctx::BufferId,
54 indirect_offset: BufferAddress,
55 );
56}
57
58trait RenderInner<Ctx: Context> {
59 fn set_pipeline(&mut self, pipeline: &Ctx::RenderPipelineId);
60 fn set_bind_group(
61 &mut self,
62 index: u32,
63 bind_group: &Ctx::BindGroupId,
64 offsets: &[DynamicOffset],
65 );
66 fn set_index_buffer(
67 &mut self,
68 buffer: &Ctx::BufferId,
69 offset: BufferAddress,
70 size: Option<BufferSize>,
71 );
72 fn set_vertex_buffer(
73 &mut self,
74 slot: u32,
75 buffer: &Ctx::BufferId,
76 offset: BufferAddress,
77 size: Option<BufferSize>,
78 );
79 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
80 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
81 fn draw_indirect(&mut self, indirect_buffer: &Ctx::BufferId, indirect_offset: BufferAddress);
82 fn draw_indexed_indirect(
83 &mut self,
84 indirect_buffer: &Ctx::BufferId,
85 indirect_offset: BufferAddress,
86 );
87 fn multi_draw_indirect(
88 &mut self,
89 indirect_buffer: &Ctx::BufferId,
90 indirect_offset: BufferAddress,
91 count: u32,
92 );
93 fn multi_draw_indexed_indirect(
94 &mut self,
95 indirect_buffer: &Ctx::BufferId,
96 indirect_offset: BufferAddress,
97 count: u32,
98 );
99 fn multi_draw_indirect_count(
100 &mut self,
101 indirect_buffer: &Ctx::BufferId,
102 indirect_offset: BufferAddress,
103 count_buffer: &Ctx::BufferId,
104 count_buffer_offset: BufferAddress,
105 max_count: u32,
106 );
107 fn multi_draw_indexed_indirect_count(
108 &mut self,
109 indirect_buffer: &Ctx::BufferId,
110 indirect_offset: BufferAddress,
111 count_buffer: &Ctx::BufferId,
112 count_buffer_offset: BufferAddress,
113 max_count: u32,
114 );
115}
116
117trait RenderPassInner<Ctx: Context>: RenderInner<Ctx> {
118 fn set_blend_color(&mut self, color: Color);
119 fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32);
120 fn set_viewport(
121 &mut self,
122 x: f32,
123 y: f32,
124 width: f32,
125 height: f32,
126 min_depth: f32,
127 max_depth: f32,
128 );
129 fn set_stencil_reference(&mut self, reference: u32);
130 fn insert_debug_marker(&mut self, label: &str);
131 fn push_debug_group(&mut self, group_label: &str);
132 fn pop_debug_group(&mut self);
133 fn execute_bundles<'a, I: Iterator<Item = &'a Ctx::RenderBundleId>>(
134 &mut self,
135 render_bundles: I,
136 );
137}
138
139trait Context: Sized {
140 type AdapterId: Send + Sync + 'static;
141 type DeviceId: Send + Sync + 'static;
142 type QueueId: Send + Sync + 'static;
143 type ShaderModuleId: Send + Sync + 'static;
144 type BindGroupLayoutId: Send + Sync + 'static;
145 type BindGroupId: Send + Sync + 'static;
146 type TextureViewId: Send + Sync + 'static;
147 type SamplerId: Send + Sync + 'static;
148 type BufferId: Send + Sync + 'static;
149 type TextureId: Send + Sync + 'static;
150 type PipelineLayoutId: Send + Sync + 'static;
151 type RenderPipelineId: Send + Sync + 'static;
152 type ComputePipelineId: Send + Sync + 'static;
153 type CommandEncoderId;
154 type ComputePassId: ComputePassInner<Self>;
155 type RenderPassId: RenderPassInner<Self>;
156 type CommandBufferId: Send + Sync;
157 type RenderBundleEncoderId: RenderInner<Self>;
158 type RenderBundleId: Send + Sync + 'static;
159 type SurfaceId: Send + Sync + 'static;
160 type SwapChainId: Send + Sync + 'static;
161
162 type SwapChainOutputDetail: Send;
163
164 type RequestAdapterFuture: Future<Output = Option<Self::AdapterId>> + Send;
165 type RequestDeviceFuture: Future<Output = Result<(Self::DeviceId, Self::QueueId), RequestDeviceError>>
166 + Send;
167 type MapAsyncFuture: Future<Output = Result<(), BufferAsyncError>> + Send;
168
169 fn init(backends: BackendBit) -> Self;
170 fn instance_create_surface(
171 &self,
172 handle: &impl raw_window_handle::HasRawWindowHandle,
173 ) -> Self::SurfaceId;
174 fn instance_request_adapter(
175 &self,
176 options: &RequestAdapterOptions<'_>,
177 ) -> Self::RequestAdapterFuture;
178 fn adapter_request_device(
179 &self,
180 adapter: &Self::AdapterId,
181 desc: &DeviceDescriptor,
182 trace_dir: Option<&std::path::Path>,
183 ) -> Self::RequestDeviceFuture;
184 fn adapter_features(&self, adapter: &Self::AdapterId) -> Features;
185 fn adapter_limits(&self, adapter: &Self::AdapterId) -> Limits;
186
187 fn device_features(&self, device: &Self::DeviceId) -> Features;
188 fn device_limits(&self, device: &Self::DeviceId) -> Limits;
189 fn device_create_swap_chain(
190 &self,
191 device: &Self::DeviceId,
192 surface: &Self::SurfaceId,
193 desc: &SwapChainDescriptor,
194 ) -> Self::SwapChainId;
195 fn device_create_shader_module(
196 &self,
197 device: &Self::DeviceId,
198 source: ShaderModuleSource,
199 ) -> Self::ShaderModuleId;
200 fn device_create_bind_group_layout(
201 &self,
202 device: &Self::DeviceId,
203 desc: &BindGroupLayoutDescriptor,
204 ) -> Self::BindGroupLayoutId;
205 fn device_create_bind_group(
206 &self,
207 device: &Self::DeviceId,
208 desc: &BindGroupDescriptor,
209 ) -> Self::BindGroupId;
210 fn device_create_pipeline_layout(
211 &self,
212 device: &Self::DeviceId,
213 desc: &PipelineLayoutDescriptor,
214 ) -> Self::PipelineLayoutId;
215 fn device_create_render_pipeline(
216 &self,
217 device: &Self::DeviceId,
218 desc: &RenderPipelineDescriptor,
219 ) -> Self::RenderPipelineId;
220 fn device_create_compute_pipeline(
221 &self,
222 device: &Self::DeviceId,
223 desc: &ComputePipelineDescriptor,
224 ) -> Self::ComputePipelineId;
225 fn device_create_buffer(
226 &self,
227 device: &Self::DeviceId,
228 desc: &BufferDescriptor,
229 ) -> Self::BufferId;
230 fn device_create_texture(
231 &self,
232 device: &Self::DeviceId,
233 desc: &TextureDescriptor,
234 ) -> Self::TextureId;
235 fn device_create_sampler(
236 &self,
237 device: &Self::DeviceId,
238 desc: &SamplerDescriptor,
239 ) -> Self::SamplerId;
240 fn device_create_command_encoder(
241 &self,
242 device: &Self::DeviceId,
243 desc: &CommandEncoderDescriptor,
244 ) -> Self::CommandEncoderId;
245 fn device_create_render_bundle_encoder(
246 &self,
247 device: &Self::DeviceId,
248 desc: &RenderBundleEncoderDescriptor,
249 ) -> Self::RenderBundleEncoderId;
250 fn device_drop(&self, device: &Self::DeviceId);
251 fn device_poll(&self, device: &Self::DeviceId, maintain: Maintain);
252
253 fn buffer_map_async(
254 &self,
255 buffer: &Self::BufferId,
256 mode: MapMode,
257 range: Range<BufferAddress>,
258 ) -> Self::MapAsyncFuture;
259 fn buffer_get_mapped_range(
262 &self,
263 buffer: &Self::BufferId,
264 sub_range: Range<BufferAddress>,
265 ) -> &[u8];
266 fn buffer_get_mapped_range_mut(
267 &self,
268 buffer: &Self::BufferId,
269 sub_range: Range<BufferAddress>,
270 ) -> &mut [u8];
271 fn buffer_unmap(&self, buffer: &Self::BufferId);
272 fn swap_chain_get_next_texture(
273 &self,
274 swap_chain: &Self::SwapChainId,
275 ) -> (
276 Option<Self::TextureViewId>,
277 SwapChainStatus,
278 Self::SwapChainOutputDetail,
279 );
280 fn swap_chain_present(&self, view: &Self::TextureViewId, detail: &Self::SwapChainOutputDetail);
281 fn texture_create_view(
282 &self,
283 texture: &Self::TextureId,
284 desc: Option<&TextureViewDescriptor>,
285 ) -> Self::TextureViewId;
286 fn texture_drop(&self, texture: &Self::TextureId);
287 fn texture_view_drop(&self, texture_view: &Self::TextureViewId);
288 fn sampler_drop(&self, sampler: &Self::SamplerId);
289 fn buffer_drop(&self, buffer: &Self::BufferId);
290 fn bind_group_drop(&self, bind_group: &Self::BindGroupId);
291 fn bind_group_layout_drop(&self, bind_group_layout: &Self::BindGroupLayoutId);
292 fn pipeline_layout_drop(&self, pipeline_layout: &Self::PipelineLayoutId);
293 fn shader_module_drop(&self, shader_module: &Self::ShaderModuleId);
294 fn command_buffer_drop(&self, command_buffer: &Self::CommandBufferId);
295 fn render_bundle_drop(&self, render_bundle: &Self::RenderBundleId);
296 fn compute_pipeline_drop(&self, pipeline: &Self::ComputePipelineId);
297 fn render_pipeline_drop(&self, pipeline: &Self::RenderPipelineId);
298
299 fn command_encoder_copy_buffer_to_buffer(
300 &self,
301 encoder: &Self::CommandEncoderId,
302 source: &Self::BufferId,
303 source_offset: BufferAddress,
304 destination: &Self::BufferId,
305 destination_offset: BufferAddress,
306 copy_size: BufferAddress,
307 );
308 fn command_encoder_copy_buffer_to_texture(
309 &self,
310 encoder: &Self::CommandEncoderId,
311 source: BufferCopyView,
312 destination: TextureCopyView,
313 copy_size: Extent3d,
314 );
315 fn command_encoder_copy_texture_to_buffer(
316 &self,
317 encoder: &Self::CommandEncoderId,
318 source: TextureCopyView,
319 destination: BufferCopyView,
320 copy_size: Extent3d,
321 );
322 fn command_encoder_copy_texture_to_texture(
323 &self,
324 encoder: &Self::CommandEncoderId,
325 source: TextureCopyView,
326 destination: TextureCopyView,
327 copy_size: Extent3d,
328 );
329
330 fn command_encoder_begin_compute_pass(
331 &self,
332 encoder: &Self::CommandEncoderId,
333 ) -> Self::ComputePassId;
334 fn command_encoder_end_compute_pass(
335 &self,
336 encoder: &Self::CommandEncoderId,
337 pass: &mut Self::ComputePassId,
338 );
339 fn command_encoder_begin_render_pass<'a>(
340 &self,
341 encoder: &Self::CommandEncoderId,
342 desc: &RenderPassDescriptor<'a, '_>,
343 ) -> Self::RenderPassId;
344 fn command_encoder_end_render_pass(
345 &self,
346 encoder: &Self::CommandEncoderId,
347 pass: &mut Self::RenderPassId,
348 );
349 fn command_encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId;
350 fn render_bundle_encoder_finish(
351 &self,
352 encoder: Self::RenderBundleEncoderId,
353 desc: &RenderBundleDescriptor,
354 ) -> Self::RenderBundleId;
355 fn queue_write_buffer(
356 &self,
357 queue: &Self::QueueId,
358 buffer: &Self::BufferId,
359 offset: BufferAddress,
360 data: &[u8],
361 );
362 fn queue_write_texture(
363 &self,
364 queue: &Self::QueueId,
365 texture: TextureCopyView,
366 data: &[u8],
367 data_layout: TextureDataLayout,
368 size: Extent3d,
369 );
370 fn queue_submit<I: Iterator<Item = Self::CommandBufferId>>(
371 &self,
372 queue: &Self::QueueId,
373 command_buffers: I,
374 );
375}
376
377pub struct Instance {
384 context: Arc<C>,
385}
386
387pub struct Adapter {
394 context: Arc<C>,
395 id: <C as Context>::AdapterId,
396}
397
398#[derive(Clone)]
400pub struct RequestAdapterOptions<'a> {
401 pub power_preference: PowerPreference,
403 pub compatible_surface: Option<&'a Surface>,
406}
407
408pub struct Device {
415 context: Arc<C>,
416 id: <C as Context>::DeviceId,
417}
418
419#[derive(Debug, Copy, Clone, PartialEq, Eq)]
422pub enum Maintain {
423 Wait,
425 Poll,
427}
428
429#[derive(Debug)]
433struct MapContext {
434 total_size: BufferAddress,
435 initial_range: Range<BufferAddress>,
436 sub_ranges: Vec<Range<BufferAddress>>,
437}
438
439impl MapContext {
440 fn new(total_size: BufferAddress) -> Self {
441 MapContext {
442 total_size,
443 initial_range: 0..0,
444 sub_ranges: Vec::new(),
445 }
446 }
447
448 fn reset(&mut self) {
449 self.initial_range = 0..0;
450
451 assert!(
452 self.sub_ranges.is_empty(),
453 "You cannot unmap a buffer that still has accessible mapped views"
454 );
455 }
456
457 fn add(&mut self, offset: BufferAddress, size: Option<BufferSize>) -> BufferAddress {
458 let end = match size {
459 Some(s) => offset + s.get(),
460 None => self.initial_range.end,
461 };
462 assert!(self.initial_range.start <= offset && end <= self.initial_range.end);
463 for sub in self.sub_ranges.iter() {
464 assert!(
465 end <= sub.start || offset >= sub.end,
466 "Intersecting map range with {:?}",
467 sub
468 );
469 }
470 self.sub_ranges.push(offset..end);
471 end
472 }
473
474 fn remove(&mut self, offset: BufferAddress, size: Option<BufferSize>) {
475 let end = match size {
476 Some(s) => offset + s.get(),
477 None => self.initial_range.end,
478 };
479
480 let index = self
482 .sub_ranges
483 .iter()
484 .position(|r| *r == (offset..end))
485 .expect("unable to remove range from map context");
486 self.sub_ranges.swap_remove(index);
487 }
488}
489
490pub struct Buffer {
494 context: Arc<C>,
495 id: <C as Context>::BufferId,
496 map_context: Mutex<MapContext>,
497 usage: BufferUsage,
498}
499
500#[derive(Copy, Clone)]
506pub struct BufferSlice<'a> {
507 buffer: &'a Buffer,
508 offset: BufferAddress,
509 size: Option<BufferSize>,
510}
511
512pub struct Texture {
516 context: Arc<C>,
517 id: <C as Context>::TextureId,
518 owned: bool,
519}
520
521pub struct TextureView {
526 context: Arc<C>,
527 id: <C as Context>::TextureViewId,
528 owned: bool,
529}
530
531pub struct Sampler {
537 context: Arc<C>,
538 id: <C as Context>::SamplerId,
539}
540
541impl Drop for Sampler {
542 fn drop(&mut self) {
543 if !thread::panicking() {
544 self.context.sampler_drop(&self.id);
545 }
546 }
547}
548
549pub struct Surface {
554 id: <C as Context>::SurfaceId,
555}
556
557pub struct SwapChain {
562 context: Arc<C>,
563 id: <C as Context>::SwapChainId,
564}
565
566pub struct BindGroupLayout {
573 context: Arc<C>,
574 id: <C as Context>::BindGroupLayoutId,
575}
576
577impl Drop for BindGroupLayout {
578 fn drop(&mut self) {
579 if !thread::panicking() {
580 self.context.bind_group_layout_drop(&self.id);
581 }
582 }
583}
584
585pub struct BindGroup {
592 context: Arc<C>,
593 id: <C as Context>::BindGroupId,
594}
595
596impl Drop for BindGroup {
597 fn drop(&mut self) {
598 if !thread::panicking() {
599 self.context.bind_group_drop(&self.id);
600 }
601 }
602}
603
604pub struct ShaderModule {
610 context: Arc<C>,
611 id: <C as Context>::ShaderModuleId,
612}
613
614impl Drop for ShaderModule {
615 fn drop(&mut self) {
616 if !thread::panicking() {
617 self.context.shader_module_drop(&self.id);
618 }
619 }
620}
621
622pub enum ShaderModuleSource<'a> {
624 SpirV(&'a [u32]),
629 Wgsl(&'a str),
636}
637
638pub struct PipelineLayout {
642 context: Arc<C>,
643 id: <C as Context>::PipelineLayoutId,
644}
645
646impl Drop for PipelineLayout {
647 fn drop(&mut self) {
648 if !thread::panicking() {
649 self.context.pipeline_layout_drop(&self.id);
650 }
651 }
652}
653
654pub struct RenderPipeline {
659 context: Arc<C>,
660 id: <C as Context>::RenderPipelineId,
661}
662
663impl Drop for RenderPipeline {
664 fn drop(&mut self) {
665 if !thread::panicking() {
666 self.context.render_pipeline_drop(&self.id);
667 }
668 }
669}
670
671pub struct ComputePipeline {
676 context: Arc<C>,
677 id: <C as Context>::ComputePipelineId,
678}
679
680impl Drop for ComputePipeline {
681 fn drop(&mut self) {
682 if !thread::panicking() {
683 self.context.compute_pipeline_drop(&self.id);
684 }
685 }
686}
687
688pub struct CommandBuffer {
694 context: Arc<C>,
695 id: Option<<C as Context>::CommandBufferId>,
696}
697
698impl Drop for CommandBuffer {
699 fn drop(&mut self) {
700 if !thread::panicking() {
701 if let Some(ref id) = self.id {
702 self.context.command_buffer_drop(id);
703 }
704 }
705 }
706}
707
708pub struct CommandEncoder {
716 context: Arc<C>,
717 id: <C as Context>::CommandEncoderId,
718 _p: PhantomData<*const u8>,
721}
722
723pub struct RenderPass<'a> {
725 id: <C as Context>::RenderPassId,
726 parent: &'a mut CommandEncoder,
727}
728
729pub struct ComputePass<'a> {
731 id: <C as Context>::ComputePassId,
732 parent: &'a mut CommandEncoder,
733}
734
735pub struct RenderBundleEncoder<'a> {
742 context: Arc<C>,
743 id: <C as Context>::RenderBundleEncoderId,
744 _parent: &'a Device,
745 _p: PhantomData<*const u8>,
748}
749
750pub struct RenderBundle {
757 context: Arc<C>,
758 id: <C as Context>::RenderBundleId,
759}
760
761impl Drop for RenderBundle {
762 fn drop(&mut self) {
763 if !thread::panicking() {
764 self.context.render_bundle_drop(&self.id);
765 }
766 }
767}
768
769pub struct Queue {
774 context: Arc<C>,
775 id: <C as Context>::QueueId,
776}
777
778#[non_exhaustive]
780pub enum BindingResource<'a> {
781 Buffer(BufferSlice<'a>),
786 Sampler(&'a Sampler),
790 TextureView(&'a TextureView),
795 TextureViewArray(&'a [TextureView]),
802}
803
804pub struct Binding<'a> {
806 pub binding: u32,
809 pub resource: BindingResource<'a>,
811}
812
813#[derive(Clone)]
815pub struct BindGroupDescriptor<'a> {
816 pub layout: &'a BindGroupLayout,
818
819 pub bindings: &'a [Binding<'a>],
821
822 pub label: Option<&'a str>,
824}
825
826#[derive(Clone)]
831pub struct PipelineLayoutDescriptor<'a> {
832 pub bind_group_layouts: &'a [&'a BindGroupLayout],
835}
836
837#[derive(Clone)]
839pub struct ProgrammableStageDescriptor<'a> {
840 pub module: &'a ShaderModule,
842
843 pub entry_point: &'a str,
846}
847
848#[derive(Clone)]
850pub struct RenderPipelineDescriptor<'a> {
851 pub layout: &'a PipelineLayout,
853
854 pub vertex_stage: ProgrammableStageDescriptor<'a>,
856
857 pub fragment_stage: Option<ProgrammableStageDescriptor<'a>>,
859
860 pub rasterization_state: Option<RasterizationStateDescriptor>,
862
863 pub primitive_topology: PrimitiveTopology,
865
866 pub color_states: &'a [ColorStateDescriptor],
868
869 pub depth_stencil_state: Option<DepthStencilStateDescriptor>,
871
872 pub vertex_state: VertexStateDescriptor<'a>,
874
875 pub sample_count: u32,
878
879 pub sample_mask: u32,
882
883 pub alpha_to_coverage_enabled: bool,
890}
891
892#[derive(Clone)]
894pub struct ComputePipelineDescriptor<'a> {
895 pub layout: &'a PipelineLayout,
897
898 pub compute_stage: ProgrammableStageDescriptor<'a>,
900}
901
902#[derive(Clone, Copy, Debug, Hash, PartialEq)]
904pub enum LoadOp<V> {
905 Clear(V),
907 Load,
909}
910
911#[derive(Clone, Debug, Hash, PartialEq)]
913pub struct Operations<V> {
914 pub load: LoadOp<V>,
916 pub store: bool,
918}
919
920#[derive(Clone)]
922pub struct RenderPassColorAttachmentDescriptor<'a> {
923 pub attachment: &'a TextureView,
925 pub resolve_target: Option<&'a TextureView>,
927 pub ops: Operations<Color>,
929}
930#[derive(Clone)]
932pub struct RenderPassDepthStencilAttachmentDescriptor<'a> {
933 pub attachment: &'a TextureView,
935 pub depth_ops: Option<Operations<f32>>,
937 pub stencil_ops: Option<Operations<u32>>,
939}
940
941#[derive(Clone)]
943pub struct RenderPassDescriptor<'a, 'b> {
944 pub color_attachments: &'b [RenderPassColorAttachmentDescriptor<'a>],
946
947 pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescriptor<'a>>,
949}
950
951pub use wgt::BufferDescriptor as BufferDescriptorBase;
954pub type BufferDescriptor<'a> = BufferDescriptorBase<Option<&'a str>>;
956
957pub use wgt::CommandEncoderDescriptor as CommandEncoderDescriptorBase;
958pub type CommandEncoderDescriptor<'a> = CommandEncoderDescriptorBase<Option<&'a str>>;
960
961pub use wgt::RenderBundleDescriptor as RenderBundleDescriptorBase;
962pub type RenderBundleDescriptor<'a> = RenderBundleDescriptorBase<Option<&'a str>>;
964
965pub use wgt::TextureDescriptor as TextureDescriptorBase;
966pub type TextureDescriptor<'a> = TextureDescriptorBase<Option<&'a str>>;
968
969pub use wgt::TextureViewDescriptor as TextureViewDescriptorBase;
970pub type TextureViewDescriptor<'a> = TextureViewDescriptorBase<Option<&'a str>>;
972
973pub use wgt::SamplerDescriptor as SamplerDescriptorBase;
974pub type SamplerDescriptor<'a> = SamplerDescriptorBase<Option<&'a str>>;
976
977pub struct SwapChainTexture {
979 pub view: TextureView,
981 detail: <C as Context>::SwapChainOutputDetail,
982}
983
984pub struct SwapChainFrame {
986 pub output: SwapChainTexture,
988 pub suboptimal: bool,
991}
992
993#[derive(Debug)]
995pub enum SwapChainError {
996 Timeout,
998 Outdated,
1000 Lost,
1002 OutOfMemory,
1004}
1005
1006#[derive(Clone)]
1008pub struct BufferCopyView<'a> {
1009 pub buffer: &'a Buffer,
1011
1012 pub layout: TextureDataLayout,
1014}
1015
1016#[derive(Clone)]
1018pub struct TextureCopyView<'a> {
1019 pub texture: &'a Texture,
1021
1022 pub mip_level: u32,
1024
1025 pub origin: Origin3d,
1027}
1028
1029impl Instance {
1030 pub fn new(backends: BackendBit) -> Self {
1037 Instance {
1038 context: Arc::new(C::init(backends)),
1039 }
1040 }
1041
1042 #[cfg(not(target_arch = "wasm32"))]
1048 pub fn enumerate_adapters(&self, backends: BackendBit) -> impl Iterator<Item = Adapter> {
1049 let context = Arc::clone(&self.context);
1050 self.context
1051 .enumerate_adapters(wgc::instance::AdapterInputs::Mask(backends, |_| {
1052 PhantomData
1053 }))
1054 .into_iter()
1055 .map(move |id| crate::Adapter {
1056 id,
1057 context: Arc::clone(&context),
1058 })
1059 }
1060
1061 pub fn request_adapter(
1067 &self,
1068 options: &RequestAdapterOptions<'_>,
1069 ) -> impl Future<Output = Option<Adapter>> + Send {
1070 let context = Arc::clone(&self.context);
1071 self.context
1072 .instance_request_adapter(options)
1073 .map(|option| option.map(|id| Adapter { context, id }))
1074 }
1075
1076 pub unsafe fn create_surface<W: raw_window_handle::HasRawWindowHandle>(
1082 &self,
1083 window: &W,
1084 ) -> Surface {
1085 Surface {
1086 id: Context::instance_create_surface(&*self.context, window),
1087 }
1088 }
1089
1090 #[cfg(any(target_os = "ios", target_os = "macos"))]
1091 pub unsafe fn create_surface_from_core_animation_layer(
1092 &self,
1093 layer: *mut std::ffi::c_void,
1094 ) -> Surface {
1095 let surface = wgc::instance::Surface {
1096 #[cfg(feature = "vulkan-portability")]
1097 vulkan: self.context.instance.vulkan.as_ref().map(|inst| {
1098 inst.create_surface_from_layer(layer as *mut _, cfg!(debug_assertions))
1099 }),
1100 metal: self.context.instance.metal.as_ref().map(|inst| {
1101 inst.create_surface_from_layer(layer as *mut _, cfg!(debug_assertions))
1102 }),
1103 };
1104
1105 crate::Surface {
1106 id: self.context.surfaces.register_identity(
1107 PhantomData,
1108 surface,
1109 &mut wgc::hub::Token::root(),
1110 ),
1111 }
1112 }
1113}
1114
1115impl Adapter {
1116 pub fn request_device(
1133 &self,
1134 desc: &DeviceDescriptor,
1135 trace_path: Option<&std::path::Path>,
1136 ) -> impl Future<Output = Result<(Device, Queue), RequestDeviceError>> + Send {
1137 let context = Arc::clone(&self.context);
1138 Context::adapter_request_device(&*self.context, &self.id, desc, trace_path).map(|result| {
1139 result.map(|(device_id, queue_id)| {
1140 (
1141 Device {
1142 context: Arc::clone(&context),
1143 id: device_id,
1144 },
1145 Queue {
1146 context,
1147 id: queue_id,
1148 },
1149 )
1150 })
1151 })
1152 }
1153
1154 pub fn features(&self) -> Features {
1159 Context::adapter_features(&*self.context, &self.id)
1160 }
1161
1162 pub fn limits(&self) -> Limits {
1167 Context::adapter_limits(&*self.context, &self.id)
1168 }
1169
1170 #[cfg(not(target_arch = "wasm32"))]
1172 pub fn get_info(&self) -> AdapterInfo {
1173 let context = &self.context;
1174 wgc::gfx_select!(self.id => context.adapter_get_info(self.id))
1175 }
1176}
1177
1178impl Device {
1179 pub fn poll(&self, maintain: Maintain) {
1183 Context::device_poll(&*self.context, &self.id, maintain);
1184 }
1185
1186 pub fn features(&self) -> Features {
1190 Context::device_features(&*self.context, &self.id)
1191 }
1192
1193 pub fn limits(&self) -> Limits {
1197 Context::device_limits(&*self.context, &self.id)
1198 }
1199
1200 pub fn create_shader_module(&self, source: ShaderModuleSource) -> ShaderModule {
1202 ShaderModule {
1203 context: Arc::clone(&self.context),
1204 id: Context::device_create_shader_module(&*self.context, &self.id, source),
1205 }
1206 }
1207
1208 pub fn create_command_encoder(&self, desc: &CommandEncoderDescriptor) -> CommandEncoder {
1210 CommandEncoder {
1211 context: Arc::clone(&self.context),
1212 id: Context::device_create_command_encoder(&*self.context, &self.id, desc),
1213 _p: Default::default(),
1214 }
1215 }
1216
1217 pub fn create_render_bundle_encoder(
1219 &self,
1220 desc: &RenderBundleEncoderDescriptor,
1221 ) -> RenderBundleEncoder {
1222 RenderBundleEncoder {
1223 context: Arc::clone(&self.context),
1224 id: Context::device_create_render_bundle_encoder(&*self.context, &self.id, desc),
1225 _parent: self,
1226 _p: Default::default(),
1227 }
1228 }
1229
1230 pub fn create_bind_group(&self, desc: &BindGroupDescriptor) -> BindGroup {
1232 BindGroup {
1233 context: Arc::clone(&self.context),
1234 id: Context::device_create_bind_group(&*self.context, &self.id, desc),
1235 }
1236 }
1237
1238 pub fn create_bind_group_layout(&self, desc: &BindGroupLayoutDescriptor) -> BindGroupLayout {
1240 BindGroupLayout {
1241 context: Arc::clone(&self.context),
1242 id: Context::device_create_bind_group_layout(&*self.context, &self.id, desc),
1243 }
1244 }
1245
1246 pub fn create_pipeline_layout(&self, desc: &PipelineLayoutDescriptor) -> PipelineLayout {
1248 PipelineLayout {
1249 context: Arc::clone(&self.context),
1250 id: Context::device_create_pipeline_layout(&*self.context, &self.id, desc),
1251 }
1252 }
1253
1254 pub fn create_render_pipeline(&self, desc: &RenderPipelineDescriptor) -> RenderPipeline {
1256 RenderPipeline {
1257 context: Arc::clone(&self.context),
1258 id: Context::device_create_render_pipeline(&*self.context, &self.id, desc),
1259 }
1260 }
1261
1262 pub fn create_compute_pipeline(&self, desc: &ComputePipelineDescriptor) -> ComputePipeline {
1264 ComputePipeline {
1265 context: Arc::clone(&self.context),
1266 id: Context::device_create_compute_pipeline(&*self.context, &self.id, desc),
1267 }
1268 }
1269
1270 pub fn create_buffer(&self, desc: &BufferDescriptor) -> Buffer {
1272 let mut map_context = MapContext::new(desc.size);
1273 if desc.mapped_at_creation {
1274 map_context.initial_range = 0..desc.size;
1275 }
1276 Buffer {
1277 context: Arc::clone(&self.context),
1278 id: Context::device_create_buffer(&*self.context, &self.id, desc),
1279 map_context: Mutex::new(map_context),
1280 usage: desc.usage,
1281 }
1282 }
1283
1284 pub fn create_buffer_with_data(&self, data: &[u8], usage: BufferUsage) -> Buffer {
1287 let size = data.len() as u64;
1288 let buffer = self.create_buffer(&BufferDescriptor {
1289 label: None,
1290 size,
1291 usage,
1292 mapped_at_creation: true,
1293 });
1294 Context::buffer_get_mapped_range_mut(&*self.context, &buffer.id, 0..size)
1295 .copy_from_slice(data);
1296 buffer.unmap();
1297 buffer
1298 }
1299
1300 pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture {
1304 Texture {
1305 context: Arc::clone(&self.context),
1306 id: Context::device_create_texture(&*self.context, &self.id, desc),
1307 owned: true,
1308 }
1309 }
1310
1311 pub fn create_sampler(&self, desc: &SamplerDescriptor) -> Sampler {
1315 Sampler {
1316 context: Arc::clone(&self.context),
1317 id: Context::device_create_sampler(&*self.context, &self.id, desc),
1318 }
1319 }
1320
1321 pub fn create_swap_chain(&self, surface: &Surface, desc: &SwapChainDescriptor) -> SwapChain {
1328 SwapChain {
1329 context: Arc::clone(&self.context),
1330 id: Context::device_create_swap_chain(&*self.context, &self.id, &surface.id, desc),
1331 }
1332 }
1333}
1334
1335impl Drop for Device {
1336 fn drop(&mut self) {
1337 if !thread::panicking() {
1338 self.context.device_drop(&self.id);
1339 }
1340 }
1341}
1342
1343#[derive(Clone, PartialEq, Eq, Debug)]
1345pub struct RequestDeviceError;
1346
1347#[derive(Clone, PartialEq, Eq, Debug)]
1349pub struct BufferAsyncError;
1350
1351#[derive(Debug, Clone, Copy, PartialEq)]
1353pub enum MapMode {
1354 Read,
1356 Write,
1358}
1359
1360fn range_to_offset_size<S: RangeBounds<BufferAddress>>(
1361 bounds: S,
1362) -> (BufferAddress, Option<BufferSize>) {
1363 let offset = match bounds.start_bound() {
1364 Bound::Included(&bound) => bound,
1365 Bound::Excluded(&bound) => bound + 1,
1366 Bound::Unbounded => 0,
1367 };
1368 let size = match bounds.end_bound() {
1369 Bound::Included(&bound) => BufferSize::new(bound + 1 - offset),
1370 Bound::Excluded(&bound) => BufferSize::new(bound - offset),
1371 Bound::Unbounded => None,
1372 };
1373
1374 (offset, size)
1375}
1376
1377pub struct BufferView<'a> {
1379 slice: BufferSlice<'a>,
1380 data: &'a [u8],
1381}
1382
1383pub struct BufferViewMut<'a> {
1385 slice: BufferSlice<'a>,
1386 data: &'a mut [u8],
1387 readable: bool,
1388}
1389
1390impl std::ops::Deref for BufferView<'_> {
1391 type Target = [u8];
1392
1393 fn deref(&self) -> &[u8] {
1394 self.data
1395 }
1396}
1397
1398impl std::ops::Deref for BufferViewMut<'_> {
1399 type Target = [u8];
1400
1401 fn deref(&self) -> &[u8] {
1402 assert!(
1403 self.readable,
1404 "Attempting to read a write-only mapping for buffer {:?}",
1405 self.slice.buffer.id
1406 );
1407 self.data
1408 }
1409}
1410
1411impl std::ops::DerefMut for BufferViewMut<'_> {
1412 fn deref_mut(&mut self) -> &mut Self::Target {
1413 self.data
1414 }
1415}
1416
1417impl Drop for BufferView<'_> {
1418 fn drop(&mut self) {
1419 self.slice
1420 .buffer
1421 .map_context
1422 .lock()
1423 .remove(self.slice.offset, self.slice.size);
1424 }
1425}
1426
1427impl Drop for BufferViewMut<'_> {
1428 fn drop(&mut self) {
1429 self.slice
1430 .buffer
1431 .map_context
1432 .lock()
1433 .remove(self.slice.offset, self.slice.size);
1434 }
1435}
1436
1437impl Buffer {
1438 pub fn slice<S: RangeBounds<BufferAddress>>(&self, bounds: S) -> BufferSlice {
1441 let (offset, size) = range_to_offset_size(bounds);
1442 BufferSlice {
1443 buffer: self,
1444 offset,
1445 size,
1446 }
1447 }
1448
1449 pub fn unmap(&self) {
1451 self.map_context.lock().reset();
1452 Context::buffer_unmap(&*self.context, &self.id);
1453 }
1454}
1455
1456impl<'a> BufferSlice<'a> {
1457 pub fn map_async(
1468 &self,
1469 mode: MapMode,
1470 ) -> impl Future<Output = Result<(), BufferAsyncError>> + Send {
1471 let end = {
1472 let mut mc = self.buffer.map_context.lock();
1473 assert_eq!(
1474 mc.initial_range,
1475 0..0,
1476 "Buffer {:?} is already mapped",
1477 self.buffer.id
1478 );
1479 let end = match self.size {
1480 Some(s) => self.offset + s.get(),
1481 None => mc.total_size,
1482 };
1483 mc.initial_range = self.offset..end;
1484 end
1485 };
1486 Context::buffer_map_async(
1487 &*self.buffer.context,
1488 &self.buffer.id,
1489 mode,
1490 self.offset..end,
1491 )
1492 }
1493
1494 pub fn get_mapped_range(&self) -> BufferView<'a> {
1497 let end = self.buffer.map_context.lock().add(self.offset, self.size);
1498 let data = Context::buffer_get_mapped_range(
1499 &*self.buffer.context,
1500 &self.buffer.id,
1501 self.offset..end,
1502 );
1503 BufferView { slice: *self, data }
1504 }
1505
1506 pub fn get_mapped_range_mut(&self) -> BufferViewMut<'a> {
1509 let end = self.buffer.map_context.lock().add(self.offset, self.size);
1510 let data = Context::buffer_get_mapped_range_mut(
1511 &*self.buffer.context,
1512 &self.buffer.id,
1513 self.offset..end,
1514 );
1515 BufferViewMut {
1516 slice: *self,
1517 data,
1518 readable: self.buffer.usage.contains(BufferUsage::MAP_READ),
1519 }
1520 }
1521}
1522
1523impl Drop for Buffer {
1524 fn drop(&mut self) {
1525 if !thread::panicking() {
1526 self.context.buffer_drop(&self.id);
1527 }
1528 }
1529}
1530
1531impl Texture {
1532 pub fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView {
1534 TextureView {
1535 context: Arc::clone(&self.context),
1536 id: Context::texture_create_view(&*self.context, &self.id, Some(desc)),
1537 owned: true,
1538 }
1539 }
1540
1541 pub fn create_default_view(&self) -> TextureView {
1543 TextureView {
1544 context: Arc::clone(&self.context),
1545 id: Context::texture_create_view(&*self.context, &self.id, None),
1546 owned: true,
1547 }
1548 }
1549}
1550
1551impl Drop for Texture {
1552 fn drop(&mut self) {
1553 if self.owned && !thread::panicking() {
1554 self.context.texture_drop(&self.id);
1555 }
1556 }
1557}
1558
1559impl Drop for TextureView {
1560 fn drop(&mut self) {
1561 if self.owned && !thread::panicking() {
1562 self.context.texture_view_drop(&self.id);
1563 }
1564 }
1565}
1566
1567impl CommandEncoder {
1568 pub fn finish(self) -> CommandBuffer {
1570 CommandBuffer {
1571 context: Arc::clone(&self.context),
1572 id: Some(Context::command_encoder_finish(&*self.context, &self.id)),
1573 }
1574 }
1575
1576 pub fn begin_render_pass<'a>(
1580 &'a mut self,
1581 desc: &RenderPassDescriptor<'a, '_>,
1582 ) -> RenderPass<'a> {
1583 RenderPass {
1584 id: Context::command_encoder_begin_render_pass(&*self.context, &self.id, desc),
1585 parent: self,
1586 }
1587 }
1588
1589 pub fn begin_compute_pass(&mut self) -> ComputePass {
1593 ComputePass {
1594 id: Context::command_encoder_begin_compute_pass(&*self.context, &self.id),
1595 parent: self,
1596 }
1597 }
1598
1599 pub fn copy_buffer_to_buffer(
1606 &mut self,
1607 source: &Buffer,
1608 source_offset: BufferAddress,
1609 destination: &Buffer,
1610 destination_offset: BufferAddress,
1611 copy_size: BufferAddress,
1612 ) {
1613 Context::command_encoder_copy_buffer_to_buffer(
1614 &*self.context,
1615 &self.id,
1616 &source.id,
1617 source_offset,
1618 &destination.id,
1619 destination_offset,
1620 copy_size,
1621 );
1622 }
1623
1624 pub fn copy_buffer_to_texture(
1632 &mut self,
1633 source: BufferCopyView,
1634 destination: TextureCopyView,
1635 copy_size: Extent3d,
1636 ) {
1637 Context::command_encoder_copy_buffer_to_texture(
1638 &*self.context,
1639 &self.id,
1640 source,
1641 destination,
1642 copy_size,
1643 );
1644 }
1645
1646 pub fn copy_texture_to_buffer(
1654 &mut self,
1655 source: TextureCopyView,
1656 destination: BufferCopyView,
1657 copy_size: Extent3d,
1658 ) {
1659 Context::command_encoder_copy_texture_to_buffer(
1660 &*self.context,
1661 &self.id,
1662 source,
1663 destination,
1664 copy_size,
1665 );
1666 }
1667
1668 pub fn copy_texture_to_texture(
1676 &mut self,
1677 source: TextureCopyView,
1678 destination: TextureCopyView,
1679 copy_size: Extent3d,
1680 ) {
1681 Context::command_encoder_copy_texture_to_texture(
1682 &*self.context,
1683 &self.id,
1684 source,
1685 destination,
1686 copy_size,
1687 );
1688 }
1689}
1690
1691impl<'a> RenderPass<'a> {
1692 pub fn set_bind_group(
1697 &mut self,
1698 index: u32,
1699 bind_group: &'a BindGroup,
1700 offsets: &[DynamicOffset],
1701 ) {
1702 RenderInner::set_bind_group(&mut self.id, index, &bind_group.id, offsets)
1703 }
1704
1705 pub fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
1709 RenderInner::set_pipeline(&mut self.id, &pipeline.id)
1710 }
1711
1712 pub fn set_blend_color(&mut self, color: Color) {
1716 self.id.set_blend_color(color)
1717 }
1718
1719 pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>) {
1724 RenderInner::set_index_buffer(
1725 &mut self.id,
1726 &buffer_slice.buffer.id,
1727 buffer_slice.offset,
1728 buffer_slice.size,
1729 )
1730 }
1731
1732 pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
1743 RenderInner::set_vertex_buffer(
1744 &mut self.id,
1745 slot,
1746 &buffer_slice.buffer.id,
1747 buffer_slice.offset,
1748 buffer_slice.size,
1749 )
1750 }
1751
1752 pub fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
1756 self.id.set_scissor_rect(x, y, width, height);
1757 }
1758
1759 pub fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
1763 self.id.set_viewport(x, y, w, h, min_depth, max_depth);
1764 }
1765
1766 pub fn set_stencil_reference(&mut self, reference: u32) {
1770 self.id.set_stencil_reference(reference);
1771 }
1772
1773 pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
1777 RenderInner::draw(&mut self.id, vertices, instances)
1778 }
1779
1780 pub fn insert_debug_marker(&mut self, label: &str) {
1782 self.id.insert_debug_marker(label);
1783 }
1784
1785 pub fn push_debug_group(&mut self, label: &str) {
1787 self.id.push_debug_group(label);
1788 }
1789
1790 pub fn pop_debug_group(&mut self) {
1792 self.id.pop_debug_group();
1793 }
1794
1795 pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
1800 RenderInner::draw_indexed(&mut self.id, indices, base_vertex, instances);
1801 }
1802
1803 pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
1819 self.id.draw_indirect(&indirect_buffer.id, indirect_offset);
1820 }
1821
1822 pub fn draw_indexed_indirect(
1841 &mut self,
1842 indirect_buffer: &'a Buffer,
1843 indirect_offset: BufferAddress,
1844 ) {
1845 self.id
1846 .draw_indexed_indirect(&indirect_buffer.id, indirect_offset);
1847 }
1848
1849 pub fn execute_bundles<I: Iterator<Item = &'a RenderBundle>>(&mut self, render_bundles: I) {
1852 self.id
1853 .execute_bundles(render_bundles.into_iter().map(|rb| &rb.id))
1854 }
1855}
1856
1857impl<'a> RenderPass<'a> {
1859 pub fn multi_draw_indirect(
1878 &mut self,
1879 indirect_buffer: &'a Buffer,
1880 indirect_offset: BufferAddress,
1881 count: u32,
1882 ) {
1883 self.id
1884 .multi_draw_indirect(&indirect_buffer.id, indirect_offset, count);
1885 }
1886
1887 pub fn multi_draw_indexed_indirect(
1908 &mut self,
1909 indirect_buffer: &'a Buffer,
1910 indirect_offset: BufferAddress,
1911 count: u32,
1912 ) {
1913 self.id
1914 .multi_draw_indexed_indirect(&indirect_buffer.id, indirect_offset, count);
1915 }
1916}
1917
1918impl<'a> RenderPass<'a> {
1920 pub fn multi_draw_indirect_count(
1951 &mut self,
1952 indirect_buffer: &'a Buffer,
1953 indirect_offset: BufferAddress,
1954 count_buffer: &'a Buffer,
1955 count_offset: BufferAddress,
1956 max_count: u32,
1957 ) {
1958 self.id.multi_draw_indirect_count(
1959 &indirect_buffer.id,
1960 indirect_offset,
1961 &count_buffer.id,
1962 count_offset,
1963 max_count,
1964 );
1965 }
1966
1967 pub fn multi_draw_indexed_indirect_count(
2000 &mut self,
2001 indirect_buffer: &'a Buffer,
2002 indirect_offset: BufferAddress,
2003 count_buffer: &'a Buffer,
2004 count_offset: BufferAddress,
2005 max_count: u32,
2006 ) {
2007 self.id.multi_draw_indexed_indirect_count(
2008 &indirect_buffer.id,
2009 indirect_offset,
2010 &count_buffer.id,
2011 count_offset,
2012 max_count,
2013 );
2014 }
2015}
2016
2017impl<'a> Drop for RenderPass<'a> {
2018 fn drop(&mut self) {
2019 if !thread::panicking() {
2020 self.parent
2021 .context
2022 .command_encoder_end_render_pass(&self.parent.id, &mut self.id);
2023 }
2024 }
2025}
2026
2027impl<'a> ComputePass<'a> {
2028 pub fn set_bind_group(
2033 &mut self,
2034 index: u32,
2035 bind_group: &'a BindGroup,
2036 offsets: &[DynamicOffset],
2037 ) {
2038 ComputePassInner::set_bind_group(&mut self.id, index, &bind_group.id, offsets);
2039 }
2040
2041 pub fn set_pipeline(&mut self, pipeline: &'a ComputePipeline) {
2043 ComputePassInner::set_pipeline(&mut self.id, &pipeline.id);
2044 }
2045
2046 pub fn dispatch(&mut self, x: u32, y: u32, z: u32) {
2050 ComputePassInner::dispatch(&mut self.id, x, y, z);
2051 }
2052
2053 pub fn dispatch_indirect(
2055 &mut self,
2056 indirect_buffer: &'a Buffer,
2057 indirect_offset: BufferAddress,
2058 ) {
2059 ComputePassInner::dispatch_indirect(&mut self.id, &indirect_buffer.id, indirect_offset);
2060 }
2061}
2062
2063impl<'a> Drop for ComputePass<'a> {
2064 fn drop(&mut self) {
2065 if !thread::panicking() {
2066 self.parent
2067 .context
2068 .command_encoder_end_compute_pass(&self.parent.id, &mut self.id);
2069 }
2070 }
2071}
2072
2073impl<'a> RenderBundleEncoder<'a> {
2074 pub fn finish(self, desc: &RenderBundleDescriptor) -> RenderBundle {
2076 RenderBundle {
2077 context: Arc::clone(&self.context),
2078 id: Context::render_bundle_encoder_finish(&*self.context, self.id, desc),
2079 }
2080 }
2081
2082 pub fn set_bind_group(
2087 &mut self,
2088 index: u32,
2089 bind_group: &'a BindGroup,
2090 offsets: &[DynamicOffset],
2091 ) {
2092 RenderInner::set_bind_group(&mut self.id, index, &bind_group.id, offsets)
2093 }
2094
2095 pub fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
2099 RenderInner::set_pipeline(&mut self.id, &pipeline.id)
2100 }
2101
2102 pub fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>) {
2107 RenderInner::set_index_buffer(
2108 &mut self.id,
2109 &buffer_slice.buffer.id,
2110 buffer_slice.offset,
2111 buffer_slice.size,
2112 )
2113 }
2114
2115 pub fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
2126 RenderInner::set_vertex_buffer(
2127 &mut self.id,
2128 slot,
2129 &buffer_slice.buffer.id,
2130 buffer_slice.offset,
2131 buffer_slice.size,
2132 )
2133 }
2134
2135 pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
2139 RenderInner::draw(&mut self.id, vertices, instances)
2140 }
2141
2142 pub fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
2147 RenderInner::draw_indexed(&mut self.id, indices, base_vertex, instances);
2148 }
2149
2150 pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
2166 self.id.draw_indirect(&indirect_buffer.id, indirect_offset);
2167 }
2168
2169 pub fn draw_indexed_indirect(
2188 &mut self,
2189 indirect_buffer: &'a Buffer,
2190 indirect_offset: BufferAddress,
2191 ) {
2192 self.id
2193 .draw_indexed_indirect(&indirect_buffer.id, indirect_offset);
2194 }
2195}
2196
2197impl Queue {
2198 pub fn write_buffer(&self, buffer: &Buffer, offset: BufferAddress, data: &[u8]) {
2200 Context::queue_write_buffer(&*self.context, &self.id, &buffer.id, offset, data)
2201 }
2202
2203 pub fn write_texture(
2205 &self,
2206 texture: TextureCopyView,
2207 data: &[u8],
2208 data_layout: TextureDataLayout,
2209 size: Extent3d,
2210 ) {
2211 Context::queue_write_texture(&*self.context, &self.id, texture, data, data_layout, size)
2212 }
2213
2214 pub fn submit<I: IntoIterator<Item = CommandBuffer>>(&self, command_buffers: I) {
2216 Context::queue_submit(
2217 &*self.context,
2218 &self.id,
2219 command_buffers
2220 .into_iter()
2221 .map(|mut comb| comb.id.take().unwrap()),
2222 );
2223 }
2224}
2225
2226impl Drop for SwapChainTexture {
2227 fn drop(&mut self) {
2228 if !thread::panicking() {
2229 Context::swap_chain_present(&*self.view.context, &self.view.id, &self.detail);
2230 }
2231 }
2232}
2233
2234impl SwapChain {
2235 pub fn get_next_frame(&mut self) -> Result<SwapChainFrame, SwapChainError> {
2243 let (view_id, status, detail) =
2244 Context::swap_chain_get_next_texture(&*self.context, &self.id);
2245 let output = view_id.map(|id| SwapChainTexture {
2246 view: TextureView {
2247 context: Arc::clone(&self.context),
2248 id: id,
2249 owned: false,
2250 },
2251 detail,
2252 });
2253
2254 match status {
2255 SwapChainStatus::Good => Ok(SwapChainFrame {
2256 output: output.unwrap(),
2257 suboptimal: false,
2258 }),
2259 SwapChainStatus::Suboptimal => Ok(SwapChainFrame {
2260 output: output.unwrap(),
2261 suboptimal: true,
2262 }),
2263 SwapChainStatus::Timeout => Err(SwapChainError::Timeout),
2264 SwapChainStatus::Outdated => Err(SwapChainError::Outdated),
2265 SwapChainStatus::Lost => Err(SwapChainError::Lost),
2266 SwapChainStatus::OutOfMemory => Err(SwapChainError::OutOfMemory),
2267 }
2268 }
2269}