1use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec};
2use core::ptr::NonNull;
3
4#[cfg(feature = "trace")]
5use crate::device::trace;
6use crate::{
7 binding_model::{self},
8 command,
9 device::{life::WaitIdleError, DeviceError, DeviceLostClosure},
10 global::Global,
11 id::{self, AdapterId, DeviceId, QueueId, SurfaceId},
12 instance::{self, Adapter, Surface},
13 pipeline::{
14 self, MeshState, ProgrammableStageDescriptor, RenderPipelineVertexProcessor,
15 ResolvedGeneralRenderPipelineDescriptor, TaskState,
16 },
17 present,
18 resource::{
19 self, BufferAccessError, BufferAccessResult, BufferMapOperation, CreateBufferError,
20 },
21 storage::Storage,
22 Label, LabelHelpers,
23};
24
25use wgt::{BufferAddress, TextureFormat};
26
27pub type BindGroupDescriptor<'a> = binding_model::BindGroupDescriptor<
28 'a,
29 id::BindGroupLayoutId,
30 id::BufferId,
31 id::SamplerId,
32 id::TextureViewId,
33 id::TlasId,
34 id::ExternalTextureId,
35>;
36
37pub type BindGroupEntry<'a> = binding_model::BindGroupEntry<
38 'a,
39 id::BufferId,
40 id::SamplerId,
41 id::TextureViewId,
42 id::TlasId,
43 id::ExternalTextureId,
44>;
45
46pub type BufferBinding = binding_model::BufferBinding<id::BufferId>;
47
48pub type BindingResource<'a> = binding_model::BindingResource<
49 'a,
50 id::BufferId,
51 id::SamplerId,
52 id::TextureViewId,
53 id::TlasId,
54 id::ExternalTextureId,
55>;
56
57pub type ComputePipelineDescriptor<'a> = pipeline::ComputePipelineDescriptor<
58 'a,
59 id::PipelineLayoutId,
60 id::ShaderModuleId,
61 id::PipelineCacheId,
62>;
63
64pub type VertexState<'a> = pipeline::VertexState<'a, id::ShaderModuleId>;
65
66pub type MeshPipelineDescriptor<'a> = pipeline::MeshPipelineDescriptor<
67 'a,
68 id::PipelineLayoutId,
69 id::ShaderModuleId,
70 id::PipelineCacheId,
71>;
72
73pub type RenderPipelineDescriptor<'a> = pipeline::RenderPipelineDescriptor<
74 'a,
75 id::PipelineLayoutId,
76 id::ShaderModuleId,
77 id::PipelineCacheId,
78>;
79
80pub type GeneralRenderPipelineDescriptor<'a> = pipeline::GeneralRenderPipelineDescriptor<
81 'a,
82 id::PipelineLayoutId,
83 id::ShaderModuleId,
84 id::PipelineCacheId,
85>;
86
87impl Global {
88 pub fn adapter_is_surface_supported(
89 &self,
90 adapter_id: AdapterId,
91 surface_id: SurfaceId,
92 ) -> bool {
93 let surface = self.surfaces.get(surface_id);
94 let adapter = self.hub.adapters.get(adapter_id);
95 adapter.is_surface_supported(&surface)
96 }
97
98 pub fn surface_get_capabilities(
99 &self,
100 surface_id: SurfaceId,
101 adapter_id: AdapterId,
102 ) -> Result<wgt::SurfaceCapabilities, instance::GetSurfaceSupportError> {
103 self.fetch_adapter_and_surface::<_, _>(surface_id, adapter_id, |adapter, surface| {
104 surface.get_capabilities(adapter)
105 })
106 }
107
108 pub fn surface_display_hdr_info(
118 &self,
119 surface_id: SurfaceId,
120 adapter_id: AdapterId,
121 ) -> wgt::DisplayHdrInfo {
122 self.fetch_adapter_and_surface(surface_id, adapter_id, |adapter, surface| {
123 surface.display_hdr_info(adapter)
124 })
125 }
126
127 fn fetch_adapter_and_surface<F: FnOnce(&Adapter, &Surface) -> B, B>(
128 &self,
129 surface_id: SurfaceId,
130 adapter_id: AdapterId,
131 get_supported_callback: F,
132 ) -> B {
133 let surface = self.surfaces.get(surface_id);
134 let adapter = self.hub.adapters.get(adapter_id);
135 get_supported_callback(&adapter, &surface)
136 }
137
138 pub fn device_features(&self, device_id: DeviceId) -> wgt::Features {
139 let device = self.hub.devices.get(device_id);
140 *device.features()
141 }
142
143 pub fn device_limits(&self, device_id: DeviceId) -> wgt::Limits {
144 let device = self.hub.devices.get(device_id);
145 device.limits().clone()
146 }
147
148 pub fn device_adapter_info(&self, device_id: DeviceId) -> wgt::AdapterInfo {
149 let device = self.hub.devices.get(device_id);
150 device.adapter.get_info()
151 }
152
153 pub fn device_downlevel_properties(&self, device_id: DeviceId) -> wgt::DownlevelCapabilities {
154 let device = self.hub.devices.get(device_id);
155 device.downlevel().clone()
156 }
157
158 pub fn device_create_buffer(
159 &self,
160 device_id: DeviceId,
161 desc: &resource::BufferDescriptor,
162 id_in: Option<id::BufferId>,
163 ) -> (id::BufferId, Option<CreateBufferError>) {
164 let hub = &self.hub;
165 let fid = hub.buffers.prepare(id_in);
166
167 let device = self.hub.devices.get(device_id);
168
169 let (buffer, error) = device.create_buffer(desc);
170
171 let id = fid.assign(buffer);
172
173 (id, error)
174 }
175
176 pub fn create_buffer_error(
205 &self,
206 device_id: DeviceId,
207 id_in: Option<id::BufferId>,
208 desc: &resource::BufferDescriptor,
209 ) {
210 let fid = self.hub.buffers.prepare(id_in);
211 let device = self.hub.devices.get(device_id);
212 fid.assign(resource::Buffer::invalid(device, desc));
213 }
214
215 pub fn create_render_bundle_error(
219 &self,
220 device_id: DeviceId,
221 id_in: Option<id::RenderBundleId>,
222 desc: &command::RenderBundleDescriptor,
223 ) {
224 let device = self.hub.devices.get(device_id);
225 let fid = self.hub.render_bundles.prepare(id_in);
226 fid.assign(command::RenderBundle::invalid(device, desc));
227 }
228
229 pub fn create_texture_error(
233 &self,
234 device_id: DeviceId,
235 id_in: Option<id::TextureId>,
236 desc: &resource::TextureDescriptor,
237 ) -> id::TextureId {
238 let fid = self.hub.textures.prepare(id_in);
239 let device = self.hub.devices.get(device_id);
240 let texture = device.create_texture_error(desc);
241 fid.assign(texture)
242 }
243
244 pub fn create_external_texture_error(
248 &self,
249 device_id: DeviceId,
250 id_in: Option<id::ExternalTextureId>,
251 desc: &resource::ExternalTextureDescriptor,
252 ) {
253 let fid = self.hub.external_textures.prepare(id_in);
254 let device = self.hub.devices.get(device_id);
255 fid.assign(resource::ExternalTexture::invalid(device, desc));
256 }
257
258 pub fn create_bind_group_layout_error(
267 &self,
268 device_id: DeviceId,
269 id_in: Option<id::BindGroupLayoutId>,
270 label: Option<Cow<'_, str>>,
271 ) {
272 let fid = self.hub.bind_group_layouts.prepare(id_in);
273 let device = self.hub.devices.get(device_id);
274 fid.assign(binding_model::BindGroupLayout::invalid(
275 &device,
276 label.to_string(),
277 ));
278 }
279
280 pub fn buffer_destroy(&self, buffer_id: id::BufferId) {
281 let hub = &self.hub;
282
283 let buffer = hub.buffers.get(buffer_id);
284
285 buffer.destroy();
286 }
287
288 pub fn buffer_drop(&self, buffer_id: id::BufferId) {
289 let hub = &self.hub;
290
291 let _buffer = hub.buffers.remove(buffer_id);
292 }
293
294 pub fn device_create_texture(
295 &self,
296 device_id: DeviceId,
297 desc: &resource::TextureDescriptor,
298 id_in: Option<id::TextureId>,
299 ) -> (id::TextureId, Option<resource::CreateTextureError>) {
300 let hub = &self.hub;
301
302 let fid = hub.textures.prepare(id_in);
303
304 let device = self.hub.devices.get(device_id);
305
306 let (texture, error) = device.create_texture(desc);
307
308 let id = fid.assign(texture);
309
310 (id, error)
311 }
312
313 pub fn device_validate_texture_descriptor(
314 &self,
315 device_id: DeviceId,
316 desc: &resource::TextureDescriptor,
317 ) -> Option<resource::CreateTextureError> {
318 self.hub
319 .devices
320 .get(device_id)
321 .validate_texture_descriptor(desc)
322 .err()
323 }
324
325 pub unsafe fn create_texture_from_hal(
333 &self,
334 hal_texture: Box<dyn hal::DynTexture>,
335 device_id: DeviceId,
336 desc: &resource::TextureDescriptor,
337 initial_state: wgt::TextureUses,
338 id_in: Option<id::TextureId>,
339 ) -> (id::TextureId, Option<resource::CreateTextureError>) {
340 let hub = &self.hub;
341
342 let fid = hub.textures.prepare(id_in);
343
344 let device = self.hub.devices.get(device_id);
345
346 let (texture, error) =
347 unsafe { device.create_texture_from_hal(hal_texture, desc, initial_state) };
348
349 let id = fid.assign(texture);
350 (id, error)
351 }
352
353 pub unsafe fn create_buffer_from_hal<A: hal::Api>(
360 &self,
361 hal_buffer: A::Buffer,
362 device_id: DeviceId,
363 desc: &resource::BufferDescriptor,
364 id_in: Option<id::BufferId>,
365 ) -> (id::BufferId, Option<CreateBufferError>) {
366 let hub = &self.hub;
367 let fid = hub.buffers.prepare(id_in);
368
369 let device = self.hub.devices.get(device_id);
370
371 let (buffer, err) = unsafe { device.create_buffer_from_hal(Box::new(hal_buffer), desc) };
372
373 let id = fid.assign(buffer);
374
375 (id, err)
376 }
377
378 pub fn texture_destroy(&self, texture_id: id::TextureId) {
379 let hub = &self.hub;
380
381 let texture = hub.textures.get(texture_id);
382
383 texture.destroy();
384 }
385
386 pub fn texture_drop(&self, texture_id: id::TextureId) {
387 let hub = &self.hub;
388
389 hub.textures.remove(texture_id);
390 }
391
392 pub fn texture_create_view(
393 &self,
394 texture_id: id::TextureId,
395 desc: &resource::TextureViewDescriptor,
396 id_in: Option<id::TextureViewId>,
397 ) -> (id::TextureViewId, Option<resource::CreateTextureViewError>) {
398 let hub = &self.hub;
399
400 let fid = hub.texture_views.prepare(id_in);
401
402 let texture = hub.textures.get(texture_id);
403
404 let (view, error) = texture.create_view(desc);
405
406 let id = fid.assign(view);
407
408 (id, error)
409 }
410
411 pub fn texture_view_drop(&self, texture_view_id: id::TextureViewId) {
412 let hub = &self.hub;
413
414 let _view = hub.texture_views.remove(texture_view_id);
415 }
416
417 pub fn device_create_external_texture(
418 &self,
419 device_id: DeviceId,
420 desc: &resource::ExternalTextureDescriptor,
421 planes: &[id::TextureViewId],
422 id_in: Option<id::ExternalTextureId>,
423 ) -> (
424 id::ExternalTextureId,
425 Option<resource::CreateExternalTextureError>,
426 ) {
427 let hub = &self.hub;
428
429 let fid = hub.external_textures.prepare(id_in);
430
431 let device = self.hub.devices.get(device_id);
432
433 let planes = planes
434 .iter()
435 .map(|plane_id| self.hub.texture_views.get(*plane_id))
436 .collect::<Vec<_>>();
437
438 let (external_texture, error) = device.create_external_texture(desc, &planes);
439
440 let id = fid.assign(external_texture);
441
442 (id, error)
443 }
444
445 pub fn external_texture_destroy(&self, external_texture_id: id::ExternalTextureId) {
446 let hub = &self.hub;
447
448 let external_texture = hub.external_textures.get(external_texture_id);
449
450 external_texture.destroy();
451 }
452
453 pub fn external_texture_drop(&self, external_texture_id: id::ExternalTextureId) {
454 let hub = &self.hub;
455
456 let _external_texture = hub.external_textures.remove(external_texture_id);
457 }
458
459 pub fn device_create_sampler(
460 &self,
461 device_id: DeviceId,
462 desc: &resource::SamplerDescriptor,
463 id_in: Option<id::SamplerId>,
464 ) -> (id::SamplerId, Option<resource::CreateSamplerError>) {
465 let hub = &self.hub;
466 let fid = hub.samplers.prepare(id_in);
467
468 let device = self.hub.devices.get(device_id);
469
470 let (sampler, error) = device.create_sampler(desc);
471
472 let id = fid.assign(sampler);
473
474 (id, error)
475 }
476
477 pub fn sampler_drop(&self, sampler_id: id::SamplerId) {
478 let hub = &self.hub;
479
480 let _sampler = hub.samplers.remove(sampler_id);
481 }
482
483 pub fn device_create_bind_group_layout(
484 &self,
485 device_id: DeviceId,
486 desc: &binding_model::BindGroupLayoutDescriptor,
487 id_in: Option<id::BindGroupLayoutId>,
488 ) -> (
489 id::BindGroupLayoutId,
490 Option<binding_model::CreateBindGroupLayoutError>,
491 ) {
492 let hub = &self.hub;
493 let fid = hub.bind_group_layouts.prepare(id_in);
494
495 let device = self.hub.devices.get(device_id);
496
497 let (bgl, error) = device.create_bind_group_layout(desc);
498
499 let id = fid.assign(bgl);
500
501 (id, error)
502 }
503
504 pub fn bind_group_layout_drop(&self, bind_group_layout_id: id::BindGroupLayoutId) {
505 let hub = &self.hub;
506
507 let _layout = hub.bind_group_layouts.remove(bind_group_layout_id);
508 }
509
510 pub fn device_create_pipeline_layout(
511 &self,
512 device_id: DeviceId,
513 desc: &binding_model::PipelineLayoutDescriptor<id::BindGroupLayoutId>,
514 id_in: Option<id::PipelineLayoutId>,
515 ) -> (
516 id::PipelineLayoutId,
517 Option<binding_model::CreatePipelineLayoutError>,
518 ) {
519 let hub = &self.hub;
520 let fid = hub.pipeline_layouts.prepare(id_in);
521
522 let device = self.hub.devices.get(device_id);
523
524 let bind_group_layouts = {
525 let bind_group_layouts_guard = hub.bind_group_layouts.read();
526 desc.bind_group_layouts
527 .iter()
528 .map(|bgl_id| bgl_id.map(|bgl_id| bind_group_layouts_guard.get(bgl_id)))
529 .collect::<Vec<_>>()
530 };
531
532 let desc = binding_model::PipelineLayoutDescriptor {
533 label: desc.label.clone(),
534 bind_group_layouts: Cow::Owned(bind_group_layouts),
535 immediate_size: desc.immediate_size,
536 };
537
538 let (layout, error) = device.create_pipeline_layout(&desc);
539 let id = fid.assign(layout);
540 (id, error)
541 }
542
543 pub fn pipeline_layout_drop(&self, pipeline_layout_id: id::PipelineLayoutId) {
544 let hub = &self.hub;
545
546 let _layout = hub.pipeline_layouts.remove(pipeline_layout_id);
547 }
548
549 pub fn device_create_bind_group(
550 &self,
551 device_id: DeviceId,
552 desc: &BindGroupDescriptor,
553 id_in: Option<id::BindGroupId>,
554 ) -> (id::BindGroupId, Option<binding_model::CreateBindGroupError>) {
555 let hub = &self.hub;
556 let fid = hub.bind_groups.prepare(id_in);
557
558 let device = hub.devices.get(device_id);
559
560 let layout = hub.bind_group_layouts.get(desc.layout);
561
562 fn resolve_entry<'a>(
563 e: &BindGroupEntry<'a>,
564 buffer_storage: &Storage<Arc<resource::Buffer>>,
565 sampler_storage: &Storage<Arc<resource::Sampler>>,
566 texture_view_storage: &Storage<Arc<resource::TextureView>>,
567 tlas_storage: &Storage<Arc<resource::Tlas>>,
568 external_texture_storage: &Storage<Arc<resource::ExternalTexture>>,
569 ) -> binding_model::BindGroupEntry<'a> {
570 let resolve_buffer = |bb: &BufferBinding| {
571 let buffer = buffer_storage.get(bb.buffer);
572 binding_model::BufferBinding {
573 buffer,
574 offset: bb.offset,
575 size: bb.size,
576 }
577 };
578 let resolve_sampler = |id: &id::SamplerId| sampler_storage.get(*id);
579 let resolve_view = |id: &id::TextureViewId| texture_view_storage.get(*id);
580 let resolve_tlas = |id: &id::TlasId| tlas_storage.get(*id);
581 let resolve_external_texture =
582 |id: &id::ExternalTextureId| external_texture_storage.get(*id);
583 let resource = match e.resource {
584 BindingResource::Buffer(ref buffer) => {
585 binding_model::BindingResource::Buffer(resolve_buffer(buffer))
586 }
587 BindingResource::BufferArray(ref buffers) => {
588 let buffers = buffers.iter().map(resolve_buffer).collect::<Vec<_>>();
589 binding_model::BindingResource::BufferArray(Cow::Owned(buffers))
590 }
591 BindingResource::Sampler(ref sampler) => {
592 binding_model::BindingResource::Sampler(resolve_sampler(sampler))
593 }
594 BindingResource::SamplerArray(ref samplers) => {
595 let samplers = samplers.iter().map(resolve_sampler).collect::<Vec<_>>();
596 binding_model::BindingResource::SamplerArray(Cow::Owned(samplers))
597 }
598 BindingResource::TextureView(ref view) => {
599 binding_model::BindingResource::TextureView(resolve_view(view))
600 }
601 BindingResource::TextureViewArray(ref views) => {
602 let views = views.iter().map(resolve_view).collect::<Vec<_>>();
603 binding_model::BindingResource::TextureViewArray(Cow::Owned(views))
604 }
605 BindingResource::AccelerationStructure(ref tlas) => {
606 binding_model::BindingResource::AccelerationStructure(resolve_tlas(tlas))
607 }
608 BindingResource::AccelerationStructureArray(ref tlas_array) => {
609 let tlas_array = tlas_array.iter().map(resolve_tlas).collect::<Vec<_>>();
610 binding_model::BindingResource::AccelerationStructureArray(Cow::Owned(
611 tlas_array,
612 ))
613 }
614 BindingResource::ExternalTexture(ref et) => {
615 binding_model::BindingResource::ExternalTexture(resolve_external_texture(et))
616 }
617 };
618 binding_model::BindGroupEntry {
619 binding: e.binding,
620 resource,
621 }
622 }
623
624 let entries = {
625 let buffer_guard = hub.buffers.read();
626 let texture_view_guard = hub.texture_views.read();
627 let sampler_guard = hub.samplers.read();
628 let tlas_guard = hub.tlas_s.read();
629 let external_texture_guard = hub.external_textures.read();
630 desc.entries
631 .iter()
632 .map(|e| {
633 resolve_entry(
634 e,
635 &buffer_guard,
636 &sampler_guard,
637 &texture_view_guard,
638 &tlas_guard,
639 &external_texture_guard,
640 )
641 })
642 .collect::<Vec<_>>()
643 };
644 let entries = Cow::Owned(entries);
645
646 let desc = binding_model::BindGroupDescriptor {
647 label: desc.label.clone(),
648 layout,
649 entries,
650 };
651
652 let (bind_group, error) = device.create_bind_group(&desc);
653
654 let id = fid.assign(bind_group);
655 (id, error)
656 }
657
658 pub fn bind_group_drop(&self, bind_group_id: id::BindGroupId) {
659 let hub = &self.hub;
660
661 let _bind_group = hub.bind_groups.remove(bind_group_id);
662 }
663
664 pub fn device_create_shader_module(
679 &self,
680 device_id: DeviceId,
681 desc: &pipeline::ShaderModuleDescriptor,
682 source: pipeline::ShaderModuleSource,
683 id_in: Option<id::ShaderModuleId>,
684 ) -> (
685 id::ShaderModuleId,
686 Option<pipeline::CreateShaderModuleError>,
687 ) {
688 let hub = &self.hub;
689 let fid = hub.shader_modules.prepare(id_in);
690
691 let device = self.hub.devices.get(device_id);
692
693 let (shader, error) = device.create_shader_module(desc, source);
694
695 let id = fid.assign(shader);
696
697 (id, error)
698 }
699
700 pub unsafe fn device_create_shader_module_passthrough(
705 &self,
706 device_id: DeviceId,
707 desc: &pipeline::ShaderModuleDescriptorPassthrough<'_>,
708 id_in: Option<id::ShaderModuleId>,
709 ) -> (
710 id::ShaderModuleId,
711 Option<pipeline::CreateShaderModuleError>,
712 ) {
713 let hub = &self.hub;
714 let fid = hub.shader_modules.prepare(id_in);
715
716 let device = self.hub.devices.get(device_id);
717
718 let (shader, error) = unsafe { device.create_shader_module_passthrough(desc) };
719
720 let id = fid.assign(shader);
721
722 (id, error)
723 }
724
725 pub fn shader_module_drop(&self, shader_module_id: id::ShaderModuleId) {
726 let hub = &self.hub;
727
728 let _shader_module = hub.shader_modules.remove(shader_module_id);
729 }
730
731 pub fn device_create_command_encoder(
732 &self,
733 device_id: DeviceId,
734 desc: &wgt::CommandEncoderDescriptor<Label>,
735 id_in: Option<id::CommandEncoderId>,
736 ) -> (id::CommandEncoderId, Option<DeviceError>) {
737 let hub = &self.hub;
738 let fid = hub.command_encoders.prepare(id_in);
739
740 let device = self.hub.devices.get(device_id);
741
742 let (cmd_enc, error) = device.create_command_encoder(desc);
743
744 let id = fid.assign(cmd_enc);
745 (id, error)
746 }
747
748 pub fn command_encoder_drop(&self, command_encoder_id: id::CommandEncoderId) {
749 let _cmd_enc = self.hub.command_encoders.remove(command_encoder_id);
750 }
751
752 pub fn command_buffer_drop(&self, command_buffer_id: id::CommandBufferId) {
753 let _cmd_buf = self.hub.command_buffers.remove(command_buffer_id);
754 }
755
756 pub fn device_create_render_bundle_encoder(
757 &self,
758 device_id: DeviceId,
759 desc: &command::RenderBundleEncoderDescriptor,
760 ) -> (
761 Box<command::RenderBundleEncoder>,
762 Option<command::CreateRenderBundleError>,
763 ) {
764 let device = self.hub.devices.get(device_id);
765 device.create_render_bundle_encoder(desc)
766 }
767
768 pub fn device_create_render_bundle_encoder_with_id(
769 &self,
770 device_id: DeviceId,
771 desc: &command::RenderBundleEncoderDescriptor,
772 id_in: Option<id::RenderBundleEncoderId>,
773 ) -> (
774 id::RenderBundleEncoderId,
775 Option<command::CreateRenderBundleError>,
776 ) {
777 let fid = self.hub.render_bundle_encoders.prepare(id_in);
778
779 let (render_bundle_encoder, error) =
780 self.device_create_render_bundle_encoder(device_id, desc);
781
782 let id = fid.assign(Arc::new(parking_lot::Mutex::new(*render_bundle_encoder)));
786
787 (id, error)
788 }
789
790 pub fn render_bundle_encoder_finish(
791 &self,
792 bundle_encoder: &mut command::RenderBundleEncoder,
793 desc: &command::RenderBundleDescriptor,
794 id_in: Option<id::RenderBundleId>,
795 ) -> (id::RenderBundleId, Option<command::RenderBundleError>) {
796 let hub = &self.hub;
797
798 let fid = hub.render_bundles.prepare(id_in);
799
800 let (render_bundle, error) = bundle_encoder.finish(desc);
801
802 let id = fid.assign(render_bundle);
803
804 (id, error)
805 }
806
807 pub fn render_bundle_encoder_finish_with_id(
808 &self,
809 render_bundle_encoder_id: id::RenderBundleEncoderId,
810 desc: &command::RenderBundleDescriptor,
811 id_in: Option<id::RenderBundleId>,
812 ) -> (id::RenderBundleId, Option<command::RenderBundleError>) {
813 let bundle_encoder = self
814 .hub
815 .render_bundle_encoders
816 .get(render_bundle_encoder_id);
817
818 let mut bundle_encoder = bundle_encoder
819 .try_lock()
820 .expect("RenderBundleEncoders should not be accessed concurrently");
821
822 let (id, error) = self.render_bundle_encoder_finish(&mut bundle_encoder, desc, id_in);
823
824 (id, error)
825 }
826
827 pub fn render_bundle_encoder_drop(&self, render_bundle_encoder_id: id::RenderBundleEncoderId) {
828 let hub = &self.hub;
829
830 let _bundle_encoder = hub.render_bundle_encoders.remove(render_bundle_encoder_id);
831 }
832
833 pub fn render_bundle_drop(&self, render_bundle_id: id::RenderBundleId) {
834 let hub = &self.hub;
835
836 let _bundle = hub.render_bundles.remove(render_bundle_id);
837 }
838
839 pub fn device_create_query_set(
840 &self,
841 device_id: DeviceId,
842 desc: &resource::QuerySetDescriptor,
843 id_in: Option<id::QuerySetId>,
844 ) -> (id::QuerySetId, Option<resource::CreateQuerySetError>) {
845 let hub = &self.hub;
846 let fid = hub.query_sets.prepare(id_in);
847
848 let device = self.hub.devices.get(device_id);
849
850 let (query_set, error) = device.create_query_set(desc);
851
852 let id = fid.assign(query_set);
853
854 (id, error)
855 }
856
857 pub fn query_set_destroy(&self, query_set_id: id::QuerySetId) {
858 let hub = &self.hub;
859
860 let query_set = hub.query_sets.get(query_set_id);
861
862 query_set.destroy();
863 }
864
865 pub fn query_set_drop(&self, query_set_id: id::QuerySetId) {
866 let hub = &self.hub;
867
868 let _query_set = hub.query_sets.remove(query_set_id);
869 }
870
871 pub fn device_create_render_pipeline(
872 &self,
873 device_id: DeviceId,
874 desc: &RenderPipelineDescriptor,
875 id_in: Option<id::RenderPipelineId>,
876 ) -> (
877 id::RenderPipelineId,
878 Option<pipeline::CreateRenderPipelineError>,
879 ) {
880 let hub = &self.hub;
881
882 let fid = hub.render_pipelines.prepare(id_in);
883
884 let device = self.hub.devices.get(device_id);
885
886 self.device_create_general_render_pipeline(desc.clone().into(), device, fid)
887 }
888
889 pub fn device_create_mesh_pipeline(
890 &self,
891 device_id: DeviceId,
892 desc: &MeshPipelineDescriptor,
893 id_in: Option<id::RenderPipelineId>,
894 ) -> (
895 id::RenderPipelineId,
896 Option<pipeline::CreateRenderPipelineError>,
897 ) {
898 let hub = &self.hub;
899
900 let fid = hub.render_pipelines.prepare(id_in);
901
902 let device = self.hub.devices.get(device_id);
903 self.device_create_general_render_pipeline(desc.clone().into(), device, fid)
904 }
905
906 fn device_create_general_render_pipeline(
907 &self,
908 desc: GeneralRenderPipelineDescriptor,
909 device: Arc<crate::device::resource::Device>,
910 fid: crate::registry::FutureId<Arc<pipeline::RenderPipeline>>,
911 ) -> (
912 id::RenderPipelineId,
913 Option<pipeline::CreateRenderPipelineError>,
914 ) {
915 let hub = &self.hub;
916
917 let layout = desc.layout.map(|layout| hub.pipeline_layouts.get(layout));
918
919 let cache = desc.cache.map(|cache| hub.pipeline_caches.get(cache));
920
921 let vertex = match desc.vertex {
922 RenderPipelineVertexProcessor::Vertex(ref vertex) => {
923 let module = hub.shader_modules.get(vertex.stage.module);
924 let stage = ProgrammableStageDescriptor {
925 module,
926 entry_point: vertex.stage.entry_point.clone(),
927 constants: vertex.stage.constants.clone(),
928 zero_initialize_workgroup_memory: vertex.stage.zero_initialize_workgroup_memory,
929 };
930 RenderPipelineVertexProcessor::Vertex(pipeline::VertexState {
931 stage,
932 buffers: vertex.buffers.clone(),
933 })
934 }
935 RenderPipelineVertexProcessor::Mesh(ref task, ref mesh) => {
936 let task_module = if let Some(task) = task {
937 let module = hub.shader_modules.get(task.stage.module);
938
939 let state = ProgrammableStageDescriptor {
940 module,
941 entry_point: task.stage.entry_point.clone(),
942 constants: task.stage.constants.clone(),
943 zero_initialize_workgroup_memory: task
944 .stage
945 .zero_initialize_workgroup_memory,
946 };
947 Some(TaskState { stage: state })
948 } else {
949 None
950 };
951 let mesh_module = hub.shader_modules.get(mesh.stage.module);
952 let mesh_stage = ProgrammableStageDescriptor {
953 module: mesh_module,
954 entry_point: mesh.stage.entry_point.clone(),
955 constants: mesh.stage.constants.clone(),
956 zero_initialize_workgroup_memory: mesh.stage.zero_initialize_workgroup_memory,
957 };
958 RenderPipelineVertexProcessor::Mesh(task_module, MeshState { stage: mesh_stage })
959 }
960 };
961
962 let fragment = if let Some(ref state) = desc.fragment {
963 let module = hub.shader_modules.get(state.stage.module);
964
965 let stage = ProgrammableStageDescriptor {
966 module,
967 entry_point: state.stage.entry_point.clone(),
968 constants: state.stage.constants.clone(),
969 zero_initialize_workgroup_memory: state.stage.zero_initialize_workgroup_memory,
970 };
971 Some(pipeline::FragmentState {
972 stage,
973 targets: state.targets.clone(),
974 })
975 } else {
976 None
977 };
978
979 let desc = ResolvedGeneralRenderPipelineDescriptor {
980 label: desc.label.clone(),
981 layout,
982 vertex,
983 primitive: desc.primitive,
984 depth_stencil: desc.depth_stencil.clone(),
985 multisample: desc.multisample,
986 fragment,
987 multiview_mask: desc.multiview_mask,
988 cache,
989 };
990
991 let (pipeline, error) = device.create_render_pipeline(desc);
992
993 let id = fid.assign(pipeline);
994
995 (id, error)
996 }
997
998 pub fn render_pipeline_get_bind_group_layout(
1001 &self,
1002 pipeline_id: id::RenderPipelineId,
1003 index: u32,
1004 id_in: Option<id::BindGroupLayoutId>,
1005 ) -> (
1006 id::BindGroupLayoutId,
1007 Option<binding_model::GetBindGroupLayoutError>,
1008 ) {
1009 let hub = &self.hub;
1010
1011 let fid = hub.bind_group_layouts.prepare(id_in);
1012
1013 let pipeline = hub.render_pipelines.get(pipeline_id);
1014
1015 let (bgl, error) = pipeline.get_bind_group_layout(index);
1016
1017 let id = fid.assign(bgl);
1018
1019 (id, error)
1020 }
1021
1022 pub fn render_pipeline_drop(&self, render_pipeline_id: id::RenderPipelineId) {
1023 let hub = &self.hub;
1024
1025 let _pipeline = hub.render_pipelines.remove(render_pipeline_id);
1026 }
1027
1028 pub fn device_create_compute_pipeline(
1029 &self,
1030 device_id: DeviceId,
1031 desc: &ComputePipelineDescriptor,
1032 id_in: Option<id::ComputePipelineId>,
1033 ) -> (
1034 id::ComputePipelineId,
1035 Option<pipeline::CreateComputePipelineError>,
1036 ) {
1037 let hub = &self.hub;
1038
1039 let fid = hub.compute_pipelines.prepare(id_in);
1040
1041 let device = self.hub.devices.get(device_id);
1042
1043 let layout = desc.layout.map(|layout| hub.pipeline_layouts.get(layout));
1044
1045 let cache = desc.cache.map(|cache| hub.pipeline_caches.get(cache));
1046
1047 let module = hub.shader_modules.get(desc.stage.module);
1048
1049 let stage = ProgrammableStageDescriptor {
1050 module,
1051 entry_point: desc.stage.entry_point.clone(),
1052 constants: desc.stage.constants.clone(),
1053 zero_initialize_workgroup_memory: desc.stage.zero_initialize_workgroup_memory,
1054 };
1055
1056 let desc = pipeline::ComputePipelineDescriptor {
1057 label: desc.label.clone(),
1058 layout,
1059 stage,
1060 cache,
1061 };
1062
1063 let (pipeline, error) = device.create_compute_pipeline(desc);
1064
1065 let id = fid.assign(pipeline);
1066
1067 (id, error)
1068 }
1069
1070 pub fn compute_pipeline_get_bind_group_layout(
1073 &self,
1074 pipeline_id: id::ComputePipelineId,
1075 index: u32,
1076 id_in: Option<id::BindGroupLayoutId>,
1077 ) -> (
1078 id::BindGroupLayoutId,
1079 Option<binding_model::GetBindGroupLayoutError>,
1080 ) {
1081 let hub = &self.hub;
1082
1083 let fid = hub.bind_group_layouts.prepare(id_in);
1084
1085 let pipeline = hub.compute_pipelines.get(pipeline_id);
1086
1087 let (bgl, error) = pipeline.get_bind_group_layout(index);
1088
1089 let id = fid.assign(bgl);
1090
1091 (id, error)
1092 }
1093
1094 pub fn compute_pipeline_drop(&self, compute_pipeline_id: id::ComputePipelineId) {
1095 let hub = &self.hub;
1096
1097 let _pipeline = hub.compute_pipelines.remove(compute_pipeline_id);
1098 }
1099
1100 pub unsafe fn device_create_pipeline_cache(
1104 &self,
1105 device_id: DeviceId,
1106 desc: &pipeline::PipelineCacheDescriptor<'_>,
1107 id_in: Option<id::PipelineCacheId>,
1108 ) -> (
1109 id::PipelineCacheId,
1110 Option<pipeline::CreatePipelineCacheError>,
1111 ) {
1112 let hub = &self.hub;
1113
1114 let fid = hub.pipeline_caches.prepare(id_in);
1115 let device = self.hub.devices.get(device_id);
1116
1117 let (cache, error) = unsafe { device.create_pipeline_cache(desc) };
1118
1119 let id = fid.assign(cache);
1120
1121 (id, error)
1122 }
1123
1124 pub fn pipeline_cache_drop(&self, pipeline_cache_id: id::PipelineCacheId) {
1125 let hub = &self.hub;
1126
1127 let _cache = hub.pipeline_caches.remove(pipeline_cache_id);
1128 }
1129
1130 pub fn surface_configure(
1131 &self,
1132 surface_id: SurfaceId,
1133 device_id: DeviceId,
1134 config: &wgt::SurfaceConfiguration<Vec<TextureFormat>>,
1135 ) -> Option<present::ConfigureSurfaceError> {
1136 let device = self.hub.devices.get(device_id);
1137 let surface = self.surfaces.get(surface_id);
1138
1139 surface.configure(&device, config)
1140 }
1141
1142 pub fn device_poll(
1146 &self,
1147 device_id: DeviceId,
1148 poll_type: wgt::PollType<crate::SubmissionIndex>,
1149 ) -> Result<wgt::PollStatus, WaitIdleError> {
1150 let device = self.hub.devices.get(device_id);
1151
1152 device.poll(poll_type)
1153 }
1154
1155 pub fn poll_all_devices(&self, force_wait: bool) -> Result<bool, WaitIdleError> {
1162 self.instance.poll_all_devices(force_wait)
1163 }
1164
1165 pub unsafe fn device_start_graphics_debugger_capture(&self, device_id: DeviceId) {
1171 unsafe {
1172 self.hub
1173 .devices
1174 .get(device_id)
1175 .start_graphics_debugger_capture();
1176 }
1177 }
1178
1179 pub unsafe fn device_stop_graphics_debugger_capture(&self, device_id: DeviceId) {
1185 unsafe {
1186 self.hub
1187 .devices
1188 .get(device_id)
1189 .stop_graphics_debugger_capture();
1190 }
1191 }
1192
1193 pub fn pipeline_cache_get_data(&self, id: id::PipelineCacheId) -> Option<Vec<u8>> {
1194 let hub = &self.hub;
1195
1196 hub.pipeline_caches.get(id).get_data()
1197 }
1198
1199 pub fn device_drop(&self, device_id: DeviceId) {
1200 self.hub.devices.remove(device_id);
1201 }
1202
1203 pub fn device_set_device_lost_closure(
1205 &self,
1206 device_id: DeviceId,
1207 device_lost_closure: DeviceLostClosure,
1208 ) {
1209 let device = self.hub.devices.get(device_id);
1210
1211 device.set_device_lost_closure(device_lost_closure);
1212 }
1213
1214 pub fn device_destroy(&self, device_id: DeviceId) {
1215 let device = self.hub.devices.get(device_id);
1216 device.destroy();
1217 }
1218
1219 pub fn device_get_internal_counters(&self, device_id: DeviceId) -> wgt::InternalCounters {
1220 let device = self.hub.devices.get(device_id);
1221 device.get_internal_counters()
1222 }
1223
1224 pub fn device_generate_allocator_report(
1225 &self,
1226 device_id: DeviceId,
1227 ) -> Option<wgt::AllocatorReport> {
1228 let device = self.hub.devices.get(device_id);
1229 device.generate_allocator_report()
1230 }
1231
1232 #[cfg(feature = "trace")]
1233 pub fn device_take_trace(
1234 &self,
1235 device_id: DeviceId,
1236 ) -> Option<Box<dyn trace::Trace + Send + Sync + 'static>> {
1237 let device = self.hub.devices.get(device_id);
1238 device.take_trace()
1239 }
1240
1241 pub fn queue_drop(&self, queue_id: QueueId) {
1242 self.hub.queues.remove(queue_id);
1243 }
1244
1245 pub fn buffer_map_async(
1247 &self,
1248 buffer_id: id::BufferId,
1249 offset: BufferAddress,
1250 size: Option<BufferAddress>,
1251 op: BufferMapOperation,
1252 ) -> Result<crate::SubmissionIndex, BufferAccessError> {
1253 let hub = &self.hub;
1254
1255 let buffer = hub.buffers.get(buffer_id);
1256
1257 buffer.map_async(offset, size, op)
1258 }
1259
1260 pub fn buffer_get_mapped_range(
1261 &self,
1262 buffer_id: id::BufferId,
1263 offset: BufferAddress,
1264 size: Option<BufferAddress>,
1265 ) -> Result<(NonNull<u8>, u64), BufferAccessError> {
1266 let hub = &self.hub;
1267
1268 let buffer = hub.buffers.get(buffer_id);
1269
1270 buffer.get_mapped_range(offset, size)
1271 }
1272
1273 pub fn buffer_unmap(&self, buffer_id: id::BufferId) -> BufferAccessResult {
1274 let hub = &self.hub;
1275
1276 let buffer = hub.buffers.get(buffer_id);
1277
1278 buffer.unmap()
1279 }
1280}