From 87a0cd0e69dabd66da4d542b1cec0c71765cfc04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:35:02 +0200 Subject: [PATCH 01/19] Bump profiling from 1.0.10 to 1.0.11 (#4153) Bumps [profiling](https://github.com/aclysma/profiling) from 1.0.10 to 1.0.11. - [Changelog](https://github.com/aclysma/profiling/blob/master/CHANGELOG.md) - [Commits](https://github.com/aclysma/profiling/commits) --- updated-dependencies: - dependency-name: profiling dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 303e94dbd8..f966a215f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2126,9 +2126,9 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f10e75d83c7aec79a6aa46f897075890e156b105eebe51cfa0abce51af025f" +checksum = "f89dff0959d98c9758c88826cc002e2c3d0b9dfac4139711d1f30de442f1139b" [[package]] name = "quote" From 5c26841d66b7fb0675ba6b8509b483e6ac2c30ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:35:12 +0200 Subject: [PATCH 02/19] Bump termcolor from 1.2.0 to 1.3.0 (#4152) Bumps [termcolor](https://github.com/BurntSushi/termcolor) from 1.2.0 to 1.3.0. - [Commits](https://github.com/BurntSushi/termcolor/compare/1.2.0...1.3.0) --- updated-dependencies: - dependency-name: termcolor dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f966a215f0..9978941db4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2632,9 +2632,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] diff --git a/Cargo.toml b/Cargo.toml index 40b8c46c96..10378fc231 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -142,7 +142,7 @@ deno_web = "0.137.0" deno_webidl = "0.106.0" deno_webgpu = { path = "./deno_webgpu" } tokio = "1.32.0" -termcolor = "1.2.0" +termcolor = "1.3.0" [patch."https://github.com/gfx-rs/naga"] #naga = { path = "../naga" } From dc5beac8c96536d8c8a2ca98c22021dff14e53cf Mon Sep 17 00:00:00 2001 From: Frederik Magnus Johansen Vestre Date: Tue, 19 Sep 2023 13:26:30 +0200 Subject: [PATCH 03/19] Support dual source blending (#4022) Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> --- CHANGELOG.md | 1 + wgpu-core/src/device/resource.rs | 46 +++++++++++++++++++++++++++++++- wgpu-core/src/pipeline.rs | 9 +++++++ wgpu-core/src/validation.rs | 14 +++++++++- wgpu-hal/src/dx12/adapter.rs | 4 ++- wgpu-hal/src/dx12/conv.rs | 12 ++++----- wgpu-hal/src/gles/adapter.rs | 4 +++ wgpu-hal/src/gles/conv.rs | 4 +++ wgpu-hal/src/metal/adapter.rs | 4 +++ wgpu-hal/src/metal/conv.rs | 10 +++---- wgpu-hal/src/vulkan/adapter.rs | 2 ++ wgpu-hal/src/vulkan/conv.rs | 4 +++ wgpu-types/src/lib.rs | 37 ++++++++++++++++++++++++- wgpu/src/backend/web.rs | 9 +++++++ 14 files changed, 144 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f90b3d90..d60e0cd84f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,7 @@ By @wumpf in [#4147](https://github.com/gfx-rs/wgpu/pull/4147) - Add validation in accordance with WebGPU `setViewport` valid usage for `x`, `y` and `this.[[attachment_size]]`. By @James2022-rgb in [#4058](https://github.com/gfx-rs/wgpu/pull/4058) - `wgpu::CreateSurfaceError` and `wgpu::RequestDeviceError` now give details of the failure, but no longer implement `PartialEq` and cannot be constructed. By @kpreid in [#4066](https://github.com/gfx-rs/wgpu/pull/4066) and [#4145](https://github.com/gfx-rs/wgpu/pull/4145) - Make `WGPU_POWER_PREF=none` a valid value. By @fornwall in [4076](https://github.com/gfx-rs/wgpu/pull/4076) +- Support dual source blending in OpenGL ES, Metal, Vulkan & DX12. By @freqmod in [4022](https://github.com/gfx-rs/wgpu/pull/4022) #### Vulkan diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 73f1887e10..ba7006d3d5 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -1276,6 +1276,10 @@ impl Device { .flags .contains(wgt::DownlevelFlags::MULTISAMPLED_SHADING), ); + caps.set( + Caps::DUAL_SOURCE_BLENDING, + self.features.contains(wgt::Features::DUAL_SOURCE_BLENDING), + ); let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps) .validate(&module) @@ -2560,6 +2564,8 @@ impl Device { let mut vertex_steps = Vec::with_capacity(desc.vertex.buffers.len()); let mut vertex_buffers = Vec::with_capacity(desc.vertex.buffers.len()); let mut total_attributes = 0; + let mut shader_expects_dual_source_blending = false; + let mut pipeline_expects_dual_source_blending = false; for (i, vb_state) in desc.vertex.buffers.iter().enumerate() { vertex_steps.push(pipeline::VertexStep { stride: vb_state.array_stride, @@ -2700,7 +2706,25 @@ impl Device { { break Some(pipeline::ColorStateError::FormatNotMultisampled(cs.format)); } - + if let Some(blend_mode) = cs.blend { + for factor in [ + blend_mode.color.src_factor, + blend_mode.color.dst_factor, + blend_mode.alpha.src_factor, + blend_mode.alpha.dst_factor, + ] { + if factor.ref_second_blend_source() { + self.require_features(wgt::Features::DUAL_SOURCE_BLENDING)?; + if i == 0 { + pipeline_expects_dual_source_blending = true; + break; + } else { + return Err(crate::pipeline::CreateRenderPipelineError + ::BlendFactorOnUnsupportedTarget { factor, target: i as u32 }); + } + } + } + } break None; }; if let Some(e) = error { @@ -2857,6 +2881,15 @@ impl Device { } } + if let Some(ref interface) = shader_module.interface { + shader_expects_dual_source_blending = interface + .fragment_uses_dual_source_blending(&fragment.stage.entry_point) + .map_err(|error| pipeline::CreateRenderPipelineError::Stage { + stage: flag, + error, + })?; + } + Some(hal::ProgrammableStage { module: &shader_module.raw, entry_point: fragment.stage.entry_point.as_ref(), @@ -2865,6 +2898,17 @@ impl Device { None => None, }; + if !pipeline_expects_dual_source_blending && shader_expects_dual_source_blending { + return Err( + pipeline::CreateRenderPipelineError::ShaderExpectsPipelineToUseDualSourceBlending, + ); + } + if pipeline_expects_dual_source_blending && !shader_expects_dual_source_blending { + return Err( + pipeline::CreateRenderPipelineError::PipelineExpectsShaderToUseDualSourceBlending, + ); + } + if validated_stages.contains(wgt::ShaderStages::FRAGMENT) { for (i, output) in io.iter() { match color_targets.get(*i as usize) { diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index da06b652ea..c78a79820d 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -384,6 +384,15 @@ pub enum CreateRenderPipelineError { }, #[error("In the provided shader, the type given for group {group} binding {binding} has a size of {size}. As the device does not support `DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED`, the type must have a size that is a multiple of 16 bytes.")] UnalignedShader { group: u32, binding: u32, size: u64 }, + #[error("Using the blend factor {factor:?} for render target {target} is not possible. Only the first render target may be used when dual-source blending.")] + BlendFactorOnUnsupportedTarget { + factor: wgt::BlendFactor, + target: u32, + }, + #[error("Pipeline expects the shader entry point to make use of dual-source blending.")] + PipelineExpectsShaderToUseDualSourceBlending, + #[error("Shader entry point expects the pipeline to make use of dual-source blending.")] + ShaderExpectsPipelineToUseDualSourceBlending, } bitflags::bitflags! { diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index e3ecb916d3..778cc26cd5 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -116,6 +116,7 @@ struct EntryPoint { spec_constants: Vec, sampling_pairs: FastHashSet<(naga::Handle, naga::Handle)>, workgroup_size: [u32; 3], + dual_source_blending: bool, } #[derive(Debug)] @@ -903,7 +904,7 @@ impl Interface { ep.sampling_pairs .insert((resource_mapping[&key.image], resource_mapping[&key.sampler])); } - + ep.dual_source_blending = info.dual_source_blending; ep.workgroup_size = entry_point.workgroup_size; entry_points.insert((entry_point.stage, entry_point.name.clone()), ep); @@ -1177,4 +1178,15 @@ impl Interface { .collect(); Ok(outputs) } + + pub fn fragment_uses_dual_source_blending( + &self, + entry_point_name: &str, + ) -> Result { + let pair = (naga::ShaderStage::Fragment, entry_point_name.to_string()); + self.entry_points + .get(&pair) + .ok_or(StageError::MissingEntryPoint(pair.1)) + .map(|ep| ep.dual_source_blending) + } } diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 02cde913ca..3959deeccd 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -250,7 +250,9 @@ impl super::Adapter { | wgt::Features::TEXTURE_FORMAT_16BIT_NORM | wgt::Features::PUSH_CONSTANTS | wgt::Features::SHADER_PRIMITIVE_INDEX - | wgt::Features::RG11B10UFLOAT_RENDERABLE; + | wgt::Features::RG11B10UFLOAT_RENDERABLE + | wgt::Features::DUAL_SOURCE_BLENDING; + //TODO: in order to expose this, we need to run a compute shader // that extract the necessary statistics out of the D3D12 result. // Alternatively, we could allocate a buffer for the query set, diff --git a/wgpu-hal/src/dx12/conv.rs b/wgpu-hal/src/dx12/conv.rs index 908944567a..f484d1a9e2 100644 --- a/wgpu-hal/src/dx12/conv.rs +++ b/wgpu-hal/src/dx12/conv.rs @@ -246,12 +246,12 @@ fn map_blend_factor(factor: wgt::BlendFactor, is_alpha: bool) -> d3d12_ty::D3D12 Bf::Constant => d3d12_ty::D3D12_BLEND_BLEND_FACTOR, Bf::OneMinusConstant => d3d12_ty::D3D12_BLEND_INV_BLEND_FACTOR, Bf::SrcAlphaSaturated => d3d12_ty::D3D12_BLEND_SRC_ALPHA_SAT, - //Bf::Src1Color if is_alpha => d3d12_ty::D3D12_BLEND_SRC1_ALPHA, - //Bf::Src1Color => d3d12_ty::D3D12_BLEND_SRC1_COLOR, - //Bf::OneMinusSrc1Color if is_alpha => d3d12_ty::D3D12_BLEND_INV_SRC1_ALPHA, - //Bf::OneMinusSrc1Color => d3d12_ty::D3D12_BLEND_INV_SRC1_COLOR, - //Bf::Src1Alpha => d3d12_ty::D3D12_BLEND_SRC1_ALPHA, - //Bf::OneMinusSrc1Alpha => d3d12_ty::D3D12_BLEND_INV_SRC1_ALPHA, + Bf::Src1 if is_alpha => d3d12_ty::D3D12_BLEND_SRC1_ALPHA, + Bf::Src1 => d3d12_ty::D3D12_BLEND_SRC1_COLOR, + Bf::OneMinusSrc1 if is_alpha => d3d12_ty::D3D12_BLEND_INV_SRC1_ALPHA, + Bf::OneMinusSrc1 => d3d12_ty::D3D12_BLEND_INV_SRC1_COLOR, + Bf::Src1Alpha => d3d12_ty::D3D12_BLEND_SRC1_ALPHA, + Bf::OneMinusSrc1Alpha => d3d12_ty::D3D12_BLEND_INV_SRC1_ALPHA, } } diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 348f62bc03..3dae58b7c4 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -363,6 +363,10 @@ impl super::Adapter { wgt::Features::MULTIVIEW, extensions.contains("OVR_multiview2"), ); + features.set( + wgt::Features::DUAL_SOURCE_BLENDING, + extensions.contains("GL_EXT_blend_func_extended"), + ); features.set( wgt::Features::SHADER_PRIMITIVE_INDEX, ver >= (3, 2) || extensions.contains("OES_geometry_shader"), diff --git a/wgpu-hal/src/gles/conv.rs b/wgpu-hal/src/gles/conv.rs index dd5d764c6a..9bfac022a1 100644 --- a/wgpu-hal/src/gles/conv.rs +++ b/wgpu-hal/src/gles/conv.rs @@ -376,6 +376,10 @@ fn map_blend_factor(factor: wgt::BlendFactor) -> u32 { Bf::Constant => glow::CONSTANT_COLOR, Bf::OneMinusConstant => glow::ONE_MINUS_CONSTANT_COLOR, Bf::SrcAlphaSaturated => glow::SRC_ALPHA_SATURATE, + Bf::Src1 => glow::SRC1_COLOR, + Bf::OneMinusSrc1 => glow::ONE_MINUS_SRC1_COLOR, + Bf::Src1Alpha => glow::SRC1_ALPHA, + Bf::OneMinusSrc1Alpha => glow::ONE_MINUS_SRC1_ALPHA, } } diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 126741d257..da254442bc 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -833,6 +833,10 @@ impl super::PrivateCapabilities { self.timestamp_query_support .contains(TimestampQuerySupport::INSIDE_WGPU_PASSES), ); + features.set( + F::DUAL_SOURCE_BLENDING, + self.msl_version >= MTLLanguageVersion::V1_2 && self.dual_source_blending, + ); features.set(F::TEXTURE_COMPRESSION_ASTC, self.format_astc); features.set(F::TEXTURE_COMPRESSION_ASTC_HDR, self.format_astc_hdr); features.set(F::TEXTURE_COMPRESSION_BC, self.format_bc); diff --git a/wgpu-hal/src/metal/conv.rs b/wgpu-hal/src/metal/conv.rs index a1ceb287ab..8f6439b50b 100644 --- a/wgpu-hal/src/metal/conv.rs +++ b/wgpu-hal/src/metal/conv.rs @@ -152,13 +152,11 @@ pub fn map_blend_factor(factor: wgt::BlendFactor) -> metal::MTLBlendFactor { Bf::OneMinusDstAlpha => OneMinusDestinationAlpha, Bf::Constant => BlendColor, Bf::OneMinusConstant => OneMinusBlendColor, - //Bf::ConstantAlpha => BlendAlpha, - //Bf::OneMinusConstantAlpha => OneMinusBlendAlpha, Bf::SrcAlphaSaturated => SourceAlphaSaturated, - //Bf::Src1 => Source1Color, - //Bf::OneMinusSrc1 => OneMinusSource1Color, - //Bf::Src1Alpha => Source1Alpha, - //Bf::OneMinusSrc1Alpha => OneMinusSource1Alpha, + Bf::Src1 => Source1Color, + Bf::OneMinusSrc1 => OneMinusSource1Color, + Bf::Src1Alpha => Source1Alpha, + Bf::OneMinusSrc1Alpha => OneMinusSource1Alpha, } } diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index bcbab85084..78aceeeeef 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -177,6 +177,7 @@ impl PhysicalDeviceFeatures { //.shader_resource_residency(requested_features.contains(wgt::Features::SHADER_RESOURCE_RESIDENCY)) .geometry_shader(requested_features.contains(wgt::Features::SHADER_PRIMITIVE_INDEX)) .depth_clamp(requested_features.contains(wgt::Features::DEPTH_CLIP_CONTROL)) + .dual_src_blend(requested_features.contains(wgt::Features::DUAL_SOURCE_BLENDING)) .build(), descriptor_indexing: if requested_features.intersects(indexing_features()) { Some( @@ -460,6 +461,7 @@ impl PhysicalDeviceFeatures { } features.set(F::DEPTH_CLIP_CONTROL, self.core.depth_clamp != 0); + features.set(F::DUAL_SOURCE_BLENDING, self.core.dual_src_blend != 0); if let Some(ref multiview) = self.multiview { features.set(F::MULTIVIEW, multiview.multiview != 0); diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index e2398c2689..459b7f858f 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -792,6 +792,10 @@ fn map_blend_factor(factor: wgt::BlendFactor) -> vk::BlendFactor { Bf::SrcAlphaSaturated => vk::BlendFactor::SRC_ALPHA_SATURATE, Bf::Constant => vk::BlendFactor::CONSTANT_COLOR, Bf::OneMinusConstant => vk::BlendFactor::ONE_MINUS_CONSTANT_COLOR, + Bf::Src1 => vk::BlendFactor::SRC1_COLOR, + Bf::OneMinusSrc1 => vk::BlendFactor::ONE_MINUS_SRC1_COLOR, + Bf::Src1Alpha => vk::BlendFactor::SRC1_ALPHA, + Bf::OneMinusSrc1Alpha => vk::BlendFactor::ONE_MINUS_SRC1_ALPHA, } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 9f61e2e490..e08b802094 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -781,7 +781,17 @@ bitflags::bitflags! { /// This is a native only feature. const SHADER_EARLY_DEPTH_TEST = 1 << 62; - // 62..64 available + /// Allows two outputs from a shader to be used for blending. + /// Note that dual-source blending doesn't support multiple render targets. + /// + /// For more info see the OpenGL ES extension GL_EXT_blend_func_extended. + /// + /// Supported platforms: + /// - OpenGL ES (with GL_EXT_blend_func_extended) + /// - Metal (with MSL 1.2+) + /// - Vulkan (with dualSrcBlend) + /// - DX12 + const DUAL_SOURCE_BLENDING = 1 << 63; } } @@ -1549,6 +1559,8 @@ impl TextureViewDimension { /// /// Corresponds to [WebGPU `GPUBlendFactor`]( /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendfactor). +/// Values using S1 requires [`Features::DUAL_SOURCE_BLENDING`] and can only be +/// used with the first render target. #[repr(C)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] #[cfg_attr(feature = "trace", derive(Serialize))] @@ -1581,6 +1593,29 @@ pub enum BlendFactor { Constant = 11, /// 1.0 - Constant OneMinusConstant = 12, + /// S1.component + Src1 = 13, + /// 1.0 - S1.component + OneMinusSrc1 = 14, + /// S1.alpha + Src1Alpha = 15, + /// 1.0 - S1.alpha + OneMinusSrc1Alpha = 16, +} + +impl BlendFactor { + /// Returns `true` if the blend factor references the second blend source. + /// + /// Note that the usage of those blend factors require [`Features::DUAL_SOURCE_BLENDING`]. + pub fn ref_second_blend_source(&self) -> bool { + match self { + BlendFactor::Src1 + | BlendFactor::OneMinusSrc1 + | BlendFactor::Src1Alpha + | BlendFactor::OneMinusSrc1Alpha => true, + _ => false, + } + } } /// Alpha blend operation. diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index d457681e57..b649d41ebb 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -421,6 +421,15 @@ fn map_blend_factor(factor: wgt::BlendFactor) -> web_sys::GpuBlendFactor { BlendFactor::SrcAlphaSaturated => bf::SrcAlphaSaturated, BlendFactor::Constant => bf::Constant, BlendFactor::OneMinusConstant => bf::OneMinusConstant, + BlendFactor::Src1 + | BlendFactor::OneMinusSrc1 + | BlendFactor::Src1Alpha + | BlendFactor::OneMinusSrc1Alpha => { + panic!( + "{:?} is not enabled for this backend", + wgt::Features::DUAL_SOURCE_BLENDING + ) + } } } From 82f0cd9ee655fc14af04693e9d30c5e3130161ce Mon Sep 17 00:00:00 2001 From: Alphyr <47725341+a1phyr@users.noreply.github.com> Date: Wed, 20 Sep 2023 20:45:09 +0200 Subject: [PATCH 04/19] Fix `Features::TEXTURE_COMPRESSION_ASTC*` doc (#4157) Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 3 ++- wgpu-types/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d60e0cd84f..4a54939a25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,7 +110,8 @@ By @wumpf in [#4147](https://github.com/gfx-rs/wgpu/pull/4147) ### Documentation -- Use WGSL for VertexFormat example types. By @ScanMountGoat in [#4305](https://github.com/gfx-rs/wgpu/pull/4035) +- Use WGSL for VertexFormat example types. By @ScanMountGoat in [#4035](https://github.com/gfx-rs/wgpu/pull/4035) +- Fix description of `Features::TEXTURE_COMPRESSION_ASTC_HDR` in [#4157](https://github.com/gfx-rs/wgpu/pull/4157) #### Metal diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index e08b802094..59c32ec3b8 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -371,7 +371,7 @@ bitflags::bitflags! { /// Compressed textures sacrifice some quality in exchange for significantly reduced /// bandwidth usage. /// - /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats. + /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats with Unorm/UnormSrgb channel type. /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages. /// /// Supported Platforms: @@ -409,7 +409,7 @@ bitflags::bitflags! { /// Compressed textures sacrifice some quality in exchange for significantly reduced /// bandwidth usage. /// - /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for BCn formats. + /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats with the HDR channel type. /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages. /// /// Supported Platforms: From 3c37c2afe525d9ea28c3b525b1f5a927a1ce13fb Mon Sep 17 00:00:00 2001 From: Neil Sarkar Date: Wed, 20 Sep 2023 12:07:40 -0700 Subject: [PATCH 05/19] Bring back xtask alias (#4160) --- .cargo/config.toml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000..95d2a35175 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,7 @@ +[alias] +xtask = "run --manifest-path xtask/Cargo.toml --" + +[build] +rustflags = [ +"--cfg=web_sys_unstable_apis" +] From 2b4a8b318fb3717473b7da20b028dbc1f58ee9a2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 20 Sep 2023 21:02:37 -0400 Subject: [PATCH 06/19] wgpu-core: Only produce StageError::InputNotConsumed on DX11/DX12 (#4116) * wgpu-core: Only produce StageError::InputNotConsumed on DX11/DX12 This error only exists due to an issue with naga's HLSL support: https://github.com/gfx-rs/naga/issues/1945 The WGPU spec itself allows vertex shader outputs that are not consumed by the fragment shader. Until the issue is fixed, we can allow unconsumed outputs on all platforms other than DX11/DX12. * Add Features::SHADER_UNUSED_VERTEX_OUTPUT to allow disabling check * Pick an unused feature id --- CHANGELOG.md | 1 + deno_webgpu/lib.rs | 7 +++++++ wgpu-core/src/device/resource.rs | 3 ++- wgpu-core/src/validation.rs | 16 ++++++++++++++-- wgpu-hal/src/gles/adapter.rs | 1 + wgpu-hal/src/metal/adapter.rs | 1 + wgpu-hal/src/vulkan/adapter.rs | 1 + wgpu-types/src/lib.rs | 9 +++++++++ 8 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a54939a25..08d20c09fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -124,6 +124,7 @@ By @wumpf in [#4147](https://github.com/gfx-rs/wgpu/pull/4147) - Derive storage bindings via `naga::StorageAccess` instead of `naga::GlobalUse`. By @teoxoy in [#3985](https://github.com/gfx-rs/wgpu/pull/3985). - `Queue::on_submitted_work_done` callbacks will now always be called after all previous `BufferSlice::map_async` callbacks, even when there are no active submissions. By @cwfitzgerald in [#4036](https://github.com/gfx-rs/wgpu/pull/4036). - Fix `clear` texture views being leaked when `wgpu::SurfaceTexture` is dropped before it is presented. By @rajveermalviya in [#4057](https://github.com/gfx-rs/wgpu/pull/4057). +- Add `Feature::SHADER_UNUSED_VERTEX_OUTPUT` to allow unused vertex shader outputs. By @Aaron1011 in [#4116](https://github.com/gfx-rs/wgpu/pull/4116). #### Vulkan - Fix enabling `wgpu::Features::PARTIALLY_BOUND_BINDING_ARRAY` not being actually enabled in vulkan backend. By @39ali in[#3772](https://github.com/gfx-rs/wgpu/pull/3772). diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 92a6a51334..bf61e42517 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -365,6 +365,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::SHADER_EARLY_DEPTH_TEST) { return_features.push("shader-early-depth-test"); } + if features.contains(wgpu_types::Features::SHADER_UNUSED_VERTEX_OUTPUT) { + return_features.push("shader-unused-vertex-output"); + } return_features } @@ -625,6 +628,10 @@ impl From for wgpu_types::Features { wgpu_types::Features::SHADER_EARLY_DEPTH_TEST, required_features.0.contains("shader-early-depth-test"), ); + features.set( + wgpu_types::Features::SHADER_UNUSED_VERTEX_OUTPUT, + required_features.0.contains("shader-unused-vertex-output"), + ); features } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index ba7006d3d5..8acc34acf4 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -1290,7 +1290,8 @@ impl Device { inner: Box::new(inner), }) })?; - let interface = validation::Interface::new(&module, &info, self.limits.clone()); + let interface = + validation::Interface::new(&module, &info, self.limits.clone(), self.features); let hal_shader = hal::ShaderInput::Naga(hal::NagaShader { module, info }); let hal_desc = hal::ShaderModuleDescriptor { diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 778cc26cd5..ef5c65ed00 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -122,6 +122,7 @@ struct EntryPoint { #[derive(Debug)] pub struct Interface { limits: wgt::Limits, + features: wgt::Features, resources: naga::Arena, entry_points: FastHashMap<(naga::ShaderStage, String), EntryPoint>, } @@ -831,7 +832,12 @@ impl Interface { list.push(varying); } - pub fn new(module: &naga::Module, info: &naga::valid::ModuleInfo, limits: wgt::Limits) -> Self { + pub fn new( + module: &naga::Module, + info: &naga::valid::ModuleInfo, + limits: wgt::Limits, + features: wgt::Features, + ) -> Self { let mut resources = naga::Arena::new(); let mut resource_mapping = FastHashMap::default(); for (var_handle, var) in module.global_variables.iter() { @@ -912,6 +918,7 @@ impl Interface { Self { limits, + features, resources, entry_points, } @@ -1121,7 +1128,12 @@ impl Interface { } // Check all vertex outputs and make sure the fragment shader consumes them. - if shader_stage == naga::ShaderStage::Fragment { + // This requirement is removed if the `SHADER_UNUSED_VERTEX_OUTPUT` feature is enabled. + if shader_stage == naga::ShaderStage::Fragment + && !self + .features + .contains(wgt::Features::SHADER_UNUSED_VERTEX_OUTPUT) + { for &index in inputs.keys() { // This is a linear scan, but the count should be low enough // that this should be fine. diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 3dae58b7c4..cbbcf7399e 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -372,6 +372,7 @@ impl super::Adapter { ver >= (3, 2) || extensions.contains("OES_geometry_shader"), ); features.set(wgt::Features::SHADER_EARLY_DEPTH_TEST, ver >= (3, 1)); + features.set(wgt::Features::SHADER_UNUSED_VERTEX_OUTPUT, true); let gles_bcn_exts = [ "GL_EXT_texture_compression_s3tc_srgb", "GL_EXT_texture_compression_rgtc", diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index da254442bc..c4617deaa0 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -871,6 +871,7 @@ impl super::PrivateCapabilities { features.set(F::ADDRESS_MODE_CLAMP_TO_ZERO, true); features.set(F::RG11B10UFLOAT_RENDERABLE, self.format_rg11b10_all); + features.set(F::SHADER_UNUSED_VERTEX_OUTPUT, true); features } diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 78aceeeeef..b515628726 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -522,6 +522,7 @@ impl PhysicalDeviceFeatures { | vk::FormatFeatureFlags::COLOR_ATTACHMENT_BLEND, ); features.set(F::RG11B10UFLOAT_RENDERABLE, rg11b10ufloat_renderable); + features.set(F::SHADER_UNUSED_VERTEX_OUTPUT, true); (features, dl_flags) } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 59c32ec3b8..13603fc03f 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -737,6 +737,15 @@ bitflags::bitflags! { /// This is a native only feature. const VERTEX_ATTRIBUTE_64BIT = 1 << 53; + /// Allows vertex shaders to have outputs which are not consumed + /// by the fragment shader. + /// + /// Supported platforms: + /// - Vulkan + /// - Metal + /// - OpenGL + const SHADER_UNUSED_VERTEX_OUTPUT = 1 << 54; + // 54..59 available // Shader: From 3ff04c31e6b9b5f8b0589e6dfa55aecb91d1ce8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Sep 2023 02:36:45 +0000 Subject: [PATCH 07/19] Bump smallvec from 1.11.0 to 1.11.1 (#4161) Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.11.0 to 1.11.1. - [Release notes](https://github.com/servo/rust-smallvec/releases) - [Commits](https://github.com/servo/rust-smallvec/compare/v1.11.0...v1.11.1) --- updated-dependencies: - dependency-name: smallvec dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9978941db4..942cf10970 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2531,9 +2531,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smithay-client-toolkit" From 855fefc10e14caa7c262c9a21a1db25a821f3c96 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 21 Sep 2023 02:01:35 -0400 Subject: [PATCH 08/19] Update CODEOWNERS with new wgpu team (#4162) --- .github/CODEOWNERS | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7fefad320c..1d6e147803 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,4 @@ -/cts_runner/ @crowlKats -/deno_webgpu/ @crowlKats +* @gfx-rs/wgpu + +/cts_runner/ @gfx-rs/deno @gfx-rs/wgpu +/deno_webgpu/ @gfx-rs/deno @gfx-rs/wgpu From 85e2141355adb37cd58f90a5fcd889e14a659a91 Mon Sep 17 00:00:00 2001 From: Fredrik Fornwall Date: Fri, 22 Sep 2023 14:58:33 +0200 Subject: [PATCH 09/19] Fix using trunk version on mac (#4164) Overriding the metal version in the workspace Cargo.toml using a patch section does not work for projects building against the trunk version: wgpu = { git = "https://github.com/gfx-rs/wgpu", branch = "trunk" } Instead specify the metal dependencies only once in wgpu-hal. --- Cargo.toml | 9 --------- wgpu-hal/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 10378fc231..b10762248e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,12 +100,6 @@ wgpu-test = { version = "0.17", path = "./tests"} wgpu-types = { version = "0.17.0", path = "./wgpu-types" } winit = { version = "0.28.6", features = [ "android-native-activity" ] } -# Metal dependencies -block = "0.1" -metal = "0.26.0" -objc = "0.2.5" -core-graphics-types = "0.1" - # Vulkan dependencies ash = "0.37.3" gpu-alloc = "0.6" @@ -157,9 +151,6 @@ termcolor = "1.3.0" #naga = { path = "../naga" } #glow = { path = "../glow" } #d3d12 = { path = "../d3d12-rs" } -#metal = { path = "../metal-rs" } -#metal = { path = "../metal-rs" } -metal = { git = "https://github.com/gfx-rs/metal-rs/", rev = "d24f1a4" } # More timer support via https://github.com/gfx-rs/metal-rs/pull/280 #web-sys = { path = "../wasm-bindgen/crates/web-sys" } #js-sys = { path = "../wasm-bindgen/crates/js-sys" } #wasm-bindgen = { path = "../wasm-bindgen" } diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 3db7363616..3cc69975cc 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -103,7 +103,7 @@ d3d12 = { version = "0.7", features = ["libloading"], optional = true } # backend: Metal block = { version = "0.1", optional = true } -metal = "0.26.0" +metal = { git = "https://github.com/gfx-rs/metal-rs/", rev = "d24f1a4" } # More timer support via https://github.com/gfx-rs/metal-rs/pull/280 objc = "0.2.5" core-graphics-types = "0.1" From 8e393ca213ecd4b74c541a226a763fc4ec0a42c2 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 22 Sep 2023 20:00:07 -0700 Subject: [PATCH 10/19] Add some missing `Debug` implementations. (#4166) --- wgpu-types/src/lib.rs | 1 + wgpu/src/lib.rs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 13603fc03f..a680d91296 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6473,6 +6473,7 @@ pub enum Gles3MinorVersion { } /// Options for creating an instance. +#[derive(Debug)] pub struct InstanceDescriptor { /// Which `Backends` to enable. pub backends: Backends, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 88b852eaa4..f655075c06 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -523,7 +523,7 @@ impl Drop for ShaderModule { /// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, /// only WGSL source code strings are accepted. #[cfg_attr(feature = "naga", allow(clippy::large_enum_variant))] -#[derive(Clone)] +#[derive(Clone, Debug)] #[non_exhaustive] pub enum ShaderSource<'a> { /// SPIR-V module represented as a slice of words. @@ -560,7 +560,7 @@ static_assertions::assert_impl_all!(ShaderSource: Send, Sync); /// /// Corresponds to [WebGPU `GPUShaderModuleDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpushadermoduledescriptor). -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ShaderModuleDescriptor<'a> { /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. pub label: Label<'a>, @@ -574,6 +574,7 @@ static_assertions::assert_impl_all!(ShaderModuleDescriptor: Send, Sync); /// /// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, /// only WGSL source code strings are accepted. +#[derive(Debug)] pub struct ShaderModuleDescriptorSpirV<'a> { /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. pub label: Label<'a>, From 7e0d6c971f900f6a8f01a9de9c41f7894164a82c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 00:09:48 -0400 Subject: [PATCH 11/19] Bump glam from 0.24.1 to 0.24.2 (#4171) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 942cf10970..fdc1ff0554 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1127,9 +1127,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226" +checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" [[package]] name = "glow" diff --git a/Cargo.toml b/Cargo.toml index b10762248e..63e7ff9a8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,7 @@ ddsfile = "0.5" env_logger = "0.10" futures-intrusive = "0.5" rustc-hash = "1.1.0" -glam = "0.24.1" +glam = "0.24.2" image = { version = "0.24", default-features = false, features = ["png"] } # libloading 0.8 switches from `winapi` to `windows-sys`; permit either libloading = ">=0.7,<0.9" From 27f2ce397a5712f04c582642888c608f5aa1d5ce Mon Sep 17 00:00:00 2001 From: Jacob Hughes Date: Mon, 25 Sep 2023 13:57:15 -0400 Subject: [PATCH 12/19] Re-export Naga (#4172) --- CHANGELOG.md | 1 + wgpu/src/lib.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d20c09fa..9a50aee642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,7 @@ By @wumpf in [#4147](https://github.com/gfx-rs/wgpu/pull/4147) ### Added/New Features - Add `gles_minor_version` field to `wgpu::InstanceDescriptor`. By @PJB3005 in [#3998](https://github.com/gfx-rs/wgpu/pull/3998) +- Re-export Naga. By @exrook in [#4172](https://github.com/gfx-rs/wgpu/pull/4172) ### Changes diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index f655075c06..f62e14bcae 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -54,6 +54,8 @@ pub use wgt::{ ))] #[doc(hidden)] pub use ::hal; +#[cfg(feature = "naga")] +pub use ::naga; #[cfg(any( not(target_arch = "wasm32"), feature = "webgl", From 3666f1aef8fde9a74d736792299fb6d925b726b4 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Mon, 25 Sep 2023 16:55:55 -0700 Subject: [PATCH 13/19] Add test case for #4167, marked as an expected failure. (#4168) --- tests/tests/pipeline.rs | 37 +++++++++++++++++++++++++++++++++++++ tests/tests/root.rs | 1 + 2 files changed, 38 insertions(+) create mode 100644 tests/tests/pipeline.rs diff --git a/tests/tests/pipeline.rs b/tests/tests/pipeline.rs new file mode 100644 index 0000000000..37046dd6b9 --- /dev/null +++ b/tests/tests/pipeline.rs @@ -0,0 +1,37 @@ +use wasm_bindgen_test::*; +use wgpu_test::{fail, initialize_test, FailureCase, TestParameters}; + +#[test] +#[wasm_bindgen_test] +fn pipeline_default_layout_bad_module() { + // Create an invalid shader and a compute pipeline that uses it + // with a default bindgroup layout, and then ask for that layout. + // Validation should fail, but wgpu should not panic. + let parameters = TestParameters::default() + .skip(FailureCase::webgl2()) + // https://github.com/gfx-rs/wgpu/issues/4167 + .expect_fail(FailureCase::always()); + initialize_test(parameters, |ctx| { + ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); + + fail(&ctx.device, || { + let module = ctx + .device + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl("not valid wgsl".into()), + }); + + let pipeline = ctx + .device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: Some("mandelbrot compute pipeline"), + layout: None, + module: &module, + entry_point: "doesn't exist", + }); + + pipeline.get_bind_group_layout(0); + }); + }); +} diff --git a/tests/tests/root.rs b/tests/tests/root.rs index b2695fd827..ff910ef877 100644 --- a/tests/tests/root.rs +++ b/tests/tests/root.rs @@ -19,6 +19,7 @@ mod external_texture; mod instance; mod occlusion_query; mod partially_bounded_arrays; +mod pipeline; mod poll; mod query_set; mod queue_transfer; From 21e20076a09cdefaed3baadfaf23836cc0c9c7af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:41:31 +0200 Subject: [PATCH 14/19] Bump gpu-descriptor from 0.2.3 to 0.2.4 (#4173) Bumps [gpu-descriptor](https://github.com/zakarumych/gpu-descriptor) from 0.2.3 to 0.2.4. - [Changelog](https://github.com/zakarumych/gpu-descriptor/blob/master/CHANGELOG.md) - [Commits](https://github.com/zakarumych/gpu-descriptor/commits) --- updated-dependencies: - dependency-name: gpu-descriptor dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdc1ff0554..e58106ba94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,11 +35,11 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "getrandom 0.2.10", + "cfg-if", "once_cell", "version_check", ] @@ -53,6 +53,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-activity" version = "0.4.2" @@ -1242,13 +1248,13 @@ dependencies = [ [[package]] name = "gpu-descriptor" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" +checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "gpu-descriptor-types", - "hashbrown 0.12.3", + "hashbrown 0.14.0", ] [[package]] @@ -1265,15 +1271,16 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] [[package]] name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hassle-rs" From 2b1ea39028a1ec80fc591c8f61c05dbc70a7aad9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 23:44:52 -0400 Subject: [PATCH 15/19] Bump thiserror from 1.0.48 to 1.0.49 (#4178) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e58106ba94..814d133c96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2648,18 +2648,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", From 8d32dc2b47f8fa3d9d568f3d1a8150d208895f30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 23:45:02 -0400 Subject: [PATCH 16/19] Bump async-executor from 1.5.1 to 1.5.3 (#4174) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 814d133c96..48d4cefb05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,9 +130,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +checksum = "78f2db9467baa66a700abce2a18c5ad793f6f83310aca1284796fc3921d113fd" dependencies = [ "async-lock", "async-task", @@ -856,12 +856,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" @@ -1042,13 +1039,8 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", "futures-core", - "futures-io", - "memchr", - "parking", "pin-project-lite", - "waker-fn", ] [[package]] @@ -1958,12 +1950,6 @@ dependencies = [ "ttf-parser", ] -[[package]] -name = "parking" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" - [[package]] name = "parking_lot" version = "0.12.1" @@ -2929,12 +2915,6 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" From 57f8757fadf36b833714488fea8663ef8b0257eb Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Wed, 27 Sep 2023 05:34:23 -0700 Subject: [PATCH 17/19] Add device destroy method (#4163) Plus tests that ensure that an invalid device behaves correctly. Mostly a stub implementation otherwise. --- CHANGELOG.md | 1 + tests/tests/device.rs | 354 +++++++++++++++++++++++++++++- wgpu-core/src/command/clear.rs | 3 + wgpu-core/src/command/compute.rs | 9 + wgpu-core/src/command/render.rs | 9 + wgpu-core/src/command/transfer.rs | 16 +- wgpu-core/src/device/global.rs | 123 ++++++++++- wgpu-core/src/device/mod.rs | 6 +- wgpu-core/src/device/resource.rs | 39 ++++ wgpu-core/src/present.rs | 9 + wgpu/src/backend/direct.rs | 9 + wgpu/src/backend/web.rs | 10 + wgpu/src/context.rs | 16 ++ wgpu/src/lib.rs | 5 + 14 files changed, 601 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a50aee642..f59fc35dc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ By @wumpf in [#4147](https://github.com/gfx-rs/wgpu/pull/4147) - `wgpu::CreateSurfaceError` and `wgpu::RequestDeviceError` now give details of the failure, but no longer implement `PartialEq` and cannot be constructed. By @kpreid in [#4066](https://github.com/gfx-rs/wgpu/pull/4066) and [#4145](https://github.com/gfx-rs/wgpu/pull/4145) - Make `WGPU_POWER_PREF=none` a valid value. By @fornwall in [4076](https://github.com/gfx-rs/wgpu/pull/4076) - Support dual source blending in OpenGL ES, Metal, Vulkan & DX12. By @freqmod in [4022](https://github.com/gfx-rs/wgpu/pull/4022) +- Add stub support for device destroy and device validity. By @bradwerth in [4163](https://github.com/gfx-rs/wgpu/pull/4163) #### Vulkan diff --git a/tests/tests/device.rs b/tests/tests/device.rs index 7964f2afdb..991170e739 100644 --- a/tests/tests/device.rs +++ b/tests/tests/device.rs @@ -1,6 +1,6 @@ use wasm_bindgen_test::*; -use wgpu_test::{initialize_test, FailureCase, TestParameters}; +use wgpu_test::{fail, initialize_test, FailureCase, TestParameters}; #[test] #[wasm_bindgen_test] @@ -91,3 +91,355 @@ async fn request_device_error_message() { } assert!(device_error.contains(expected), "{device_error}"); } + +#[test] +fn device_destroy_then_more() { + // This is a test of device behavior after device.destroy. Specifically, all operations + // should trigger errors since the device is lost. + // + // On DX12 this test fails with a validation error in the very artifical actions taken + // after lose the device. The error is "ID3D12CommandAllocator::Reset: The command + // allocator cannot be reset because a command list is currently being recorded with the + // allocator." That may indicate that DX12 doesn't like opened command buffers staying + // open even after they return an error. For now, this test is skipped on DX12. + // + // The DX12 issue may be related to https://github.com/gfx-rs/wgpu/issues/3193. + initialize_test( + TestParameters::default() + .features(wgpu::Features::CLEAR_TEXTURE) + .skip(FailureCase::backend(wgpu::Backends::DX12)), + |ctx| { + // Create some resources on the device that we will attempt to use *after* losing + // the device. + + // Create some 512 x 512 2D textures. + let texture_extent = wgpu::Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }; + let texture_for_view = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: texture_extent, + mip_level_count: 2, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Uint, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + let target_view = texture_for_view.create_view(&wgpu::TextureViewDescriptor::default()); + + let texture_for_read = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: texture_extent, + mip_level_count: 2, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Uint, + usage: wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + + let texture_for_write = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: texture_extent, + mip_level_count: 2, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Uint, + usage: wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + + // Create some buffers. + let buffer_source = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + let buffer_dest = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + // Create a bind group layout. + let bind_group_layout = + ctx.device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[], + }); + + // Create a shader module. + let shader_module = ctx + .device + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed("")), + }); + + // Create some command encoders. + let mut encoder_for_clear = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + let mut encoder_for_compute_pass = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + let mut encoder_for_render_pass = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + let mut encoder_for_buffer_buffer_copy = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + let mut encoder_for_buffer_texture_copy = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + let mut encoder_for_texture_buffer_copy = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + let mut encoder_for_texture_texture_copy = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + // Destroy the device. This will cause all other requests to return some variation of + // a device invalid error. + ctx.device.destroy(); + + // TODO: verify the following operations will return an invalid device error: + // * Run a compute pass + // * Run a render pass + // * Finish a render bundle encoder + // * Create a texture from HAL + // * Create a buffer from HAL + // * Create a sampler + // * Validate a surface configuration + // * Start capture + // * Stop capture + // * Buffer map + + // TODO: figure out how to structure a test around these operations which panic when + // the device is invalid: + // * device.features() + // * device.limits() + // * device.downlevel_properties() + // * device.create_query_set() + + // TODO: change these fail calls to check for the specific errors which indicate that + // the device is not valid. + + // Creating a commmand encoder should fail. + fail(&ctx.device, || { + ctx.device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + }); + + // Creating a buffer should fail. + fail(&ctx.device, || { + ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + }); + + // Creating a texture should fail. + fail(&ctx.device, || { + ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }, + mip_level_count: 2, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Uint, + usage: wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + }); + + // Texture clear should fail. + fail(&ctx.device, || { + encoder_for_clear.clear_texture( + &texture_for_write, + &wgpu::ImageSubresourceRange { + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + mip_level_count: None, + base_array_layer: 0, + array_layer_count: None, + }, + ); + }); + + // Creating a compute pass should fail. + fail(&ctx.device, || { + encoder_for_compute_pass.begin_compute_pass(&wgpu::ComputePassDescriptor { + label: None, + timestamp_writes: None, + }); + }); + + // Creating a render pass should fail. + fail(&ctx.device, || { + encoder_for_render_pass.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + ops: wgpu::Operations::default(), + resolve_target: None, + view: &target_view, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + }); + + // Copying a buffer to a buffer should fail. + fail(&ctx.device, || { + encoder_for_buffer_buffer_copy.copy_buffer_to_buffer( + &buffer_source, + 0, + &buffer_dest, + 0, + 256, + ); + }); + + // Copying a buffer to a texture should fail. + fail(&ctx.device, || { + encoder_for_buffer_texture_copy.copy_buffer_to_texture( + wgpu::ImageCopyBuffer { + buffer: &buffer_source, + layout: wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(4), + rows_per_image: None, + }, + }, + texture_for_write.as_image_copy(), + texture_extent, + ); + }); + + // Copying a texture to a buffer should fail. + fail(&ctx.device, || { + encoder_for_texture_buffer_copy.copy_texture_to_buffer( + texture_for_read.as_image_copy(), + wgpu::ImageCopyBuffer { + buffer: &buffer_source, + layout: wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(4), + rows_per_image: None, + }, + }, + texture_extent, + ); + }); + + // Copying a texture to a texture should fail. + fail(&ctx.device, || { + encoder_for_texture_texture_copy.copy_texture_to_texture( + texture_for_read.as_image_copy(), + texture_for_write.as_image_copy(), + texture_extent, + ); + }); + + // Creating a bind group layout should fail. + fail(&ctx.device, || { + ctx.device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[], + }); + }); + + // Creating a bind group should fail. + fail(&ctx.device, || { + ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &bind_group_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer( + buffer_source.as_entire_buffer_binding(), + ), + }], + }); + }); + + // Creating a pipeline layout should fail. + fail(&ctx.device, || { + ctx.device + .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + }); + + // Creating a shader module should fail. + fail(&ctx.device, || { + ctx.device + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed("")), + }); + }); + + // Creating a shader module spirv should fail. + fail(&ctx.device, || unsafe { + ctx.device + .create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV { + label: None, + source: std::borrow::Cow::Borrowed(&[]), + }); + }); + + // Creating a render pipeline should fail. + fail(&ctx.device, || { + ctx.device + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + module: &shader_module, + entry_point: "", + buffers: &[], + }, + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + fragment: None, + multiview: None, + }); + }); + + // Creating a compute pipeline should fail. + fail(&ctx.device, || { + ctx.device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &shader_module, + entry_point: "", + }); + }); + }, + ) +} diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index ceceb2ba58..c39d5fbcd9 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -219,6 +219,9 @@ impl Global { } let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(ClearError::InvalidDevice(cmd_buf.device_id.value.0)); + } clear_texture( &*texture_guard, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index c9b20c5a0e..fbb53bdf85 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -16,6 +16,7 @@ use crate::{ hal_api::HalApi, hub::Token, id, + id::DeviceId, identity::GlobalIdentityHandlerFactory, init_tracker::MemoryInitKind, pipeline, @@ -193,6 +194,8 @@ pub enum ComputePassErrorInner { Encoder(#[from] CommandEncoderError), #[error("Bind group {0:?} is invalid")] InvalidBindGroup(id::BindGroupId), + #[error("Device {0:?} is invalid")] + InvalidDevice(DeviceId), #[error("Bind group index {index} is greater than the device's requested `max_bind_group` limit {max}")] BindGroupIndexOutOfRange { index: u32, max: u32 }, #[error("Compute pipeline {0:?} is invalid")] @@ -390,6 +393,12 @@ impl Global { let raw = cmd_buf.encoder.open(); let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(ComputePassErrorInner::InvalidDevice( + cmd_buf.device_id.value.0, + )) + .map_pass_err(init_scope); + } #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index f9202ee3f5..06a9cee1d2 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -18,6 +18,7 @@ use crate::{ hal_api::HalApi, hub::Token, id, + id::DeviceId, identity::GlobalIdentityHandlerFactory, init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction}, pipeline::{self, PipelineFlags}, @@ -523,6 +524,8 @@ pub enum RenderPassErrorInner { ColorAttachment(#[from] ColorAttachmentError), #[error(transparent)] Encoder(#[from] CommandEncoderError), + #[error("Device {0:?} is invalid")] + InvalidDevice(DeviceId), #[error("Attachment texture view {0:?} is invalid")] InvalidAttachment(id::TextureViewId), #[error("The format of the depth-stencil attachment ({0:?}) is not a depth-stencil format")] @@ -1346,6 +1349,12 @@ impl Global { } let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(RenderPassErrorInner::InvalidDevice( + cmd_buf.device_id.value.0, + )) + .map_pass_err(init_scope); + } cmd_buf.encoder.open_pass(base.label); let (bundle_guard, mut token) = hub.render_bundles.read(&mut token); diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 58f88a70e1..10eb80f426 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -8,7 +8,7 @@ use crate::{ global::Global, hal_api::HalApi, hub::Token, - id::{BufferId, CommandEncoderId, TextureId, Valid}, + id::{BufferId, CommandEncoderId, DeviceId, TextureId, Valid}, identity::GlobalIdentityHandlerFactory, init_tracker::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, @@ -40,6 +40,8 @@ pub enum CopySide { #[derive(Clone, Debug, Error)] #[non_exhaustive] pub enum TransferError { + #[error("Device {0:?} is invalid")] + InvalidDevice(DeviceId), #[error("Buffer {0:?} is invalid or destroyed")] InvalidBuffer(BufferId), #[error("Texture {0:?} is invalid or destroyed")] @@ -569,6 +571,9 @@ impl Global { let (buffer_guard, _) = hub.buffers.read(&mut token); let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(TransferError::InvalidDevice(cmd_buf.device_id.value.0).into()); + } #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { @@ -714,6 +719,9 @@ impl Global { let (texture_guard, _) = hub.textures.read(&mut token); let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(TransferError::InvalidDevice(cmd_buf.device_id.value.0).into()); + } #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { @@ -858,6 +866,9 @@ impl Global { let (texture_guard, _) = hub.textures.read(&mut token); let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(TransferError::InvalidDevice(cmd_buf.device_id.value.0).into()); + } #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { @@ -1020,6 +1031,9 @@ impl Global { let (texture_guard, _) = hub.textures.read(&mut token); let device = &device_guard[cmd_buf.device_id.value]; + if !device.is_valid() { + return Err(TransferError::InvalidDevice(cmd_buf.device_id.value.0).into()); + } #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 632c83e37f..eee1f6e054 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -102,6 +102,9 @@ impl Global { let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); let device = device_guard.get(device_id).map_err(|_| InvalidDevice)?; + if !device.valid { + return Err(InvalidDevice); + } Ok(device.features) } @@ -114,6 +117,9 @@ impl Global { let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); let device = device_guard.get(device_id).map_err(|_| InvalidDevice)?; + if !device.valid { + return Err(InvalidDevice); + } Ok(device.limits.clone()) } @@ -126,6 +132,9 @@ impl Global { let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); let device = device_guard.get(device_id).map_err(|_| InvalidDevice)?; + if !device.valid { + return Err(InvalidDevice); + } Ok(device.downlevel.clone()) } @@ -148,6 +157,9 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } if desc.usage.is_empty() { // Per spec, `usage` must not be zero. @@ -586,6 +598,9 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace @@ -641,6 +656,9 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } // NB: Any change done through the raw texture handle will not be // recorded in the replay @@ -717,6 +735,9 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } // NB: Any change done through the raw buffer handle will not be // recorded in the replay @@ -978,6 +999,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace @@ -1056,6 +1081,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace @@ -1170,6 +1199,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace @@ -1249,6 +1282,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace @@ -1351,6 +1388,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { let mut trace = trace.lock(); @@ -1416,6 +1457,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { let mut trace = trace.lock(); @@ -1486,6 +1531,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid, }; + if !device.valid { + break DeviceError::Invalid; + } + let dev_stored = Stored { value: id::Valid(device_id), ref_count: device.life_guard.add_ref(), @@ -1579,6 +1628,10 @@ impl Global { Ok(device) => device, Err(_) => break command::RenderBundleError::INVALID_DEVICE, }; + if !device.valid { + break command::RenderBundleError::INVALID_DEVICE; + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace.lock().add(trace::Action::CreateRenderBundle { @@ -1661,6 +1714,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace.lock().add(trace::Action::CreateQuerySet { @@ -1750,6 +1807,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + let adapter = &adapter_guard[device.adapter_id.value]; #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { @@ -1893,6 +1954,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace.lock().add(trace::Action::CreateComputePipeline { @@ -2141,6 +2206,10 @@ impl Global { Ok(device) => device, Err(_) => break DeviceError::Invalid.into(), }; + if !device.valid { + break DeviceError::Invalid.into(); + } + #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { trace @@ -2405,6 +2474,9 @@ impl Global { let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); if let Ok(device) = device_guard.get(id) { + if !device.valid { + return; + } unsafe { device.raw.start_capture() }; } } @@ -2414,6 +2486,9 @@ impl Global { let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); if let Ok(device) = device_guard.get(id) { + if !device.valid { + return; + } unsafe { device.raw.stop_capture() }; } } @@ -2435,6 +2510,46 @@ impl Global { } } + pub fn device_destroy(&self, device_id: DeviceId) { + let hub = A::hub(self); + let mut token = Token::root(); + + let (mut device_guard, _) = hub.devices.write(&mut token); + if let Ok(device) = device_guard.get_mut(device_id) { + // Follow the steps at + // https://gpuweb.github.io/gpuweb/#dom-gpudevice-destroy. + + // It's legal to call destroy multiple times, but if the device + // is already invalid, there's nothing more to do. There's also + // no need to return an error. + if !device.valid { + return; + } + + // The last part of destroy is to lose the device. The spec says + // delay that until all "currently-enqueued operations on any + // queue on this device are completed." + + // TODO: implement this delay. + + // Finish by losing the device. + + // TODO: associate this "destroyed" reason more tightly with + // the GPUDeviceLostReason defined in webgpu.idl. + device.lose(Some("destroyed")); + } + } + + pub fn device_lose(&self, device_id: DeviceId, reason: Option<&str>) { + let hub = A::hub(self); + let mut token = Token::root(); + + let (mut device_guard, _) = hub.devices.write(&mut token); + if let Ok(device) = device_guard.get_mut(device_id) { + device.lose(reason); + } + } + /// Exit the unreferenced, inactive device `device_id`. fn exit_device(&self, device_id: DeviceId) { let hub = A::hub(self); @@ -2519,6 +2634,11 @@ impl Global { } }; + let device = &device_guard[buffer.device_id.value]; + if !device.valid { + return Err((op, BufferAccessError::Invalid)); + } + if let Err(e) = check_buffer_usage(buffer.usage, pub_usage) { return Err((op, e.into())); } @@ -2559,8 +2679,6 @@ impl Global { }; log::debug!("Buffer {:?} map state -> Waiting", buffer_id); - let device = &device_guard[buffer.device_id.value]; - let ret = (buffer.device_id.value, buffer.life_guard.add_ref()); let mut trackers = device.trackers.lock(); @@ -2573,7 +2691,6 @@ impl Global { }; let device = &device_guard[device_id]; - device .lock_life(&mut token) .map(id::Valid(buffer_id), ref_count); diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 9a77bf9536..3e2a245127 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -292,11 +292,11 @@ pub struct InvalidDevice; #[derive(Clone, Debug, Error)] pub enum DeviceError { - #[error("Parent device is invalid")] + #[error("Parent device is invalid.")] Invalid, #[error("Parent device is lost")] Lost, - #[error("Not enough memory left")] + #[error("Not enough memory left.")] OutOfMemory, #[error("Creation of a resource failed for a reason other than running out of memory.")] ResourceCreationFailed, @@ -305,7 +305,7 @@ pub enum DeviceError { impl From for DeviceError { fn from(error: hal::DeviceError) -> Self { match error { - hal::DeviceError::Lost => DeviceError::Lost, + hal::DeviceError::Lost => DeviceError::Invalid, hal::DeviceError::OutOfMemory => DeviceError::OutOfMemory, hal::DeviceError::ResourceCreationFailed => DeviceError::ResourceCreationFailed, } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 8acc34acf4..8f37f68be9 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -72,6 +72,19 @@ pub struct Device { pub(crate) active_submission_index: SubmissionIndex, pub(super) fence: A::Fence, + /// Is this device valid? Valid is closely associated with "lose the device", + /// which can be triggered by various methods, including at the end of device + /// destroy, and by any GPU errors that cause us to no longer trust the state + /// of the device. Ideally we would like to fold valid into the storage of + /// the device itself (for example as an Error enum), but unfortunately we + /// need to continue to be able to retrieve the device in poll_devices to + /// determine if it can be dropped. If our internal accesses of devices were + /// done through ref-counted references and external accesses checked for + /// Error enums, we wouldn't need this. For now, we need it. All the call + /// sites where we check it are areas that should be revisited if we start + /// using ref-counted references for internal access. + pub(crate) valid: bool, + /// All live resources allocated with this [`Device`]. /// /// Has to be locked temporarily only (locked last) @@ -189,6 +202,7 @@ impl Device { command_allocator: Mutex::new(com_alloc), active_submission_index: 0, fence, + valid: true, trackers: Mutex::new(Tracker::new()), life_tracker: Mutex::new(life::LifetimeTracker::new()), temp_suspected: life::SuspectedResources::default(), @@ -214,6 +228,10 @@ impl Device { }) } + pub fn is_valid(&self) -> bool { + self.valid + } + pub(super) fn lock_life<'this, 'token: 'this>( &'this self, //TODO: fix this - the token has to be borrowed for the lock @@ -3155,6 +3173,27 @@ impl Device { desc: desc.map_label(|_| ()), }) } + + pub(crate) fn lose(&mut self, _reason: Option<&str>) { + // Follow the steps at https://gpuweb.github.io/gpuweb/#lose-the-device. + + // Mark the device explicitly as invalid. This is checked in various + // places to prevent new work from being submitted. + self.valid = false; + + // The following steps remain in "lose the device": + // 1) Resolve the GPUDevice device.lost promise. + + // TODO: triggger this passively or actively, and supply the reason. + + // 2) Complete any outstanding mapAsync() steps. + // 3) Complete any outstanding onSubmittedWorkDone() steps. + + // These parts are passively accomplished by setting valid to false, + // since that will prevent any new work from being added to the queues. + // Future calls to poll_devices will continue to check the work queues + // until they are cleared, and then drop the device. + } } impl Device { diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 7366934d27..9a6d0e32a6 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -138,6 +138,9 @@ impl Global { let (device, config) = match surface.presentation { Some(ref present) => { let device = &device_guard[present.device_id.value]; + if !device.is_valid() { + return Err(DeviceError::Invalid.into()); + } (device, present.config.clone()) } None => return Err(SurfaceError::NotConfigured), @@ -290,6 +293,9 @@ impl Global { }; let device = &mut device_guard[present.device_id.value]; + if !device.is_valid() { + return Err(DeviceError::Invalid.into()); + } #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { @@ -376,6 +382,9 @@ impl Global { }; let device = &mut device_guard[present.device_id.value]; + if !device.is_valid() { + return Err(DeviceError::Invalid.into()); + } #[cfg(feature = "trace")] if let Some(ref trace) = device.trace { diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 3d3028d334..e8776f881a 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1439,6 +1439,15 @@ impl crate::Context for Context { wgc::gfx_select!(device => global.device_drop(*device)); } + fn device_destroy(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { + let global = &self.0; + wgc::gfx_select!(device => global.device_destroy(*device)); + } + fn device_lose(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { + // TODO: accept a reason, and pass it to device_lose. + let global = &self.0; + wgc::gfx_select!(device => global.device_lose(*device, None)); + } fn device_poll( &self, device: &Self::DeviceId, diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index b649d41ebb..3868a01fcd 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1914,6 +1914,16 @@ impl crate::context::Context for Context { // Device is dropped automatically } + fn device_destroy(&self, _buffer: &Self::DeviceId, device_data: &Self::DeviceData) { + device_data.0.destroy(); + } + + fn device_lose(&self, _device: &Self::DeviceId, _device_data: &Self::DeviceData) { + // TODO: figure out the GPUDevice implementation of this, including resolving + // the device.lost promise, which will require a different invocation pattern + // with a callback. + } + fn device_poll( &self, _device: &Self::DeviceId, diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 9d0bdd9100..bfcd4ae2ec 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -269,6 +269,8 @@ pub trait Context: Debug + WasmNotSend + WasmNotSync + Sized { desc: &RenderBundleEncoderDescriptor, ) -> (Self::RenderBundleEncoderId, Self::RenderBundleEncoderData); fn device_drop(&self, device: &Self::DeviceId, device_data: &Self::DeviceData); + fn device_destroy(&self, device: &Self::DeviceId, device_data: &Self::DeviceData); + fn device_lose(&self, device: &Self::DeviceId, device_data: &Self::DeviceData); fn device_poll( &self, device: &Self::DeviceId, @@ -1363,6 +1365,8 @@ pub(crate) trait DynContext: Debug + WasmNotSend + WasmNotSync { desc: &RenderBundleEncoderDescriptor, ) -> (ObjectId, Box); fn device_drop(&self, device: &ObjectId, device_data: &crate::Data); + fn device_destroy(&self, device: &ObjectId, device_data: &crate::Data); + fn device_lose(&self, device: &ObjectId, device_data: &crate::Data); fn device_poll(&self, device: &ObjectId, device_data: &crate::Data, maintain: Maintain) -> bool; fn device_on_uncaptured_error( @@ -2424,6 +2428,18 @@ where Context::device_drop(self, &device, device_data) } + fn device_destroy(&self, device: &ObjectId, device_data: &crate::Data) { + let device = ::from(*device); + let device_data = downcast_ref(device_data); + Context::device_destroy(self, &device, device_data) + } + + fn device_lose(&self, device: &ObjectId, device_data: &crate::Data) { + let device = ::from(*device); + let device_data = downcast_ref(device_data); + Context::device_lose(self, &device, device_data) + } + fn device_poll( &self, device: &ObjectId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index f62e14bcae..f5323a6e34 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2767,6 +2767,11 @@ impl Device { ) } } + + /// Destroy this device. + pub fn destroy(&self) { + DynContext::device_destroy(&*self.context, &self.id, self.data.as_ref()) + } } impl Drop for Device { From caad255737fc68c53ac1108b69acc2de27b3851d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 02:40:41 -0400 Subject: [PATCH 18/19] Bump winit from 0.28.6 to 0.28.7 (#4181) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 42 +++++++++++++++++++++--------------------- Cargo.toml | 2 +- wgpu-hal/Cargo.toml | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48d4cefb05..f3b3489a5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2050,7 +2050,7 @@ dependencies = [ "serde", "wgpu-core", "wgpu-types", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3143,7 +3143,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3158,7 +3158,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3176,7 +3176,7 @@ dependencies = [ "wasm-bindgen-test", "wgpu", "wgpu-example", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3187,7 +3187,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3223,7 +3223,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3244,7 +3244,7 @@ dependencies = [ "wgpu", "wgpu-hal", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3287,7 +3287,7 @@ dependencies = [ "web-sys", "wgpu-types", "winapi", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3305,7 +3305,7 @@ dependencies = [ "wasm-bindgen-test", "wgpu", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3335,7 +3335,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "wgpu", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3347,7 +3347,7 @@ dependencies = [ "env_logger", "pollster", "wgpu", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3374,7 +3374,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3388,7 +3388,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3401,7 +3401,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3417,7 +3417,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3429,7 +3429,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3467,7 +3467,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3485,7 +3485,7 @@ dependencies = [ "wasm-bindgen-test", "wgpu", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3511,7 +3511,7 @@ dependencies = [ "wgpu", "wgpu-example", "wgpu-test", - "winit 0.28.6", + "winit 0.28.7", ] [[package]] @@ -3781,9 +3781,9 @@ dependencies = [ [[package]] name = "winit" -version = "0.28.6" +version = "0.28.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866db3f712fffba75d31bf0cdecf357c8aeafd158c5b7ab51dba2a2b2d47f196" +checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" dependencies = [ "android-activity", "bitflags 1.3.2", diff --git a/Cargo.toml b/Cargo.toml index 63e7ff9a8f..8794c68e11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,7 +98,7 @@ wgpu-core = { version = "0.17.0", path = "./wgpu-core" } wgpu-example = { version = "0.17.0", path = "./examples/common" } wgpu-test = { version = "0.17", path = "./tests"} wgpu-types = { version = "0.17.0", path = "./wgpu-types" } -winit = { version = "0.28.6", features = [ "android-native-activity" ] } +winit = { version = "0.28.7", features = [ "android-native-activity" ] } # Vulkan dependencies ash = "0.37.3" diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 3cc69975cc..18e63b3d4e 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -134,7 +134,7 @@ features = ["wgsl-in"] [dev-dependencies] cfg-if = "1" env_logger = "0.10" -winit = { version = "0.28.6", features = [ "android-native-activity" ] } # for "halmark" example +winit = { version = "0.28.7", features = [ "android-native-activity" ] } # for "halmark" example [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] glutin = "0.29.1" # for "gles" example From 9a76c483da4891fb7046c579e36d7c54bdb0b251 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 28 Sep 2023 18:29:44 +0200 Subject: [PATCH 19/19] Add trace level logging to most API entry points (#4183) * Add trace level logging to most API entry points * Add a changelog entry --- CHANGELOG.md | 1 + wgpu-core/src/command/clear.rs | 4 +- wgpu-core/src/command/mod.rs | 3 + wgpu-core/src/command/render.rs | 36 +++++++++++- wgpu-core/src/device/global.rs | 98 ++++++++++++++++++++++++--------- wgpu-core/src/device/queue.rs | 3 + wgpu-core/src/instance.rs | 8 +++ 7 files changed, 125 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f59fc35dc8..7537cb8ae6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ By @wumpf in [#4147](https://github.com/gfx-rs/wgpu/pull/4147) - Make `WGPU_POWER_PREF=none` a valid value. By @fornwall in [4076](https://github.com/gfx-rs/wgpu/pull/4076) - Support dual source blending in OpenGL ES, Metal, Vulkan & DX12. By @freqmod in [4022](https://github.com/gfx-rs/wgpu/pull/4022) - Add stub support for device destroy and device validity. By @bradwerth in [4163](https://github.com/gfx-rs/wgpu/pull/4163) +- Add trace-level logging for most entry points in wgpu-core By @nical in [4183](https://github.com/gfx-rs/wgpu/pull/4183) #### Vulkan diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index c39d5fbcd9..1481dbe1e6 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -79,7 +79,8 @@ impl Global { offset: BufferAddress, size: Option, ) -> Result<(), ClearError> { - profiling::scope!("CommandEncoder::fill_buffer"); + profiling::scope!("CommandEncoder::clear_buffer"); + log::trace!("CommandEncoder::clear_buffer {dst:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -158,6 +159,7 @@ impl Global { subresource_range: &ImageSubresourceRange, ) -> Result<(), ClearError> { profiling::scope!("CommandEncoder::clear_texture"); + log::trace!("CommandEncoder::clear_texture {dst:?}"); let hub = A::hub(self); let mut token = Token::root(); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index d97d4b41e3..8bb975a112 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -391,6 +391,7 @@ impl Global { label: &str, ) -> Result<(), CommandEncoderError> { profiling::scope!("CommandEncoder::push_debug_group"); + log::trace!("CommandEncoder::push_debug_group {label}"); let hub = A::hub(self); let mut token = Token::root(); @@ -416,6 +417,7 @@ impl Global { label: &str, ) -> Result<(), CommandEncoderError> { profiling::scope!("CommandEncoder::insert_debug_marker"); + log::trace!("CommandEncoder::insert_debug_marker {label}"); let hub = A::hub(self); let mut token = Token::root(); @@ -440,6 +442,7 @@ impl Global { encoder_id: id::CommandEncoderId, ) -> Result<(), CommandEncoderError> { profiling::scope!("CommandEncoder::pop_debug_marker"); + log::trace!("CommandEncoder::pop_debug_group"); let hub = A::hub(self); let mut token = Token::root(); diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 06a9cee1d2..9e2c533893 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -2393,6 +2393,7 @@ pub mod render_ffi { pass: &mut RenderPass, pipeline_id: id::RenderPipelineId, ) { + log::trace!("RenderPass::set_pipeline {pipeline_id:?}"); if pass.current_pipeline.set_and_check_redundant(pipeline_id) { return; } @@ -2410,6 +2411,7 @@ pub mod render_ffi { offset: BufferAddress, size: Option, ) { + log::trace!("RenderPass::set_vertex_buffer {buffer_id:?}"); pass.base.commands.push(RenderCommand::SetVertexBuffer { slot, buffer_id, @@ -2426,11 +2428,13 @@ pub mod render_ffi { offset: BufferAddress, size: Option, ) { + log::trace!("RenderPass::set_index_buffer {buffer:?}"); pass.set_index_buffer(buffer, index_format, offset, size); } #[no_mangle] pub extern "C" fn wgpu_render_pass_set_blend_constant(pass: &mut RenderPass, color: &Color) { + log::trace!("RenderPass::set_blend_constant"); pass.base .commands .push(RenderCommand::SetBlendConstant(*color)); @@ -2438,6 +2442,7 @@ pub mod render_ffi { #[no_mangle] pub extern "C" fn wgpu_render_pass_set_stencil_reference(pass: &mut RenderPass, value: u32) { + log::trace!("RenderPass::set_stencil_reference {value}"); pass.base .commands .push(RenderCommand::SetStencilReference(value)); @@ -2453,6 +2458,7 @@ pub mod render_ffi { depth_min: f32, depth_max: f32, ) { + log::trace!("RenderPass::set_viewport {x} {y} {w} {h}"); pass.base.commands.push(RenderCommand::SetViewport { rect: Rect { x, y, w, h }, depth_min, @@ -2468,6 +2474,7 @@ pub mod render_ffi { w: u32, h: u32, ) { + log::trace!("RenderPass::set_scissor_rect {x} {y} {w} {h}"); pass.base .commands .push(RenderCommand::SetScissor(Rect { x, y, w, h })); @@ -2485,6 +2492,7 @@ pub mod render_ffi { size_bytes: u32, data: *const u8, ) { + log::trace!("RenderPass::set_push_constants"); assert_eq!( offset & (wgt::PUSH_CONSTANT_ALIGNMENT - 1), 0, @@ -2522,6 +2530,10 @@ pub mod render_ffi { first_vertex: u32, first_instance: u32, ) { + log::trace!( + "RenderPass::draw {vertex_count} {instance_count} {first_vertex} {first_instance}" + ); + pass.base.commands.push(RenderCommand::Draw { vertex_count, instance_count, @@ -2539,6 +2551,7 @@ pub mod render_ffi { base_vertex: i32, first_instance: u32, ) { + log::trace!("RenderPass::draw_indexed {index_count} {instance_count} {first_index} {base_vertex} {first_instance}"); pass.base.commands.push(RenderCommand::DrawIndexed { index_count, instance_count, @@ -2554,6 +2567,7 @@ pub mod render_ffi { buffer_id: id::BufferId, offset: BufferAddress, ) { + log::trace!("RenderPass::draw_indirect {buffer_id:?} {offset}"); pass.base.commands.push(RenderCommand::MultiDrawIndirect { buffer_id, offset, @@ -2568,6 +2582,7 @@ pub mod render_ffi { buffer_id: id::BufferId, offset: BufferAddress, ) { + log::trace!("RenderPass::draw_indexed_indirect {buffer_id:?} {offset}"); pass.base.commands.push(RenderCommand::MultiDrawIndirect { buffer_id, offset, @@ -2583,6 +2598,7 @@ pub mod render_ffi { offset: BufferAddress, count: u32, ) { + log::trace!("RenderPass::multi_draw_indirect {buffer_id:?} {offset} {count}"); pass.base.commands.push(RenderCommand::MultiDrawIndirect { buffer_id, offset, @@ -2598,6 +2614,7 @@ pub mod render_ffi { offset: BufferAddress, count: u32, ) { + log::trace!("RenderPass::multi_draw_indexed_indirect {buffer_id:?} {offset} {count}"); pass.base.commands.push(RenderCommand::MultiDrawIndirect { buffer_id, offset, @@ -2615,6 +2632,7 @@ pub mod render_ffi { count_buffer_offset: BufferAddress, max_count: u32, ) { + log::trace!("RenderPass::multi_draw_indirect_count {buffer_id:?} {offset} {count_buffer_id:?} {count_buffer_offset} {max_count}"); pass.base .commands .push(RenderCommand::MultiDrawIndirectCount { @@ -2636,6 +2654,7 @@ pub mod render_ffi { count_buffer_offset: BufferAddress, max_count: u32, ) { + log::trace!("RenderPass::multi_draw_indexed_indirect_count {buffer_id:?} {offset} {count_buffer_id:?} {count_buffer_offset} {max_count}"); pass.base .commands .push(RenderCommand::MultiDrawIndirectCount { @@ -2658,7 +2677,10 @@ pub mod render_ffi { label: RawString, color: u32, ) { - let bytes = unsafe { ffi::CStr::from_ptr(label) }.to_bytes(); + let cstr = unsafe { ffi::CStr::from_ptr(label) }; + log::trace!("RenderPass::push_debug_group {cstr:?}"); + + let bytes = cstr.to_bytes(); pass.base.string_data.extend_from_slice(bytes); pass.base.commands.push(RenderCommand::PushDebugGroup { @@ -2669,6 +2691,7 @@ pub mod render_ffi { #[no_mangle] pub extern "C" fn wgpu_render_pass_pop_debug_group(pass: &mut RenderPass) { + log::trace!("RenderPass::pop_debug_group"); pass.base.commands.push(RenderCommand::PopDebugGroup); } @@ -2682,7 +2705,10 @@ pub mod render_ffi { label: RawString, color: u32, ) { - let bytes = unsafe { ffi::CStr::from_ptr(label) }.to_bytes(); + let cstr = unsafe { ffi::CStr::from_ptr(label) }; + log::trace!("RenderPass::insert_debug_marker {cstr:?}"); + + let bytes = cstr.to_bytes(); pass.base.string_data.extend_from_slice(bytes); pass.base.commands.push(RenderCommand::InsertDebugMarker { @@ -2697,6 +2723,7 @@ pub mod render_ffi { query_set_id: id::QuerySetId, query_index: u32, ) { + log::trace!("RenderPass::write_timestamps {query_set_id:?} {query_index}"); pass.base.commands.push(RenderCommand::WriteTimestamp { query_set_id, query_index, @@ -2708,6 +2735,7 @@ pub mod render_ffi { pass: &mut RenderPass, query_index: u32, ) { + log::trace!("RenderPass::begin_occlusion_query {query_index}"); pass.base .commands .push(RenderCommand::BeginOcclusionQuery { query_index }); @@ -2715,6 +2743,7 @@ pub mod render_ffi { #[no_mangle] pub extern "C" fn wgpu_render_pass_end_occlusion_query(pass: &mut RenderPass) { + log::trace!("RenderPass::end_occlusion_query"); pass.base.commands.push(RenderCommand::EndOcclusionQuery); } @@ -2724,6 +2753,7 @@ pub mod render_ffi { query_set_id: id::QuerySetId, query_index: u32, ) { + log::trace!("RenderPass::begin_pipeline_statistics_query {query_set_id:?} {query_index}"); pass.base .commands .push(RenderCommand::BeginPipelineStatisticsQuery { @@ -2734,6 +2764,7 @@ pub mod render_ffi { #[no_mangle] pub extern "C" fn wgpu_render_pass_end_pipeline_statistics_query(pass: &mut RenderPass) { + log::trace!("RenderPass::end_pipeline_statistics_query"); pass.base .commands .push(RenderCommand::EndPipelineStatisticsQuery); @@ -2749,6 +2780,7 @@ pub mod render_ffi { render_bundle_ids: *const id::RenderBundleId, render_bundle_ids_length: usize, ) { + log::trace!("RenderPass::execute_bundles"); for &bundle_id in unsafe { slice::from_raw_parts(render_bundle_ids, render_bundle_ids_length) } { diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index eee1f6e054..50ef913295 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -262,7 +262,7 @@ impl Global { }; let id = fid.assign(buffer, &mut token); - log::info!("Created buffer {:?} with {:?}", id, desc); + log::trace!("Device::create_buffer -> {:?}", id); device .trackers @@ -482,7 +482,7 @@ impl Global { //TODO: lock pending writes separately, keep the device read-only let (mut device_guard, mut token) = hub.devices.write(&mut token); - log::info!("Buffer {:?} is destroyed", buffer_id); + log::trace!("Buffer::destroy {buffer_id:?}"); let (mut buffer_guard, _) = hub.buffers.write(&mut token); let buffer = buffer_guard .get_mut(buffer_id) @@ -533,7 +533,7 @@ impl Global { pub fn buffer_drop(&self, buffer_id: id::BufferId, wait: bool) { profiling::scope!("Buffer::drop"); - log::debug!("buffer {:?} is dropped", buffer_id); + log::trace!("Buffer::drop {buffer_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -616,7 +616,7 @@ impl Global { let ref_count = texture.life_guard.add_ref(); let id = fid.assign(texture, &mut token); - log::info!("Created texture {:?} with {:?}", id, desc); + log::trace!("Device::create_texture -> {id:?}"); device.trackers.lock().textures.insert_single( id.0, @@ -643,7 +643,7 @@ impl Global { desc: &resource::TextureDescriptor, id_in: Input, ) -> (id::TextureId, Option) { - profiling::scope!("Device::create_texture"); + profiling::scope!("Device::create_texture_from_hal"); let hub = A::hub(self); let mut token = Token::root(); @@ -696,7 +696,7 @@ impl Global { let ref_count = texture.life_guard.add_ref(); let id = fid.assign(texture, &mut token); - log::info!("Created texture {:?} with {:?}", id, desc); + log::trace!("Device::create_texture -> {id:?}"); device.trackers.lock().textures.insert_single( id.0, @@ -756,7 +756,7 @@ impl Global { let ref_count = buffer.life_guard.add_ref(); let id = fid.assign(buffer, &mut token); - log::info!("Created buffer {:?} with {:?}", id, desc); + log::trace!("Device::create_buffer -> {id:?}"); device .trackers @@ -780,6 +780,7 @@ impl Global { texture_id: id::TextureId, ) -> Result<(), resource::DestroyError> { profiling::scope!("Texture::destroy"); + log::trace!("Texture::destroy {texture_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -787,7 +788,6 @@ impl Global { //TODO: lock pending writes separately, keep the device read-only let (mut device_guard, mut token) = hub.devices.write(&mut token); - log::info!("Buffer {:?} is destroyed", texture_id); let (mut texture_guard, _) = hub.textures.write(&mut token); let texture = texture_guard .get_mut(texture_id) @@ -837,7 +837,7 @@ impl Global { pub fn texture_drop(&self, texture_id: id::TextureId, wait: bool) { profiling::scope!("Texture::drop"); - log::debug!("texture {:?} is dropped", texture_id); + log::trace!("Texture::drop {texture_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -921,9 +921,14 @@ impl Global { let id = fid.assign(view, &mut token); device.trackers.lock().views.insert_single(id, ref_count); + + log::trace!("Texture::create_view {:?} -> {:?}", texture_id, id.0); + return (id.0, None); }; + log::error!("Texture::create_view {:?} error {:?}", texture_id, error); + let id = fid.assign_error(desc.label.borrow_or_default(), &mut token); (id, Some(error)) } @@ -938,7 +943,7 @@ impl Global { wait: bool, ) -> Result<(), resource::TextureViewDestroyError> { profiling::scope!("TextureView::drop"); - log::debug!("texture view {:?} is dropped", texture_view_id); + log::trace!("TextureView::drop {:?}", texture_view_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1019,6 +1024,8 @@ impl Global { device.trackers.lock().samplers.insert_single(id, ref_count); + log::trace!("Device::create_sampler -> {:?}", id.0); + return (id.0, None); }; @@ -1032,7 +1039,7 @@ impl Global { pub fn sampler_drop(&self, sampler_id: id::SamplerId) { profiling::scope!("Sampler::drop"); - log::debug!("sampler {:?} is dropped", sampler_id); + log::trace!("Sampler::drop {sampler_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -1121,6 +1128,7 @@ impl Global { // the branch and instead rely on the indirection to use the // proper bind group layout id. if G::ids_are_generated_in_wgpu() { + log::trace!("Device::create_bind_group_layout (duplicate of {id:?})"); return (id, None); } @@ -1141,6 +1149,15 @@ impl Global { let id = fid.assign(layout, &mut token); + if let Some(dupe) = compatible_layout { + log::trace!( + "Device::create_bind_group_layout (duplicate of {dupe:?}) -> {:?}", + id.0 + ); + } else { + log::trace!("Device::create_bind_group_layout -> {:?}", id.0); + } + return (id.0, None); }; @@ -1154,7 +1171,7 @@ impl Global { pub fn bind_group_layout_drop(&self, bind_group_layout_id: id::BindGroupLayoutId) { profiling::scope!("BindGroupLayout::drop"); - log::debug!("bind group layout {:?} is dropped", bind_group_layout_id); + log::trace!("BindGroupLayout::drop {:?}", bind_group_layout_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1219,6 +1236,9 @@ impl Global { }; let id = fid.assign(layout, &mut token); + + log::trace!("Device::create_pipeline_layout -> {:?}", id.0); + return (id.0, None); }; @@ -1232,7 +1252,7 @@ impl Global { pub fn pipeline_layout_drop(&self, pipeline_layout_id: id::PipelineLayoutId) { profiling::scope!("PipelineLayout::drop"); - log::debug!("pipeline layout {:?} is dropped", pipeline_layout_id); + log::trace!("PipelineLayout::drop {:?}", pipeline_layout_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1318,7 +1338,8 @@ impl Global { let ref_count = bind_group.life_guard.add_ref(); let id = fid.assign(bind_group, &mut token); - log::debug!("Bind group {:?}", id,); + + log::trace!("Device::create_bind_group -> {:?}", id.0); device .trackers @@ -1338,7 +1359,7 @@ impl Global { pub fn bind_group_drop(&self, bind_group_id: id::BindGroupId) { profiling::scope!("BindGroup::drop"); - log::debug!("bind group {:?} is dropped", bind_group_id); + log::trace!("BindGroup::drop {:?}", bind_group_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1422,6 +1443,9 @@ impl Global { Err(e) => break e, }; let id = fid.assign(shader, &mut token); + + log::trace!("Device::create_shader_module -> {:?}", id.0); + return (id.0, None); }; @@ -1493,7 +1517,7 @@ impl Global { pub fn shader_module_drop(&self, shader_module_id: id::ShaderModuleId) { profiling::scope!("ShaderModule::drop"); - log::debug!("shader module {:?} is dropped", shader_module_id); + log::trace!("ShaderModule::drop {:?}", shader_module_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1559,6 +1583,9 @@ impl Global { ); let id = fid.assign(command_buffer, &mut token); + + log::trace!("Device::create_command_encoder -> {:?}", id.0); + return (id.0, None); }; @@ -1572,7 +1599,7 @@ impl Global { pub fn command_encoder_drop(&self, command_encoder_id: id::CommandEncoderId) { profiling::scope!("CommandEncoder::drop"); - log::debug!("command encoder {:?} is dropped", command_encoder_id); + log::trace!("CommandEncoder::drop {:?}", command_encoder_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1590,7 +1617,7 @@ impl Global { pub fn command_buffer_drop(&self, command_buffer_id: id::CommandBufferId) { profiling::scope!("CommandBuffer::drop"); - log::debug!("command buffer {:?} is dropped", command_buffer_id); + log::trace!("CommandBuffer::drop {:?}", command_buffer_id); self.command_encoder_drop::(command_buffer_id) } @@ -1603,6 +1630,7 @@ impl Global { Option, ) { profiling::scope!("Device::create_render_bundle_encoder"); + log::trace!("Device::device_create_render_bundle_encoder"); let (encoder, error) = match command::RenderBundleEncoder::new(desc, device_id, None) { Ok(encoder) => (encoder, None), Err(e) => (command::RenderBundleEncoder::dummy(device_id), Some(e)), @@ -1656,6 +1684,9 @@ impl Global { let id = fid.assign(render_bundle, &mut token); device.trackers.lock().bundles.insert_single(id, ref_count); + + log::trace!("RenderBundleEncoder::finish -> {:?}", id.0); + return (id.0, None); }; @@ -1669,7 +1700,7 @@ impl Global { pub fn render_bundle_drop(&self, render_bundle_id: id::RenderBundleId) { profiling::scope!("RenderBundle::drop"); - log::debug!("render bundle {:?} is dropped", render_bundle_id); + log::trace!("RenderBundle::drop {:?}", render_bundle_id); let hub = A::hub(self); let mut token = Token::root(); @@ -1744,12 +1775,15 @@ impl Global { }; let id = fid.assign_error("", &mut token); + + log::trace!("Device::create_query_set -> {:?}", id); + (id, Some(error)) } pub fn query_set_drop(&self, query_set_id: id::QuerySetId) { profiling::scope!("QuerySet::drop"); - log::debug!("query set {:?} is dropped", query_set_id); + log::trace!("QuerySet::drop {query_set_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -1835,7 +1869,7 @@ impl Global { let ref_count = pipeline.life_guard.add_ref(); let id = fid.assign(pipeline, &mut token); - log::info!("Created render pipeline {:?} with {:?}", id, desc); + log::trace!("Device::create_render_pipeline -> {id:?}"); device .trackers @@ -1899,7 +1933,7 @@ impl Global { pub fn render_pipeline_drop(&self, render_pipeline_id: id::RenderPipelineId) { profiling::scope!("RenderPipeline::drop"); - log::debug!("render pipeline {:?} is dropped", render_pipeline_id); + log::trace!("RenderPipeline::drop {:?}", render_pipeline_id); let hub = A::hub(self); let mut token = Token::root(); let (device_guard, mut token) = hub.devices.read(&mut token); @@ -1980,7 +2014,7 @@ impl Global { let ref_count = pipeline.life_guard.add_ref(); let id = fid.assign(pipeline, &mut token); - log::info!("Created compute pipeline {:?} with {:?}", id, desc); + log::trace!("Device::create_compute_pipeline -> {id:?}"); device .trackers @@ -2043,7 +2077,7 @@ impl Global { pub fn compute_pipeline_drop(&self, compute_pipeline_id: id::ComputePipelineId) { profiling::scope!("ComputePipeline::drop"); - log::debug!("compute pipeline {:?} is dropped", compute_pipeline_id); + log::trace!("ComputePipeline::drop {:?}", compute_pipeline_id); let hub = A::hub(self); let mut token = Token::root(); let (device_guard, mut token) = hub.devices.read(&mut token); @@ -2355,6 +2389,8 @@ impl Global { device_id: DeviceId, maintain: wgt::Maintain, ) -> Result { + log::trace!("Device::poll"); + let (closures, queue_empty) = { if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain { if submission_index.queue_id != device_id { @@ -2470,6 +2506,8 @@ impl Global { } pub fn device_start_capture(&self, id: DeviceId) { + log::trace!("Device::start_capture"); + let hub = A::hub(self); let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); @@ -2482,6 +2520,8 @@ impl Global { } pub fn device_stop_capture(&self, id: DeviceId) { + log::trace!("Device::stop_capture"); + let hub = A::hub(self); let mut token = Token::root(); let (device_guard, _) = hub.devices.read(&mut token); @@ -2495,7 +2535,7 @@ impl Global { pub fn device_drop(&self, device_id: DeviceId) { profiling::scope!("Device::drop"); - log::debug!("device {:?} is dropped", device_id); + log::trace!("Device::drop {device_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -2511,6 +2551,8 @@ impl Global { } pub fn device_destroy(&self, device_id: DeviceId) { + log::trace!("Device::destroy {device_id:?}"); + let hub = A::hub(self); let mut token = Token::root(); @@ -2541,6 +2583,8 @@ impl Global { } pub fn device_lose(&self, device_id: DeviceId, reason: Option<&str>) { + log::trace!("Device::lose {device_id:?}"); + let hub = A::hub(self); let mut token = Token::root(); @@ -2587,6 +2631,8 @@ impl Global { range: Range, op: BufferMapOperation, ) -> BufferAccessResult { + log::trace!("Buffer::map_async {buffer_id:?}"); + // User callbacks must not be called while holding buffer_map_async_inner's locks, so we // defer the error callback if it needs to be called immediately (typically when running // into errors). @@ -2705,6 +2751,7 @@ impl Global { size: Option, ) -> Result<(*mut u8, u64), BufferAccessError> { profiling::scope!("Buffer::get_mapped_range"); + log::trace!("Buffer::get_mapped_range {buffer_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -2865,6 +2912,7 @@ impl Global { pub fn buffer_unmap(&self, buffer_id: id::BufferId) -> BufferAccessResult { profiling::scope!("unmap", "Buffer"); + log::trace!("Buffer::unmap {buffer_id:?}"); let closure; { diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 73fa5de3b0..089f4ff717 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1051,6 +1051,7 @@ impl Global { command_buffer_ids: &[id::CommandBufferId], ) -> Result { profiling::scope!("Queue::submit"); + log::trace!("Queue::submit {queue_id:?}"); let (submit_index, callbacks) = { let hub = A::hub(self); @@ -1434,6 +1435,8 @@ impl Global { queue_id: id::QueueId, closure: SubmittedWorkDoneClosure, ) -> Result<(), InvalidQueue> { + log::trace!("Queue::on_submitted_work_done {queue_id:?}"); + //TODO: flush pending writes let hub = A::hub(self); let mut token = Token::root(); diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 0aee56ac6e..9fc198373d 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -302,6 +302,8 @@ impl Adapter { desc: &DeviceDescriptor, trace_path: Option<&std::path::Path>, ) -> Result, RequestDeviceError> { + log::trace!("Adapter::create_device"); + let caps = &self.raw.capabilities; Device::new( open, @@ -656,6 +658,8 @@ impl Global { pub fn surface_drop(&self, id: SurfaceId) { profiling::scope!("Surface::drop"); + log::trace!("Surface::drop {id:?}"); + let mut token = Token::root(); let (surface, _) = self.surfaces.unregister(id, &mut token); let mut surface = surface.unwrap(); @@ -722,6 +726,7 @@ impl Global { pub fn enumerate_adapters(&self, inputs: AdapterInputs>) -> Vec { profiling::scope!("Instance::enumerate_adapters"); + log::trace!("Instance::enumerate_adapters"); let mut adapters = Vec::new(); @@ -779,6 +784,7 @@ impl Global { inputs: AdapterInputs>, ) -> Result { profiling::scope!("Instance::pick_adapter"); + log::trace!("Instance::pick_adapter"); fn gather( _: A, @@ -1060,6 +1066,7 @@ impl Global { pub fn adapter_drop(&self, adapter_id: AdapterId) { profiling::scope!("Adapter::drop"); + log::trace!("Adapter::drop {adapter_id:?}"); let hub = A::hub(self); let mut token = Token::root(); @@ -1085,6 +1092,7 @@ impl Global { id_in: Input, ) -> (DeviceId, Option) { profiling::scope!("Adapter::request_device"); + log::trace!("Adapter::request_device"); let hub = A::hub(self); let mut token = Token::root();