From d3d174e4aaf9d799247df006ebc7f4a57d54ee8d Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 13 Sep 2022 00:00:19 -0500 Subject: [PATCH] WIP: Context dynamic dispatch --- wgpu-core/src/id.rs | 12 + wgpu/src/backend/direct.rs | 2110 ++++++++++------- wgpu/src/backend/mod.rs | 4 +- wgpu/src/backend/web.rs | 4520 ++++++++++++++++++++---------------- wgpu/src/context.rs | 2861 +++++++++++++++++++++++ wgpu/src/lib.rs | 2005 ++++++++++++---- wgpu/src/util/mod.rs | 3 +- wgpu/tests/poll.rs | 3 +- 8 files changed, 8271 insertions(+), 3247 deletions(-) create mode 100644 wgpu/src/context.rs diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 3f5ec0e3a03..0a95dceccf6 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -93,6 +93,13 @@ impl From for Id { } impl Id { + /// # Safety + /// + /// The raw id must be valid for the type. + pub unsafe fn from_raw(raw: NonZeroId) -> Self { + Self(raw, PhantomData) + } + #[allow(dead_code)] pub(crate) fn dummy(index: u32) -> Valid { Valid(Id::zip(index, 1, Backend::Empty)) @@ -165,12 +172,17 @@ pub(crate) struct Valid(pub I); /// need to construct `Id` values directly, or access their components, like the /// WGPU recording player, may use this trait to do so. pub trait TypedId: Copy { + fn as_raw(&self) -> NonZeroId; fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self; fn unzip(self) -> (Index, Epoch, Backend); } #[allow(trivial_numeric_casts)] impl TypedId for Id { + fn as_raw(&self) -> NonZeroId { + self.0 + } + fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self { assert_eq!(0, epoch >> EPOCH_BITS); assert_eq!(0, (index as IdType) >> INDEX_BITS); diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 6daab45c5de..78e1d445cd8 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1,17 +1,18 @@ use crate::{ - AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, - CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, + context::Id, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, + BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, - SurfaceStatus, TextureDescriptor, TextureFormat, TextureViewDescriptor, + SurfaceStatus, TextureDescriptor, TextureFormat, TextureViewDescriptor, UncapturedErrorHandler, }; use arrayvec::ArrayVec; use parking_lot::Mutex; use smallvec::SmallVec; use std::{ - borrow::Cow::Borrowed, + any::Any, + borrow::Cow::{Borrowed, Owned}, error::Error, fmt, future::{ready, Ready}, @@ -19,6 +20,8 @@ use std::{ slice, sync::Arc, }; +use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*}; +use wgc::id::TypedId; use wgt::{CompositeAlphaMode, PresentMode}; const LABEL: &str = "label"; @@ -185,22 +188,19 @@ impl Context { #[cfg(any(target_os = "ios", target_os = "macos"))] pub unsafe fn create_surface_from_core_animation_layer( - self: &Arc, + &self, layer: *mut std::ffi::c_void, - ) -> crate::Surface { + ) -> Surface { let id = self.0.instance_create_surface_metal(layer, ()); - crate::Surface { - context: Arc::clone(self), - id: Surface { - id, - configured_device: Mutex::default(), - }, + Surface { + id, + configured_device: Mutex::default(), } } #[cfg(all(target_arch = "wasm32", feature = "webgl", not(feature = "emscripten")))] pub fn instance_create_surface_from_canvas( - self: &Arc, + &self, canvas: &web_sys::HtmlCanvasElement, ) -> Surface { let id = self.0.create_surface_webgl_canvas(canvas, ()); @@ -212,7 +212,7 @@ impl Context { #[cfg(all(target_arch = "wasm32", feature = "webgl", not(feature = "emscripten")))] pub fn instance_create_surface_from_offscreen_canvas( - self: &Arc, + &self, canvas: &web_sys::OffscreenCanvas, ) -> Surface { let id = self.0.create_surface_webgl_offscreen_canvas(canvas, ()); @@ -223,17 +223,11 @@ impl Context { } #[cfg(target_os = "windows")] - pub unsafe fn create_surface_from_visual( - self: &Arc, - visual: *mut std::ffi::c_void, - ) -> crate::Surface { + pub unsafe fn create_surface_from_visual(&self, visual: *mut std::ffi::c_void) -> Surface { let id = self.0.instance_create_surface_from_visual(visual, ()); - crate::Surface { - context: Arc::clone(self), - id: Surface { - id, - configured_device: Mutex::default(), - }, + Surface { + id, + configured_device: Mutex::default(), } } @@ -308,434 +302,16 @@ impl Context { } } -mod pass_impl { - use super::Context; - use smallvec::SmallVec; - use std::convert::TryInto; - use std::ops::Range; - use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*}; - - impl crate::ComputePassInner for wgc::command::ComputePass { - fn set_pipeline(&mut self, pipeline: &wgc::id::ComputePipelineId) { - wgpu_compute_pass_set_pipeline(self, *pipeline) - } - fn set_bind_group( - &mut self, - index: u32, - bind_group: &wgc::id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) { - unsafe { - wgpu_compute_pass_set_bind_group( - self, - index, - *bind_group, - offsets.as_ptr(), - offsets.len(), - ) - } - } - fn set_push_constants(&mut self, offset: u32, data: &[u8]) { - unsafe { - wgpu_compute_pass_set_push_constant( - self, - offset, - data.len().try_into().unwrap(), - data.as_ptr(), - ) - } - } - fn insert_debug_marker(&mut self, label: &str) { - unsafe { - let label = std::ffi::CString::new(label).unwrap(); - wgpu_compute_pass_insert_debug_marker(self, label.as_ptr(), 0); - } - } - - fn push_debug_group(&mut self, group_label: &str) { - unsafe { - let label = std::ffi::CString::new(group_label).unwrap(); - wgpu_compute_pass_push_debug_group(self, label.as_ptr(), 0); - } - } - fn pop_debug_group(&mut self) { - wgpu_compute_pass_pop_debug_group(self); - } - - fn write_timestamp(&mut self, query_set: &wgc::id::QuerySetId, query_index: u32) { - wgpu_compute_pass_write_timestamp(self, *query_set, query_index) - } - - fn begin_pipeline_statistics_query( - &mut self, - query_set: &wgc::id::QuerySetId, - query_index: u32, - ) { - wgpu_compute_pass_begin_pipeline_statistics_query(self, *query_set, query_index) - } - - fn end_pipeline_statistics_query(&mut self) { - wgpu_compute_pass_end_pipeline_statistics_query(self) - } - - fn dispatch_workgroups(&mut self, x: u32, y: u32, z: u32) { - wgpu_compute_pass_dispatch_workgroups(self, x, y, z) - } - fn dispatch_workgroups_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - ) { - wgpu_compute_pass_dispatch_workgroups_indirect( - self, - indirect_buffer.id, - indirect_offset, - ) - } - } - - impl crate::RenderInner for wgc::command::RenderPass { - fn set_pipeline(&mut self, pipeline: &wgc::id::RenderPipelineId) { - wgpu_render_pass_set_pipeline(self, *pipeline) - } - fn set_bind_group( - &mut self, - index: u32, - bind_group: &wgc::id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) { - unsafe { - wgpu_render_pass_set_bind_group( - self, - index, - *bind_group, - offsets.as_ptr(), - offsets.len(), - ) - } - } - fn set_index_buffer( - &mut self, - buffer: &super::Buffer, - index_format: wgt::IndexFormat, - offset: wgt::BufferAddress, - size: Option, - ) { - self.set_index_buffer(buffer.id, index_format, offset, size) - } - fn set_vertex_buffer( - &mut self, - slot: u32, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - size: Option, - ) { - wgpu_render_pass_set_vertex_buffer(self, slot, buffer.id, offset, size) - } - fn set_push_constants(&mut self, stages: wgt::ShaderStages, offset: u32, data: &[u8]) { - unsafe { - wgpu_render_pass_set_push_constants( - self, - stages, - offset, - data.len().try_into().unwrap(), - data.as_ptr(), - ) - } - } - fn draw(&mut self, vertices: Range, instances: Range) { - wgpu_render_pass_draw( - self, - vertices.end - vertices.start, - instances.end - instances.start, - vertices.start, - instances.start, - ) - } - fn draw_indexed(&mut self, indices: Range, base_vertex: i32, instances: Range) { - wgpu_render_pass_draw_indexed( - self, - indices.end - indices.start, - instances.end - instances.start, - indices.start, - base_vertex, - instances.start, - ) - } - fn draw_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - ) { - wgpu_render_pass_draw_indirect(self, indirect_buffer.id, indirect_offset) - } - fn draw_indexed_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - ) { - wgpu_render_pass_draw_indexed_indirect(self, indirect_buffer.id, indirect_offset) - } - fn multi_draw_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - count: u32, - ) { - wgpu_render_pass_multi_draw_indirect(self, indirect_buffer.id, indirect_offset, count) - } - fn multi_draw_indexed_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - count: u32, - ) { - wgpu_render_pass_multi_draw_indexed_indirect( - self, - indirect_buffer.id, - indirect_offset, - count, - ) - } - fn multi_draw_indirect_count( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - count_buffer: &super::Buffer, - count_buffer_offset: wgt::BufferAddress, - max_count: u32, - ) { - wgpu_render_pass_multi_draw_indirect_count( - self, - indirect_buffer.id, - indirect_offset, - count_buffer.id, - count_buffer_offset, - max_count, - ) - } - fn multi_draw_indexed_indirect_count( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - count_buffer: &super::Buffer, - count_buffer_offset: wgt::BufferAddress, - max_count: u32, - ) { - wgpu_render_pass_multi_draw_indexed_indirect_count( - self, - indirect_buffer.id, - indirect_offset, - count_buffer.id, - count_buffer_offset, - max_count, - ) - } - } - - impl crate::RenderPassInner for wgc::command::RenderPass { - fn set_blend_constant(&mut self, color: wgt::Color) { - wgpu_render_pass_set_blend_constant(self, &color) - } - fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) { - wgpu_render_pass_set_scissor_rect(self, x, y, width, height) - } - fn set_viewport( - &mut self, - x: f32, - y: f32, - width: f32, - height: f32, - min_depth: f32, - max_depth: f32, - ) { - wgpu_render_pass_set_viewport(self, x, y, width, height, min_depth, max_depth) - } - fn set_stencil_reference(&mut self, reference: u32) { - wgpu_render_pass_set_stencil_reference(self, reference) - } - - fn insert_debug_marker(&mut self, label: &str) { - unsafe { - let label = std::ffi::CString::new(label).unwrap(); - wgpu_render_pass_insert_debug_marker(self, label.as_ptr(), 0); - } - } - - fn push_debug_group(&mut self, group_label: &str) { - unsafe { - let label = std::ffi::CString::new(group_label).unwrap(); - wgpu_render_pass_push_debug_group(self, label.as_ptr(), 0); - } - } - - fn pop_debug_group(&mut self) { - wgpu_render_pass_pop_debug_group(self); - } - - fn write_timestamp(&mut self, query_set: &wgc::id::QuerySetId, query_index: u32) { - wgpu_render_pass_write_timestamp(self, *query_set, query_index) - } - - fn begin_pipeline_statistics_query( - &mut self, - query_set: &wgc::id::QuerySetId, - query_index: u32, - ) { - wgpu_render_pass_begin_pipeline_statistics_query(self, *query_set, query_index) - } - - fn end_pipeline_statistics_query(&mut self) { - wgpu_render_pass_end_pipeline_statistics_query(self) - } - - fn execute_bundles<'a, I: Iterator>( - &mut self, - render_bundles: I, - ) { - let temp_render_bundles = render_bundles.cloned().collect::>(); - unsafe { - wgpu_render_pass_execute_bundles( - self, - temp_render_bundles.as_ptr(), - temp_render_bundles.len(), - ) - } - } - } - - impl crate::RenderInner for wgc::command::RenderBundleEncoder { - fn set_pipeline(&mut self, pipeline: &wgc::id::RenderPipelineId) { - wgpu_render_bundle_set_pipeline(self, *pipeline) - } - fn set_bind_group( - &mut self, - index: u32, - bind_group: &wgc::id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) { - unsafe { - wgpu_render_bundle_set_bind_group( - self, - index, - *bind_group, - offsets.as_ptr(), - offsets.len(), - ) - } - } - fn set_index_buffer( - &mut self, - buffer: &super::Buffer, - index_format: wgt::IndexFormat, - offset: wgt::BufferAddress, - size: Option, - ) { - self.set_index_buffer(buffer.id, index_format, offset, size) - } - fn set_vertex_buffer( - &mut self, - slot: u32, - buffer: &super::Buffer, - offset: wgt::BufferAddress, - size: Option, - ) { - wgpu_render_bundle_set_vertex_buffer(self, slot, buffer.id, offset, size) - } - - fn set_push_constants(&mut self, stages: wgt::ShaderStages, offset: u32, data: &[u8]) { - unsafe { - wgpu_render_bundle_set_push_constants( - self, - stages, - offset, - data.len().try_into().unwrap(), - data.as_ptr(), - ) - } - } - fn draw(&mut self, vertices: Range, instances: Range) { - wgpu_render_bundle_draw( - self, - vertices.end - vertices.start, - instances.end - instances.start, - vertices.start, - instances.start, - ) - } - fn draw_indexed(&mut self, indices: Range, base_vertex: i32, instances: Range) { - wgpu_render_bundle_draw_indexed( - self, - indices.end - indices.start, - instances.end - instances.start, - indices.start, - base_vertex, - instances.start, - ) - } - fn draw_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - ) { - wgpu_render_bundle_draw_indirect(self, indirect_buffer.id, indirect_offset) - } - fn draw_indexed_indirect( - &mut self, - indirect_buffer: &super::Buffer, - indirect_offset: wgt::BufferAddress, - ) { - wgpu_render_bundle_draw_indexed_indirect(self, indirect_buffer.id, indirect_offset) - } - fn multi_draw_indirect( - &mut self, - _indirect_buffer: &super::Buffer, - _indirect_offset: wgt::BufferAddress, - _count: u32, - ) { - unimplemented!() - } - fn multi_draw_indexed_indirect( - &mut self, - _indirect_buffer: &super::Buffer, - _indirect_offset: wgt::BufferAddress, - _count: u32, - ) { - unimplemented!() - } - fn multi_draw_indirect_count( - &mut self, - _indirect_buffer: &super::Buffer, - _indirect_offset: wgt::BufferAddress, - _count_buffer: &super::Buffer, - _count_buffer_offset: wgt::BufferAddress, - _max_count: u32, - ) { - unimplemented!() - } - fn multi_draw_indexed_indirect_count( - &mut self, - _indirect_buffer: &super::Buffer, - _indirect_offset: wgt::BufferAddress, - _count_buffer: &super::Buffer, - _count_buffer_offset: wgt::BufferAddress, - _max_count: u32, - ) { - unimplemented!() - } - } -} - fn map_buffer_copy_view(view: crate::ImageCopyBuffer) -> wgc::command::ImageCopyBuffer { wgc::command::ImageCopyBuffer { - buffer: view.buffer.id.id, + buffer: view.buffer.id.into(), layout: view.layout, } } fn map_texture_copy_view(view: crate::ImageCopyTexture) -> wgc::command::ImageCopyTexture { wgc::command::ImageCopyTexture { - texture: view.texture.id.id, + texture: view.texture.id.into(), mip_level: view.mip_level, origin: view.origin, aspect: view.aspect, @@ -796,9 +372,14 @@ pub struct Device { features: Features, } +impl Device { + pub fn id(&self) -> wgc::id::DeviceId { + self.id + } +} + #[derive(Debug)] pub(crate) struct Buffer { - id: wgc::id::BufferId, error_sink: ErrorSink, } @@ -808,43 +389,81 @@ pub struct Texture { error_sink: ErrorSink, } +impl Texture { + pub fn id(&self) -> wgc::id::TextureId { + self.id + } +} + #[derive(Debug)] pub(crate) struct CommandEncoder { - id: wgc::id::CommandEncoderId, error_sink: ErrorSink, open: bool, } impl crate::Context for Context { type AdapterId = wgc::id::AdapterId; - type DeviceId = Device; + type AdapterData = (); + type DeviceId = wgc::id::DeviceId; + type DeviceData = Device; type QueueId = wgc::id::QueueId; + type QueueData = (); type ShaderModuleId = wgc::id::ShaderModuleId; + type ShaderModuleData = (); type BindGroupLayoutId = wgc::id::BindGroupLayoutId; + type BindGroupLayoutData = (); type BindGroupId = wgc::id::BindGroupId; + type BindGroupData = (); type TextureViewId = wgc::id::TextureViewId; + type TextureViewData = (); type SamplerId = wgc::id::SamplerId; + type SamplerData = (); + type BufferId = wgc::id::BufferId; + type BufferData = Buffer; + type TextureId = wgc::id::TextureId; + type TextureData = Texture; type QuerySetId = wgc::id::QuerySetId; - type BufferId = Buffer; - type TextureId = Texture; + type QuerySetData = (); type PipelineLayoutId = wgc::id::PipelineLayoutId; + type PipelineLayoutData = (); type RenderPipelineId = wgc::id::RenderPipelineId; + type RenderPipelineData = (); type ComputePipelineId = wgc::id::ComputePipelineId; - type CommandEncoderId = CommandEncoder; - type ComputePassId = wgc::command::ComputePass; - type RenderPassId = wgc::command::RenderPass; + type ComputePipelineData = (); + type CommandEncoderId = wgc::id::CommandEncoderId; + type CommandEncoderData = CommandEncoder; + type ComputePassId = Id; + type ComputePassData = wgc::command::ComputePass; + type RenderPassId = Id; + type RenderPassData = wgc::command::RenderPass; type CommandBufferId = wgc::id::CommandBufferId; - type RenderBundleEncoderId = wgc::command::RenderBundleEncoder; + type CommandBufferData = (); + type RenderBundleEncoderId = Id; + type RenderBundleEncoderData = wgc::command::RenderBundleEncoder; type RenderBundleId = wgc::id::RenderBundleId; - type SurfaceId = Surface; + type RenderBundleData = (); + type SurfaceId = wgc::id::SurfaceId; + type SurfaceData = Surface; type SurfaceOutputDetail = SurfaceOutputDetail; - type SubmissionIndex = wgc::device::queue::WrappedSubmissionIndex; + type SubmissionIndex = Id; + type SubmissionIndexData = wgc::device::queue::WrappedSubmissionIndex; + + type RequestAdapterFuture = Ready>; - type RequestAdapterFuture = Ready>; #[allow(clippy::type_complexity)] - type RequestDeviceFuture = - Ready>; + type RequestDeviceFuture = Ready< + Result< + ( + Self::DeviceId, + Self::DeviceData, + Self::QueueId, + Self::QueueData, + ), + crate::RequestDeviceError, + >, + >; + type PopErrorScopeFuture = Ready>; fn init(backends: wgt::Backends) -> Self { @@ -859,13 +478,18 @@ impl crate::Context for Context { &self, display_handle: raw_window_handle::RawDisplayHandle, window_handle: raw_window_handle::RawWindowHandle, - ) -> Self::SurfaceId { - Surface { - id: self - .0 - .instance_create_surface(display_handle, window_handle, ()), - configured_device: Mutex::new(None), - } + ) -> (Self::SurfaceId, Self::SurfaceData) { + let id = self + .0 + .instance_create_surface(display_handle, window_handle, ()); + + ( + id, + Surface { + id, + configured_device: Mutex::new(None), + }, + ) } fn instance_request_adapter( @@ -876,24 +500,17 @@ impl crate::Context for Context { &wgc::instance::RequestAdapterOptions { power_preference: options.power_preference, force_fallback_adapter: options.force_fallback_adapter, - compatible_surface: options.compatible_surface.map(|surface| surface.id.id), + compatible_surface: options.compatible_surface.map(|surface| surface.id.into()), }, wgc::instance::AdapterInputs::Mask(wgt::Backends::all(), |_| ()), ); - ready(id.ok()) - } - - fn instance_poll_all_devices(&self, force_wait: bool) -> bool { - let global = &self.0; - match global.poll_all_devices(force_wait) { - Ok(all_queue_empty) => all_queue_empty, - Err(err) => self.handle_error_fatal(err, "Device::poll"), - } + ready(id.ok().map(|id| (id, ()))) } fn adapter_request_device( &self, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, desc: &crate::DeviceDescriptor, trace_dir: Option<&std::path::Path>, ) -> Self::RequestDeviceFuture { @@ -913,23 +530,36 @@ impl crate::Context for Context { error_sink: Arc::new(Mutex::new(ErrorSinkRaw::new())), features: desc.features, }; - ready(Ok((device, device_id))) + ready(Ok((device_id, device, device_id, ()))) + } + + fn instance_poll_all_devices(&self, force_wait: bool) -> bool { + let global = &self.0; + match global.poll_all_devices(force_wait) { + Ok(all_queue_empty) => all_queue_empty, + Err(err) => self.handle_error_fatal(err, "Device::poll"), + } } fn adapter_is_surface_supported( &self, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, surface: &Self::SurfaceId, + _surface_data: &Self::SurfaceData, ) -> bool { let global = &self.0; - match wgc::gfx_select!(adapter => global.adapter_is_surface_supported(*adapter, surface.id)) - { + match wgc::gfx_select!(adapter => global.adapter_is_surface_supported(*adapter, *surface)) { Ok(result) => result, Err(err) => self.handle_error_fatal(err, "Adapter::is_surface_supported"), } } - fn adapter_features(&self, adapter: &Self::AdapterId) -> Features { + fn adapter_features( + &self, + adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, + ) -> Features { let global = &self.0; match wgc::gfx_select!(*adapter => global.adapter_features(*adapter)) { Ok(features) => features, @@ -937,7 +567,11 @@ impl crate::Context for Context { } } - fn adapter_limits(&self, adapter: &Self::AdapterId) -> Limits { + fn adapter_limits( + &self, + adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, + ) -> Limits { let global = &self.0; match wgc::gfx_select!(*adapter => global.adapter_limits(*adapter)) { Ok(limits) => limits, @@ -945,7 +579,11 @@ impl crate::Context for Context { } } - fn adapter_downlevel_capabilities(&self, adapter: &Self::AdapterId) -> DownlevelCapabilities { + fn adapter_downlevel_capabilities( + &self, + adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, + ) -> DownlevelCapabilities { let global = &self.0; match wgc::gfx_select!(*adapter => global.adapter_downlevel_capabilities(*adapter)) { Ok(downlevel) => downlevel, @@ -953,7 +591,11 @@ impl crate::Context for Context { } } - fn adapter_get_info(&self, adapter: &wgc::id::AdapterId) -> AdapterInfo { + fn adapter_get_info( + &self, + adapter: &wgc::id::AdapterId, + _adapter_data: &Self::AdapterData, + ) -> AdapterInfo { let global = &self.0; match wgc::gfx_select!(*adapter => global.adapter_get_info(*adapter)) { Ok(info) => info, @@ -964,6 +606,7 @@ impl crate::Context for Context { fn adapter_get_texture_format_features( &self, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, format: wgt::TextureFormat, ) -> wgt::TextureFormatFeatures { let global = &self.0; @@ -977,10 +620,12 @@ impl crate::Context for Context { fn surface_get_supported_formats( &self, surface: &Self::SurfaceId, + _surface_data: &Self::SurfaceData, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, ) -> Vec { let global = &self.0; - match wgc::gfx_select!(adapter => global.surface_get_supported_formats(surface.id, *adapter)) + match wgc::gfx_select!(adapter => global.surface_get_supported_formats(*surface, *adapter)) { Ok(formats) => formats, Err(wgc::instance::GetSurfaceSupportError::Unsupported) => vec![], @@ -991,10 +636,12 @@ impl crate::Context for Context { fn surface_get_supported_present_modes( &self, surface: &Self::SurfaceId, + _surface_data: &Self::SurfaceData, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, ) -> Vec { let global = &self.0; - match wgc::gfx_select!(adapter => global.surface_get_supported_present_modes(surface.id, *adapter)) + match wgc::gfx_select!(adapter => global.surface_get_supported_present_modes(*surface, *adapter)) { Ok(modes) => modes, Err(wgc::instance::GetSurfaceSupportError::Unsupported) => vec![], @@ -1005,10 +652,12 @@ impl crate::Context for Context { fn surface_get_supported_alpha_modes( &self, surface: &Self::SurfaceId, + _surface_data: &Self::SurfaceData, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, ) -> Vec { let global = &self.0; - match wgc::gfx_select!(adapter => global.surface_get_supported_alpha_modes(surface.id, *adapter)) + match wgc::gfx_select!(adapter => global.surface_get_supported_alpha_modes(*surface, *adapter)) { Ok(modes) => modes, Err(wgc::instance::GetSurfaceSupportError::Unsupported) => { @@ -1021,52 +670,65 @@ impl crate::Context for Context { fn surface_configure( &self, surface: &Self::SurfaceId, + surface_data: &Self::SurfaceData, device: &Self::DeviceId, + _device_data: &Self::DeviceData, config: &wgt::SurfaceConfiguration, ) { let global = &self.0; - let error = - wgc::gfx_select!(device.id => global.surface_configure(surface.id, device.id, config)); + let error = wgc::gfx_select!(device => global.surface_configure(*surface, *device, config)); if let Some(e) = error { self.handle_error_fatal(e, "Surface::configure"); } else { - *surface.configured_device.lock() = Some(device.id); + *surface_data.configured_device.lock() = Some(*device); } } fn surface_get_current_texture( &self, surface: &Self::SurfaceId, + surface_data: &Self::SurfaceData, ) -> ( Option, + Option, SurfaceStatus, Self::SurfaceOutputDetail, ) { let global = &self.0; - let device_id = surface + let device_id = surface_data .configured_device .lock() .expect("Surface was not configured?"); match wgc::gfx_select!( - device_id => global.surface_get_current_texture(surface.id, ()) + device_id => global.surface_get_current_texture(*surface, ()) ) { - Ok(wgc::present::SurfaceOutput { status, texture_id }) => ( - texture_id.map(|id| Texture { + Ok(wgc::present::SurfaceOutput { status, texture_id }) => { + let (id, data) = { + ( + texture_id, + texture_id.map(|id| Texture { + id, + error_sink: Arc::new(Mutex::new(ErrorSinkRaw::new())), + }), + ) + }; + + ( id, - error_sink: Arc::new(Mutex::new(ErrorSinkRaw::new())), - }), - status, - SurfaceOutputDetail { - surface_id: surface.id, - }, - ), + data, + status, + SurfaceOutputDetail { + surface_id: *surface, + }, + ) + } Err(err) => self.handle_error_fatal(err, "Surface::get_current_texture_view"), } } fn surface_present(&self, texture: &Self::TextureId, detail: &Self::SurfaceOutputDetail) { let global = &self.0; - match wgc::gfx_select!(texture.id => global.surface_present(detail.surface_id)) { + match wgc::gfx_select!(texture => global.surface_present(detail.surface_id)) { Ok(_status) => (), Err(err) => self.handle_error_fatal(err, "Surface::present"), } @@ -1078,31 +740,39 @@ impl crate::Context for Context { detail: &Self::SurfaceOutputDetail, ) { let global = &self.0; - match wgc::gfx_select!(texture.id => global.surface_texture_discard(detail.surface_id)) { + match wgc::gfx_select!(texture => global.surface_texture_discard(detail.surface_id)) { Ok(_status) => (), Err(err) => self.handle_error_fatal(err, "Surface::discard_texture"), } } - fn device_features(&self, device: &Self::DeviceId) -> Features { + fn device_features( + &self, + device: &Self::DeviceId, + _device_data: &Self::DeviceData, + ) -> Features { let global = &self.0; - match wgc::gfx_select!(device.id => global.device_features(device.id)) { + match wgc::gfx_select!(device => global.device_features(*device)) { Ok(features) => features, Err(err) => self.handle_error_fatal(err, "Device::features"), } } - fn device_limits(&self, device: &Self::DeviceId) -> Limits { + fn device_limits(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) -> Limits { let global = &self.0; - match wgc::gfx_select!(device.id => global.device_limits(device.id)) { + match wgc::gfx_select!(device => global.device_limits(*device)) { Ok(limits) => limits, Err(err) => self.handle_error_fatal(err, "Device::limits"), } } - fn device_downlevel_properties(&self, device: &Self::DeviceId) -> DownlevelCapabilities { + fn device_downlevel_properties( + &self, + device: &Self::DeviceId, + _device_data: &Self::DeviceData, + ) -> DownlevelCapabilities { let global = &self.0; - match wgc::gfx_select!(device.id => global.device_downlevel_properties(device.id)) { + match wgc::gfx_select!(device => global.device_downlevel_properties(*device)) { Ok(limits) => limits, Err(err) => self.handle_error_fatal(err, "Device::downlevel_properties"), } @@ -1120,9 +790,10 @@ impl crate::Context for Context { fn device_create_shader_module( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: ShaderModuleDescriptor, shader_bound_checks: wgt::ShaderBoundChecks, - ) -> Self::ShaderModuleId { + ) -> (Self::ShaderModuleId, Self::ShaderModuleData) { let global = &self.0; let descriptor = wgc::pipeline::ShaderModuleDescriptor { label: desc.label.map(Borrowed), @@ -1139,7 +810,7 @@ impl crate::Context for Context { }; let parser = naga::front::spv::Parser::new(spv.iter().cloned(), &options); let module = parser.parse().unwrap(); - wgc::pipeline::ShaderModuleSource::Naga(std::borrow::Cow::Owned(module)) + wgc::pipeline::ShaderModuleSource::Naga(Owned(module)) } #[cfg(feature = "glsl")] ShaderSource::Glsl { @@ -1155,7 +826,7 @@ impl crate::Context for Context { let mut parser = naga::front::glsl::Parser::default(); let module = parser.parse(&options, shader).unwrap(); - wgc::pipeline::ShaderModuleSource::Naga(std::borrow::Cow::Owned(module)) + wgc::pipeline::ShaderModuleSource::Naga(Owned(module)) } #[cfg(feature = "wgsl")] ShaderSource::Wgsl(ref code) => wgc::pipeline::ShaderModuleSource::Wgsl(Borrowed(code)), @@ -1164,25 +835,26 @@ impl crate::Context for Context { ShaderSource::Dummy(_) => panic!("found `ShaderSource::Dummy`"), }; let (id, error) = wgc::gfx_select!( - device.id => global.device_create_shader_module(device.id, &descriptor, source, ()) + device => global.device_create_shader_module(*device, &descriptor, source, ()) ); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_shader_module", ); } - id + (id, ()) } unsafe fn device_create_shader_module_spirv( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &ShaderModuleDescriptorSpirV, - ) -> Self::ShaderModuleId { + ) -> (Self::ShaderModuleId, Self::ShaderModuleData) { let global = &self.0; let descriptor = wgc::pipeline::ShaderModuleDescriptor { label: desc.label.map(Borrowed), @@ -1191,62 +863,67 @@ impl crate::Context for Context { shader_bound_checks: wgt::ShaderBoundChecks::unchecked(), }; let (id, error) = wgc::gfx_select!( - device.id => global.device_create_shader_module_spirv(device.id, &descriptor, Borrowed(&desc.source), ()) + device => global.device_create_shader_module_spirv(*device, &descriptor, Borrowed(&desc.source), ()) ); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_shader_module_spirv", ); } - id + (id, ()) } fn device_create_bind_group_layout( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &BindGroupLayoutDescriptor, - ) -> Self::BindGroupLayoutId { + ) -> (Self::BindGroupLayoutId, Self::BindGroupLayoutData) { let global = &self.0; let descriptor = wgc::binding_model::BindGroupLayoutDescriptor { label: desc.label.map(Borrowed), entries: Borrowed(desc.entries), }; let (id, error) = wgc::gfx_select!( - device.id => global.device_create_bind_group_layout(device.id, &descriptor, ()) + device => global.device_create_bind_group_layout(*device, &descriptor, ()) ); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_bind_group_layout", ); } - id + (id, ()) } fn device_create_bind_group( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &BindGroupDescriptor, - ) -> Self::BindGroupId { + ) -> (Self::BindGroupId, Self::BindGroupData) { use wgc::binding_model as bm; - let mut arrayed_texture_views = Vec::new(); - let mut arrayed_samplers = Vec::new(); - if device.features.contains(Features::TEXTURE_BINDING_ARRAY) { + let mut arrayed_texture_views = Vec::::new(); + let mut arrayed_samplers = Vec::::new(); + if device_data + .features + .contains(Features::TEXTURE_BINDING_ARRAY) + { // gather all the array view IDs first for entry in desc.entries.iter() { if let BindingResource::TextureViewArray(array) = entry.resource { - arrayed_texture_views.extend(array.iter().map(|view| view.id)); + arrayed_texture_views.extend(array.iter().map(|view| &view.id)); } if let BindingResource::SamplerArray(array) = entry.resource { - arrayed_samplers.extend(array.iter().map(|sampler| sampler.id)); + arrayed_samplers.extend(array.iter().map(|sampler| &sampler.id)); } } } @@ -1254,12 +931,15 @@ impl crate::Context for Context { let mut remaining_arrayed_samplers = &arrayed_samplers[..]; let mut arrayed_buffer_bindings = Vec::new(); - if device.features.contains(Features::BUFFER_BINDING_ARRAY) { + if device_data + .features + .contains(Features::BUFFER_BINDING_ARRAY) + { // gather all the buffers first for entry in desc.entries.iter() { if let BindingResource::BufferArray(array) = entry.resource { arrayed_buffer_bindings.extend(array.iter().map(|binding| bm::BufferBinding { - buffer_id: binding.buffer.id.id, + buffer_id: binding.buffer.id.into(), offset: binding.offset, size: binding.size, })); @@ -1279,7 +959,7 @@ impl crate::Context for Context { offset, size, }) => bm::BindingResource::Buffer(bm::BufferBinding { - buffer_id: buffer.id.id, + buffer_id: buffer.id.into(), offset, size, }), @@ -1289,53 +969,61 @@ impl crate::Context for Context { &remaining_arrayed_buffer_bindings[array.len()..]; bm::BindingResource::BufferArray(Borrowed(slice)) } - BindingResource::Sampler(sampler) => bm::BindingResource::Sampler(sampler.id), + BindingResource::Sampler(sampler) => { + bm::BindingResource::Sampler(sampler.id.into()) + } BindingResource::SamplerArray(array) => { - let slice = &remaining_arrayed_samplers[..array.len()]; + let samplers = remaining_arrayed_samplers[..array.len()] + .iter() + .map(|id| ::from(*id)) + .collect::>(); remaining_arrayed_samplers = &remaining_arrayed_samplers[array.len()..]; - bm::BindingResource::SamplerArray(Borrowed(slice)) + bm::BindingResource::SamplerArray(Owned(samplers)) } BindingResource::TextureView(texture_view) => { - bm::BindingResource::TextureView(texture_view.id) + bm::BindingResource::TextureView(texture_view.id.into()) } BindingResource::TextureViewArray(array) => { - let slice = &remaining_arrayed_texture_views[..array.len()]; + let views = remaining_arrayed_texture_views[..array.len()] + .iter() + .map(|id| ::from(*id)) + .collect::>(); remaining_arrayed_texture_views = &remaining_arrayed_texture_views[array.len()..]; - bm::BindingResource::TextureViewArray(Borrowed(slice)) + bm::BindingResource::TextureViewArray(Owned(views)) } }, }) .collect::>(); let descriptor = bm::BindGroupDescriptor { label: desc.label.as_ref().map(|label| Borrowed(&label[..])), - layout: desc.layout.id, + layout: desc.layout.id.into(), entries: Borrowed(&entries), }; let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_bind_group( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_bind_group( + *device, &descriptor, () )); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_bind_group", ); } - id + (id, ()) } - fn device_create_pipeline_layout( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &PipelineLayoutDescriptor, - ) -> Self::PipelineLayoutId { + ) -> (Self::PipelineLayoutId, Self::PipelineLayoutData) { // Limit is always less or equal to hal::MAX_BIND_GROUPS, so this is always right // Guards following ArrayVec assert!( @@ -1348,7 +1036,7 @@ impl crate::Context for Context { let temp_layouts = desc .bind_group_layouts .iter() - .map(|bgl| bgl.id) + .map(|bgl| bgl.id.into()) .collect::>(); let descriptor = wgc::binding_model::PipelineLayoutDescriptor { label: desc.label.map(Borrowed), @@ -1357,28 +1045,28 @@ impl crate::Context for Context { }; let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_pipeline_layout( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_pipeline_layout( + *device, &descriptor, () )); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_pipeline_layout", ); } - id + (id, ()) } - fn device_create_render_pipeline( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &RenderPipelineDescriptor, - ) -> Self::RenderPipelineId { + ) -> (Self::RenderPipelineId, Self::RenderPipelineData) { use wgc::pipeline as pipe; let vertex_buffers: ArrayVec<_, { wgc::MAX_VERTEX_BUFFERS }> = desc @@ -1401,10 +1089,10 @@ impl crate::Context for Context { }; let descriptor = pipe::RenderPipelineDescriptor { label: desc.label.map(Borrowed), - layout: desc.layout.map(|l| l.id), + layout: desc.layout.map(|l| l.id.into()), vertex: pipe::VertexState { stage: pipe::ProgrammableStageDescriptor { - module: desc.vertex.module.id, + module: desc.vertex.module.id.into(), entry_point: Borrowed(desc.vertex.entry_point), }, buffers: Borrowed(&vertex_buffers), @@ -1414,7 +1102,7 @@ impl crate::Context for Context { multisample: desc.multisample, fragment: desc.fragment.as_ref().map(|frag| pipe::FragmentState { stage: pipe::ProgrammableStageDescriptor { - module: frag.module.id, + module: frag.module.id.into(), entry_point: Borrowed(frag.entry_point), }, targets: Borrowed(frag.targets), @@ -1423,8 +1111,8 @@ impl crate::Context for Context { }; let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_render_pipeline( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_render_pipeline( + *device, &descriptor, (), implicit_pipeline_ids @@ -1435,21 +1123,21 @@ impl crate::Context for Context { log::error!("Please report it to https://github.com/gfx-rs/naga"); } self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_render_pipeline", ); } - id + (id, ()) } - fn device_create_compute_pipeline( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &ComputePipelineDescriptor, - ) -> Self::ComputePipelineId { + ) -> (Self::ComputePipelineId, Self::ComputePipelineData) { use wgc::pipeline as pipe; let implicit_pipeline_ids = match desc.layout { @@ -1461,16 +1149,16 @@ impl crate::Context for Context { }; let descriptor = pipe::ComputePipelineDescriptor { label: desc.label.map(Borrowed), - layout: desc.layout.map(|l| l.id), + layout: desc.layout.map(|l| l.id.into()), stage: pipe::ProgrammableStageDescriptor { - module: desc.module.id, + module: desc.module.id.into(), entry_point: Borrowed(desc.entry_point), }, }; let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_compute_pipeline( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_compute_pipeline( + *device, &descriptor, (), implicit_pipeline_ids @@ -1485,73 +1173,78 @@ impl crate::Context for Context { log::warn!("Please report it to https://github.com/gfx-rs/naga"); } self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_compute_pipeline", ); } - id + (id, ()) } - fn device_create_buffer( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &crate::BufferDescriptor<'_>, - ) -> Self::BufferId { + ) -> (Self::BufferId, Self::BufferData) { let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_buffer( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_buffer( + *device, &desc.map_label(|l| l.map(Borrowed)), () )); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_buffer", ); } - Buffer { + ( id, - error_sink: Arc::clone(&device.error_sink), - } + Buffer { + error_sink: Arc::clone(&device_data.error_sink), + }, + ) } - fn device_create_texture( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &TextureDescriptor, - ) -> Self::TextureId { + ) -> (Self::TextureId, Self::TextureData) { let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_texture( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_texture( + *device, &desc.map_label(|l| l.map(Borrowed)), () )); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_texture", ); } - Texture { + ( id, - error_sink: Arc::clone(&device.error_sink), - } + Texture { + id, + error_sink: Arc::clone(&device_data.error_sink), + }, + ) } - fn device_create_sampler( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &SamplerDescriptor, - ) -> Self::SamplerId { + ) -> (Self::SamplerId, Self::SamplerData) { let descriptor = wgc::resource::SamplerDescriptor { label: desc.label.map(Borrowed), address_modes: [ @@ -1570,72 +1263,74 @@ impl crate::Context for Context { }; let global = &self.0; - let (id, error) = wgc::gfx_select!(device.id => global.device_create_sampler( - device.id, + let (id, error) = wgc::gfx_select!(device => global.device_create_sampler( + *device, &descriptor, () )); if let Some(cause) = error { self.handle_error( - &device.error_sink, + &device_data.error_sink, cause, LABEL, desc.label, "Device::create_sampler", ); } - id + (id, ()) } - fn device_create_query_set( &self, device: &Self::DeviceId, + device_data: &Self::DeviceData, desc: &wgt::QuerySetDescriptor