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