diff --git a/CHANGELOG.md b/CHANGELOG.md index 70c2c791a6..4264429f04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -115,6 +115,7 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non - Make `Surface::get_default_config` return an Option to prevent panics. By @cwfitzgerald in [#3157](https://github.com/gfx-rs/wgpu/pull/3157) - Lower the `max_buffer_size` limit value for compatibility with Apple2 and WebGPU compliance. By @jinleili in [#3255](https://github.com/gfx-rs/wgpu/pull/3255) - Dereferencing a buffer view is now marked inline. By @Wumpf in [#3307](https://github.com/gfx-rs/wgpu/pull/3307) +- The `strict_assert` family of macros was moved to `wgpu-types`. By @i509VCB in [#3051](https://github.com/gfx-rs/wgpu/pull/3051) #### WebGPU diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index fb7c90d5ec..bc2c212fc7 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -34,7 +34,7 @@ emscripten = ["hal/emscripten"] # Apply run-time checks, even in release builds. These are in addition # to the validation carried out at public APIs in all builds. -strict_asserts = [] +strict_asserts = ["wgt/strict_asserts"] angle = ["hal/gles"] # Enable API tracing trace = ["ron", "serde", "wgt/trace", "arrayvec/serde", "naga/serialize"] diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index b31e7b4c48..a326e08307 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,6 +172,7 @@ 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); fn into_raw(self) -> NonZeroId; @@ -172,6 +180,10 @@ pub trait TypedId: Copy { #[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-core/src/lib.rs b/wgpu-core/src/lib.rs index c8b3fb7296..ff9f3d4b65 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -35,9 +35,6 @@ clippy::pattern_type_mismatch, )] -#[macro_use] -mod assertions; - pub mod binding_model; pub mod command; mod conv; diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index 65f02c467d..b7682968b2 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -19,6 +19,7 @@ use crate::{ LifeGuard, RefCount, }; use hal::BufferUses; +use wgt::{strict_assert, strict_assert_eq}; impl ResourceUses for BufferUses { const EXCLUSIVE: Self = Self::EXCLUSIVE; diff --git a/wgpu-core/src/track/metadata.rs b/wgpu-core/src/track/metadata.rs index 728ff5ca0e..73da0d6c5d 100644 --- a/wgpu-core/src/track/metadata.rs +++ b/wgpu-core/src/track/metadata.rs @@ -7,6 +7,7 @@ use crate::{ }; use bit_vec::BitVec; use std::{borrow::Cow, marker::PhantomData, mem}; +use wgt::strict_assert; /// A set of resources, holding a [`RefCount`] and epoch for each member. /// diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 9d85e1ab7b..4fdb64850c 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -114,6 +114,7 @@ pub(crate) use stateless::{StatelessBindGroupSate, StatelessTracker}; pub(crate) use texture::{ TextureBindGroupState, TextureSelector, TextureTracker, TextureUsageScope, }; +use wgt::strict_assert_ne; /// A structure containing all the information about a particular resource /// transition. User code should be able to generate a pipeline barrier diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index 635a7cecaf..6db2bab725 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -34,6 +34,7 @@ use hal::TextureUses; use arrayvec::ArrayVec; use naga::FastHashMap; +use wgt::{strict_assert, strict_assert_eq}; use std::{borrow::Cow, iter, marker::PhantomData, ops::Range, vec::Drain}; diff --git a/wgpu-types/Cargo.toml b/wgpu-types/Cargo.toml index 4b608b472f..c6b1ed6aa9 100644 --- a/wgpu-types/Cargo.toml +++ b/wgpu-types/Cargo.toml @@ -18,6 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] trace = ["serde"] replay = ["serde"] +strict_asserts = [] [dependencies] bitflags = "1" diff --git a/wgpu-types/src/assertions.rs b/wgpu-types/src/assertions.rs new file mode 100644 index 0000000000..87b4de33ef --- /dev/null +++ b/wgpu-types/src/assertions.rs @@ -0,0 +1,66 @@ +//! Macros for validation internal to the wgpu. +//! +//! This module defines assertion macros that respect `wgpu-type`'s +//! `"strict_asserts"` feature. +//! +//! Because `wgpu-core`'s public APIs validate their arguments in all +//! types of builds, for performance, the `track` module skips some of +//! Rust's usual run-time checks on its internal operations in release +//! builds. However, some `wgpu-core` applications have a strong +//! preference for robustness over performance. To accommodate them, +//! `wgpu-core`'s `"strict_asserts"` feature enables that validation +//! in both debug and release builds. + +/// This is equivalent to [`std::assert`] if the `strict_asserts` feature is activated. +#[cfg(feature = "strict_asserts")] +#[macro_export] +macro_rules! strict_assert { + ( $( $arg:tt )* ) => { + assert!( $( $arg )* ) + } +} + +/// This is equivalent to [`std::assert_eq`] if the `strict_asserts` feature is activated. +#[cfg(feature = "strict_asserts")] +#[macro_export] +macro_rules! strict_assert_eq { + ( $( $arg:tt )* ) => { + assert_eq!( $( $arg )* ) + } +} + +/// This is equivalent to [`std::assert_ne`] if the `strict_asserts` feature is activated. +#[cfg(feature = "strict_asserts")] +#[macro_export] +macro_rules! strict_assert_ne { + ( $( $arg:tt )* ) => { + assert_ne!( $( $arg )* ) + } +} + +/// This is equivalent to [`std::assert`] if the `strict_asserts` feature is activated. +#[cfg(not(feature = "strict_asserts"))] +#[macro_export] +macro_rules! strict_assert { + ( $( $arg:tt )* ) => { + debug_assert!( $( $arg )* ) + }; +} + +/// This is equivalent to [`std::assert_eq`] if the `strict_asserts` feature is activated. +#[cfg(not(feature = "strict_asserts"))] +#[macro_export] +macro_rules! strict_assert_eq { + ( $( $arg:tt )* ) => { + debug_assert_eq!( $( $arg )* ) + }; +} + +/// This is equivalent to [`std::assert_ne`] if the `strict_asserts` feature is activated. +#[cfg(not(feature = "strict_asserts"))] +#[macro_export] +macro_rules! strict_assert_ne { + ( $( $arg:tt )* ) => { + debug_assert_ne!( $( $arg )* ) + }; +} diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 82ffaf31f3..4d648f45e9 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -14,6 +14,8 @@ use serde::{Deserialize, Serialize}; use std::hash::{Hash, Hasher}; use std::{num::NonZeroU32, ops::Range}; +mod assertions; + // Use this macro instead of the one provided by the bitflags_serde_shim crate // because the latter produces an error when deserializing bits that are not // specified in the bitflags, while we want deserialization to succeed and diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index bb446b7d8e..0e1c259518 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -76,7 +76,10 @@ name = "water" test = true [features] -default = ["wgsl", "expose-ids"] +default = ["wgsl", "expose-ids", "strict_asserts"] +# Apply run-time checks, even in release builds. These are in addition +# to the validation carried out at public APIs in all builds. +strict_asserts = ["wgc/strict_asserts", "wgt/strict_asserts"] spirv = ["naga/spv-in"] glsl = ["naga/glsl-in"] wgsl = ["wgc?/wgsl"] @@ -148,10 +151,10 @@ raw-window-handle.workspace = true serde = { workspace = true, features = ["derive"], optional = true } smallvec.workspace = true static_assertions.workspace = true +cfg-if.workspace = true [dev-dependencies] bitflags.workspace = true -cfg-if.workspace = true bytemuck = { workspace = true, features = ["derive"] } glam.workspace = true ddsfile.workspace = true diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 8474c35f53..db0ad568cd 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1,17 +1,19 @@ use crate::{ + context::{ObjectId, Unused}, AdapterInfo, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BufferBinding, CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, DownlevelCapabilities, Features, Label, Limits, LoadOp, MapMode, Operations, PipelineLayoutDescriptor, RenderBundleEncoderDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderModuleDescriptor, ShaderModuleDescriptorSpirV, ShaderSource, - SurfaceStatus, TextureDescriptor, TextureViewDescriptor, + SurfaceStatus, TextureDescriptor, 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 +21,8 @@ use std::{ slice, sync::Arc, }; +use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*}; +use wgc::id::TypedId; const LABEL: &str = "label"; @@ -202,22 +206,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, ) -> Result { let id = self @@ -232,7 +233,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, ) -> Result { let id = self @@ -246,17 +247,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 = unsafe { 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(), } } @@ -331,434 +326,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, @@ -812,6 +389,14 @@ pub struct Surface { configured_device: Mutex>, } +impl Surface { + // Not used on every platform + #[allow(dead_code)] + pub fn id(&self) -> wgc::id::SurfaceId { + self.id + } +} + #[derive(Debug)] pub struct Device { id: wgc::id::DeviceId, @@ -819,9 +404,16 @@ pub struct Device { features: Features, } +impl Device { + // Not used on every platform + #[allow(dead_code)] + pub fn id(&self) -> wgc::id::DeviceId { + self.id + } +} + #[derive(Debug)] -pub(crate) struct Buffer { - id: wgc::id::BufferId, +pub struct Buffer { error_sink: ErrorSink, } @@ -831,6 +423,14 @@ pub struct Texture { error_sink: ErrorSink, } +impl Texture { + // Not used on every platform + #[allow(dead_code)] + pub fn id(&self) -> wgc::id::TextureId { + self.id + } +} + #[derive(Debug)] pub struct Queue { id: wgc::id::QueueId, @@ -838,103 +438,82 @@ pub struct Queue { } impl Queue { - pub(crate) fn backend(&self) -> wgt::Backend { - self.id.backend() + // Not used on every platform + #[allow(dead_code)] + pub fn id(&self) -> wgc::id::QueueId { + self.id } } #[derive(Debug)] -pub(crate) struct CommandEncoder { - id: wgc::id::CommandEncoderId, +pub struct CommandEncoder { error_sink: ErrorSink, open: bool, } -impl crate::GlobalId for T { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - T::into_raw(*self).get().into() - } -} - -impl crate::GlobalId for Surface { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - use wgc::id::TypedId; - self.id.into_raw().get().into() - } -} - -impl crate::GlobalId for Device { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - use wgc::id::TypedId; - self.id.into_raw().get().into() - } -} - -impl crate::GlobalId for Buffer { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - use wgc::id::TypedId; - self.id.into_raw().get().into() - } -} - -impl crate::GlobalId for Texture { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - use wgc::id::TypedId; - self.id.into_raw().get().into() - } -} - -impl crate::GlobalId for CommandEncoder { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - use wgc::id::TypedId; - self.id.into_raw().get().into() - } -} - -impl crate::GlobalId for Queue { - #[allow(clippy::useless_conversion)] // because not(id32) - fn global_id(&self) -> u64 { - use wgc::id::TypedId; - self.id.into_raw().get().into() - } -} - impl crate::Context for Context { type AdapterId = wgc::id::AdapterId; - type DeviceId = Device; - type QueueId = Queue; + type AdapterData = (); + type DeviceId = wgc::id::DeviceId; + type DeviceData = Device; + type QueueId = wgc::id::QueueId; + type QueueData = Queue; 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 = Unused; + type ComputePassData = wgc::command::ComputePass; + type RenderPassId = Unused; + type RenderPassData = wgc::command::RenderPass; type CommandBufferId = wgc::id::CommandBufferId; - type RenderBundleEncoderId = wgc::command::RenderBundleEncoder; + type CommandBufferData = (); + type RenderBundleEncoderId = Unused; + 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 = Unused; + 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 { @@ -949,13 +528,18 @@ impl crate::Context for Context { &self, display_handle: raw_window_handle::RawDisplayHandle, window_handle: raw_window_handle::RawWindowHandle, - ) -> Result { - Ok(Surface { - id: self - .0 - .instance_create_surface(display_handle, window_handle, ()), - configured_device: Mutex::new(None), - }) + ) -> Result<(Self::SurfaceId, Self::SurfaceData), crate::CreateSurfaceError> { + let id = self + .0 + .instance_create_surface(display_handle, window_handle, ()); + + Ok(( + id, + Surface { + id, + configured_device: Mutex::new(None), + }, + )) } fn instance_request_adapter( @@ -966,24 +550,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 { @@ -1008,23 +585,36 @@ impl crate::Context for Context { id: device_id, error_sink, }; - ready(Ok((device, queue))) + ready(Ok((device_id, device, device_id, queue))) + } + + 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, @@ -1032,7 +622,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, @@ -1040,7 +634,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, @@ -1048,7 +646,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, @@ -1059,6 +661,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; @@ -1072,10 +675,12 @@ impl crate::Context for Context { fn surface_get_capabilities( &self, surface: &Self::SurfaceId, + _surface_data: &Self::SurfaceData, adapter: &Self::AdapterId, + _adapter_data: &Self::AdapterData, ) -> wgt::SurfaceCapabilities { let global = &self.0; - match wgc::gfx_select!(adapter => global.surface_get_capabilities(surface.id, *adapter)) { + match wgc::gfx_select!(adapter => global.surface_get_capabilities(*surface, *adapter)) { Ok(caps) => caps, Err(wgc::instance::GetSurfaceSupportError::Unsupported) => { wgt::SurfaceCapabilities::default() @@ -1087,52 +692,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"), } @@ -1144,31 +762,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"), } @@ -1186,9 +812,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), @@ -1205,7 +832,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 { @@ -1221,7 +848,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)), @@ -1230,25 +857,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), @@ -1257,62 +885,66 @@ impl crate::Context for Context { shader_bound_checks: unsafe { 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)); } } } @@ -1320,12 +952,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, })); @@ -1345,7 +980,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, }), @@ -1355,53 +990,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!( @@ -1414,7 +1057,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), @@ -1423,28 +1066,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 @@ -1467,10 +1110,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), @@ -1480,7 +1123,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), @@ -1489,8 +1132,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 @@ -1501,21 +1144,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 { @@ -1527,16 +1170,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 @@ -1551,73 +1194,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: [ @@ -1636,72 +1284,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