From ac36a6867fb0dea9d92a030ac81bb3cbae088aa2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Oct 2022 12:23:07 +0300 Subject: [PATCH 1/6] Added support for MSAA(x2,x8) beyond WEBGPU restrictions for native adapters (D3D12 , Vulkan , Metal) --- wgpu-core/src/command/render.rs | 3 --- wgpu-core/src/device/mod.rs | 9 +++++++ wgpu-core/src/instance.rs | 2 ++ wgpu-core/src/present.rs | 1 + wgpu-core/src/resource.rs | 2 ++ wgpu-hal/src/dx11/adapter.rs | 7 +++++ wgpu-hal/src/dx12/adapter.rs | 41 ++++++++++++++++++++++++++++ wgpu-hal/src/empty.rs | 7 +++++ wgpu-hal/src/gles/adapter.rs | 8 +++++- wgpu-hal/src/lib.rs | 6 +++++ wgpu-hal/src/metal/adapter.rs | 15 ++++++++--- wgpu-hal/src/metal/mod.rs | 2 +- wgpu-hal/src/vulkan/adapter.rs | 47 +++++++++++++++++++++++++++++++++ wgpu-info/src/main.rs | 19 ++++++++++++- wgpu-types/src/lib.rs | 21 +++++++++++++++ wgpu/examples/msaa-line/main.rs | 29 +++++++++++++++++--- wgpu/src/lib.rs | 9 ++++--- 17 files changed, 212 insertions(+), 16 deletions(-) diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 1b434956b5..41287c9761 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -732,9 +732,6 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> { expected: sample_count, }); } - if sample_count != 1 && sample_count != 4 { - return Err(RenderPassErrorInner::InvalidSampleCount(sample_count)); - } attachment_type_name = type_name; Ok(()) }; diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 57c6b943fc..5b5fab4034 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -806,6 +806,15 @@ impl Device { { return Err(CreateTextureError::InvalidMultisampledFormat(desc.format)); } + + match wgt::TextureFormatSampleCountFlags::from_bits(desc.sample_count as u8) { + Some(sample_count) => { + if !format_features.sample_count.contains(sample_count) { + return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); + } + } + None => return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)), + } } let mips = desc.mip_level_count; diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index c90f6cab18..ad9ea88f55 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -230,6 +230,7 @@ impl Adapter { use hal::TextureFormatCapabilities as Tfc; let caps = unsafe { self.raw.adapter.texture_format_capabilities(format) }; + let sample_count = unsafe { self.raw.adapter.texture_format_sample_count(format) }; let mut allowed_usages = wgt::TextureUsages::empty(); allowed_usages.set(wgt::TextureUsages::COPY_SRC, caps.contains(Tfc::COPY_SRC)); @@ -279,6 +280,7 @@ impl Adapter { wgt::TextureFormatFeatures { allowed_usages, flags, + sample_count, } } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 21047199ad..785cbff877 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -186,6 +186,7 @@ impl Global { allowed_usages: wgt::TextureUsages::RENDER_ATTACHMENT, flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE | wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE, + sample_count: wgt::TextureFormatSampleCountFlags::_1, }, initialization_status: TextureInitTracker::new(1, 1), full_range: track::TextureSelector { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index e106188543..66a11ecfd6 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -515,6 +515,8 @@ pub enum CreateTextureError { MultisampledNotRenderAttachment, #[error("Texture format {0:?} can't be used due to missing features.")] MissingFeatures(wgt::TextureFormat, #[source] MissingFeatures), + #[error("Sample count {0} is invalid")] + InvalidSampleCount(u32), } impl Resource for Texture { diff --git a/wgpu-hal/src/dx11/adapter.rs b/wgpu-hal/src/dx11/adapter.rs index 9ea3243ab8..993b54e4e5 100644 --- a/wgpu-hal/src/dx11/adapter.rs +++ b/wgpu-hal/src/dx11/adapter.rs @@ -18,6 +18,13 @@ impl crate::Adapter for super::Adapter { todo!() } + unsafe fn texture_format_sample_count( + &self, + format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags { + todo!() + } + unsafe fn surface_capabilities( &self, surface: &super::Surface, diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index edbda11d2f..f82d4585e3 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -456,6 +456,47 @@ impl crate::Adapter for super::Adapter { caps } + #[allow(trivial_casts)] + unsafe fn texture_format_sample_count( + &self, + format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags { + use wgt::TextureFormatSampleCountFlags as Tfsc; + + let raw_format = match auxil::dxgi::conv::map_texture_format_failable(format) { + Some(f) => f, + None => return Tfsc::empty(), + }; + + let mut flags = Tfsc::empty(); + + let mut ms_levels = d3d12::D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS { + Format: raw_format, + SampleCount: 0, + Flags: d3d12::D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE, + NumQualityLevels: 0, + }; + + for i in 0..(mem::size_of::() * 8) { + let bit = Tfsc::from_bits(1 << i); + if bit.is_some() { + ms_levels.SampleCount = 1 << i; + + if self.device.CheckFeatureSupport( + d3d12::D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, + &mut ms_levels as *mut _ as *mut _, + mem::size_of::() as _, + ) == winerror::S_OK + && ms_levels.NumQualityLevels != 0 + { + flags.set(Tfsc::from_bits(ms_levels.SampleCount as u8).unwrap(), true); + } + } + } + + flags + } + unsafe fn surface_capabilities( &self, surface: &super::Surface, diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index b13ceb9489..aa277255aa 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -89,6 +89,13 @@ impl crate::Adapter for Context { ) -> crate::TextureFormatCapabilities { crate::TextureFormatCapabilities::empty() } + + unsafe fn texture_format_sample_count( + &self, + format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags { + wgt::TextureFormatSampleCountFlags::empty() + } unsafe fn surface_capabilities(&self, surface: &Context) -> Option { None } diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 53b11029d0..996be593c2 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -197,7 +197,6 @@ impl super::Adapter { (vendor, renderer) }; let version = gl.get_parameter_string(glow::VERSION); - log::info!("Vendor: {}", vendor); log::info!("Renderer: {}", renderer); log::info!("Version: {}", version); @@ -786,6 +785,13 @@ impl crate::Adapter for super::Adapter { } } + unsafe fn texture_format_sample_count( + &self, + _format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags { + wgt::TextureFormatSampleCountFlags::_1 | wgt::TextureFormatSampleCountFlags::_4 + } + unsafe fn surface_capabilities( &self, surface: &super::Surface, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index b32f372de2..4413f98deb 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -228,6 +228,12 @@ pub trait Adapter: Send + Sync { format: wgt::TextureFormat, ) -> TextureFormatCapabilities; + /// Returns the set of supported sample count for a texture format. + unsafe fn texture_format_sample_count( + &self, + format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags; + /// Returns the capabilities of working with a specified surface. /// /// `None` means presentation is not supported for it. diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index a8bf9b18c3..c03befd9a6 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -279,6 +279,14 @@ impl crate::Adapter for super::Adapter { Tfc::COPY_SRC | Tfc::COPY_DST | Tfc::SAMPLED | extra } + #[allow(trivial_casts)] + unsafe fn texture_format_sample_count( + &self, + _format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags { + self.shared.private_caps.sample_count_mask + } + unsafe fn surface_capabilities( &self, surface: &super::Surface, @@ -489,12 +497,13 @@ impl super::PrivateCapabilities { version.is_mac = os_is_mac; let family_check = version.at_least((10, 15), (13, 0)); - let mut sample_count_mask: u8 = 1 | 4; // 1 and 4 samples are supported on all devices + let mut sample_count_mask = + wgt::TextureFormatSampleCountFlags::_1 | wgt::TextureFormatSampleCountFlags::_4; // 1 and 4 samples are supported on all devices if device.supports_texture_sample_count(2) { - sample_count_mask |= 2; + sample_count_mask |= wgt::TextureFormatSampleCountFlags::_2; } if device.supports_texture_sample_count(8) { - sample_count_mask |= 8; + sample_count_mask |= wgt::TextureFormatSampleCountFlags::_8; } let rw_texture_tier = if version.at_least((10, 13), (11, 0)) { diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 62a9b3b087..9adc287d90 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -219,7 +219,7 @@ struct PrivateCapabilities { max_varying_components: u32, max_threads_per_group: u32, max_total_threadgroup_memory: u32, - sample_count_mask: u8, + sample_count_mask: wgt::TextureFormatSampleCountFlags, supports_debug_markers: bool, supports_binary_archives: bool, supports_capture_manager: bool, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 0c035f6ae7..0d2b48977b 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1435,6 +1435,53 @@ impl crate::Adapter for super::Adapter { flags } + unsafe fn texture_format_sample_count( + &self, + format: wgt::TextureFormat, + ) -> wgt::TextureFormatSampleCountFlags { + use wgt::TextureFormatSampleCountFlags as Tfsc; + let mut flags = Tfsc::empty(); + + let format_aspect = crate::FormatAspects::from(format); + let limits = self.phd_capabilities.properties.limits; + + let sample_flags = if format_aspect.contains(crate::FormatAspects::DEPTH) { + limits + .framebuffer_depth_sample_counts + .min(limits.sampled_image_depth_sample_counts) + } else if format_aspect.contains(crate::FormatAspects::STENCIL) { + limits + .framebuffer_stencil_sample_counts + .min(limits.sampled_image_stencil_sample_counts) + } else { + limits + .framebuffer_color_sample_counts + .min(limits.sampled_image_color_sample_counts) + .min(limits.sampled_image_integer_sample_counts) + .min(limits.storage_image_sample_counts) + }; + + flags.set( + Tfsc::_1, + sample_flags.contains(vk::SampleCountFlags::TYPE_1), + ); + flags.set( + Tfsc::_2, + sample_flags.contains(vk::SampleCountFlags::TYPE_2), + ); + flags.set( + Tfsc::_4, + sample_flags.contains(vk::SampleCountFlags::TYPE_4), + ); + + flags.set( + Tfsc::_8, + sample_flags.contains(vk::SampleCountFlags::TYPE_8), + ); + + flags + } + unsafe fn surface_capabilities( &self, surface: &super::Surface, diff --git a/wgpu-info/src/main.rs b/wgpu-info/src/main.rs index 00d5e8c0f1..6bb7a1d045 100644 --- a/wgpu-info/src/main.rs +++ b/wgpu-info/src/main.rs @@ -230,7 +230,7 @@ mod inner { } } - println!("\tTexture Format Features: ┌──────────┬──────────┬──────────Allowed┬Usages───────────┬───────────────────┐ ┌────────────┬─────────────┬──────────────Feature┬Flags───────────────┬─────────────────┐"); + println!("\tTexture Format Features: ┌──────────┬──────────┬──────────Allowed┬Usages───────────┬───────────────────┐ ┌────────────┬─────────────┬──────────────Feature┬Flags───────────────┬─────────────────┬──────────┬Sample─Flags─"); for format in TEXTURE_FORMAT_LIST { let features = adapter.get_texture_format_features(format); let format_name = match format { @@ -271,6 +271,23 @@ mod inner { } } } + + for i in 0..(size_of::()*8) { + let bit = wgpu::TextureFormatSampleCountFlags::from_bits(1 << i); + if let Some(bit) = bit { + if i == 0 { + print!("│"); + } + if features.sample_count.contains(bit) { + print!("{:?}," , bit.bits()); + } + else { + let length = format!("{:?},",bit.bits()).len(); + print!("{}", " ".repeat(length)) + } + } + } + println!(" │"); } println!("\t └──────────┴──────────┴─────────────────┴─────────────────┴───────────────────┘ └────────────┴─────────────┴─────────────────────┴────────────────────┴─────────────────┘"); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ec5b0dd8a3..226d2ccf4d 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1648,6 +1648,24 @@ bitflags::bitflags! { #[cfg(feature = "bitflags_serde_shim")] bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatFeatureFlags); +bitflags::bitflags! { + /// Texture format sample count flags. + #[repr(transparent)] + pub struct TextureFormatSampleCountFlags: u8 { + /// + const _1 = 1 << 0; + /// requires [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] to be enabled + const _2 = 1 << 1; + /// + const _4 = 1 << 2; + /// requires [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] to be enabled + const _8 = 1 << 3; + } +} + +#[cfg(feature = "bitflags_serde_shim")] +bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatSampleCountFlags); + /// Features supported by a given texture format /// /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled. @@ -1657,6 +1675,8 @@ pub struct TextureFormatFeatures { pub allowed_usages: TextureUsages, /// Additional property flags for the format. pub flags: TextureFormatFeatureFlags, + /// supported sample count + pub sample_count: TextureFormatSampleCountFlags, } /// Information about a texture format. @@ -2462,6 +2482,7 @@ impl TextureFormat { guaranteed_format_features: TextureFormatFeatures { allowed_usages, flags, + sample_count: TextureFormatSampleCountFlags::_1 | TextureFormatSampleCountFlags::_4, }, } } diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index 27d1e80798..0f64964af1 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -32,6 +32,7 @@ struct Example { sample_count: u32, rebuild_bundle: bool, config: wgpu::SurfaceConfiguration, + max_sample_count: u32, } impl Example { @@ -117,6 +118,10 @@ impl Example { } impl framework::Example for Example { + fn optional_features() -> wgt::Features { + wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES + } + fn init( config: &wgpu::SurfaceConfiguration, _adapter: &wgpu::Adapter, @@ -124,7 +129,24 @@ impl framework::Example for Example { _queue: &wgpu::Queue, ) -> Self { log::info!("Press left/right arrow keys to change sample_count."); - let sample_count = 4; + + let sample_flags = _adapter + .get_texture_format_features(config.format) + .sample_count; + + let max_sample_count = { + if sample_flags.contains(wgpu::TextureFormatSampleCountFlags::_8) { + wgpu::TextureFormatSampleCountFlags::_8.bits() + } else if sample_flags.contains(wgpu::TextureFormatSampleCountFlags::_4) { + wgpu::TextureFormatSampleCountFlags::_4.bits() + } else if sample_flags.contains(wgpu::TextureFormatSampleCountFlags::_2) { + wgpu::TextureFormatSampleCountFlags::_2.bits() + } else { + wgpu::TextureFormatSampleCountFlags::_1.bits() + } + } as u32; + + let sample_count = max_sample_count; let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: None, @@ -181,6 +203,7 @@ impl framework::Example for Example { vertex_buffer, vertex_count, sample_count, + max_sample_count, rebuild_bundle: false, config: config.clone(), } @@ -195,14 +218,14 @@ impl framework::Example for Example { // TODO: Switch back to full scans of possible options when we expose // supported sample counts to the user. Some(winit::event::VirtualKeyCode::Left) => { - if self.sample_count == 4 { + if self.sample_count == self.max_sample_count { self.sample_count = 1; self.rebuild_bundle = true; } } Some(winit::event::VirtualKeyCode::Right) => { if self.sample_count == 1 { - self.sample_count = 4; + self.sample_count = self.max_sample_count; self.rebuild_bundle = true; } } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 7338e7df42..3369084b9b 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -37,10 +37,11 @@ pub use wgt::{ RenderBundleDepthStencil, SamplerBindingType, SamplerBorderColor, ShaderLocation, ShaderModel, ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, SurfaceConfiguration, SurfaceStatus, TextureAspect, TextureDimension, TextureFormat, - TextureFormatFeatureFlags, TextureFormatFeatures, TextureSampleType, TextureUsages, - TextureViewDimension, VertexAttribute, VertexFormat, VertexStepMode, COPY_BUFFER_ALIGNMENT, - COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, - QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_STRIDE_ALIGNMENT, + TextureFormatFeatureFlags, TextureFormatFeatures, TextureFormatSampleCountFlags, + TextureSampleType, TextureUsages, TextureViewDimension, VertexAttribute, VertexFormat, + VertexStepMode, COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, + PUSH_CONSTANT_ALIGNMENT, QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, + VERTEX_STRIDE_ALIGNMENT, }; use backend::{BufferMappedRange, Context as C, QueueWriteBuffer}; From b16740bd719b418646545bfe28d0618f5469bdc1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Oct 2022 12:43:23 +0300 Subject: [PATCH 2/6] Updated CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6602678c80..845906c39b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Bottom level categories: - Implement `Default` for `CompositeAlphaMode` #### WebGPU + - Implement `queue_validate_write_buffer` by @jinleili in [#3098](https://github.com/gfx-rs/wgpu/pull/3098) #### GLES @@ -62,11 +63,16 @@ Bottom level categories: - Add the `"wgsl"` feature, to enable WGSL shaders in `wgpu-core` and `wgpu`. Enabled by default in `wgpu`. By @daxpedda in [#2890](https://github.com/gfx-rs/wgpu/pull/2890). - Implement `Clone` for `ShaderSource` and `ShaderModuleDescriptor` in `wgpu`. By @daxpedda in [#3086](https://github.com/gfx-rs/wgpu/pull/3086). - Add `get_default_config` for `Surface` to simplify user creation of `SurfaceConfiguration`. By @jinleili in [#3034](https://github.com/gfx-rs/wgpu/pull/3034) +- Native adapters can now use MSAA x2 and x8 if it's supported , previously only x1 and x4 were supported . By @39ali in [3140](https://github.com/gfx-rs/wgpu/pull/3140) #### GLES - Surfaces support now `TextureFormat::Rgba8Unorm` and (non-web only) `TextureFormat::Bgra8Unorm`. By @Wumpf in [#3070](https://github.com/gfx-rs/wgpu/pull/3070) +#### WebGPU + +- Add `TextureFormatSampleCountFlags` to `TextureFormatFeatures` to query supported sample count for the current texture format. By @39ali in [3140](https://github.com/gfx-rs/wgpu/pull/3140) + ### Bug Fixes #### General @@ -76,6 +82,7 @@ Bottom level categories: - Avoid panicking in some interactions with invalid resources by @nical in (#3094)[https://github.com/gfx-rs/wgpu/pull/3094] #### WebGPU + - Use `log` instead of `println` in hello example by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858) #### GLES @@ -83,6 +90,7 @@ Bottom level categories: - Fixed WebGL not displaying srgb targets correctly if a non-screen filling viewport was previously set. By @Wumpf in [#3093](https://github.com/gfx-rs/wgpu/pull/3093) ### Examples + - Log adapter info in hello example on wasm target by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858) ### Testing/Internal @@ -185,6 +193,7 @@ both `raw_window_handle::HasRawWindowHandle` and `raw_window_handle::HasRawDispl - Report Apple M2 gpu as integrated. By @i509VCB [#3036](https://github.com/gfx-rs/wgpu/pull/3036) #### WebGPU + - When called in a web worker, `Context::init()` now uses `web_sys::WorkerGlobalContext` to create a `wgpu::Instance` instead of trying to access the unavailable `web_sys::Window` by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858) ### Changes @@ -340,6 +349,7 @@ Added items to the public API - Update present_mode docs as most of them don't automatically fall back to Fifo anymore. by @Elabajaba in [#2855](https://github.com/gfx-rs/wgpu/pull/2855) #### Hal + - Document safety requirements for `Adapter::from_external` in gles hal by @i509VCB in [#2863](https://github.com/gfx-rs/wgpu/pull/2863) - Make `AdapterContext` a publicly accessible type in the gles hal by @i509VCB in [#2870](https://github.com/gfx-rs/wgpu/pull/2870) From e1f1e4d2a672ec588bce6e4cf472acc38cae1781 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Oct 2022 15:27:34 +0300 Subject: [PATCH 3/6] Moved MULTISAMPLE_X2,MULTISAMPLE_X4 and MULTISAMPLE_X8 to TextureFormatFeatureFlags. --- wgpu-core/src/device/mod.rs | 37 ++++++++++++++++------- wgpu-core/src/instance.rs | 15 +++++++--- wgpu-core/src/present.rs | 3 +- wgpu-hal/src/dx11/adapter.rs | 7 ----- wgpu-hal/src/dx12/adapter.rs | 52 ++++++++++++--------------------- wgpu-hal/src/empty.rs | 6 ---- wgpu-hal/src/gles/adapter.rs | 11 ++----- wgpu-hal/src/lib.rs | 21 +++++++------ wgpu-hal/src/metal/adapter.rs | 25 +++++----------- wgpu-hal/src/metal/mod.rs | 2 +- wgpu-hal/src/vulkan/adapter.rs | 25 ++++------------ wgpu-info/src/main.rs | 20 ++----------- wgpu-types/src/lib.rs | 43 +++++++++------------------ wgpu/examples/msaa-line/main.rs | 22 +++++++------- wgpu/src/lib.rs | 9 +++--- 15 files changed, 112 insertions(+), 186 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 5b5fab4034..786aa97126 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -802,19 +802,33 @@ impl Device { if !format_features .flags - .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE) + .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4) { return Err(CreateTextureError::InvalidMultisampledFormat(desc.format)); } - match wgt::TextureFormatSampleCountFlags::from_bits(desc.sample_count as u8) { - Some(sample_count) => { - if !format_features.sample_count.contains(sample_count) { - return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); - } - } - None => return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)), - } + if desc.sample_count == 2 + && !format_features + .flags + .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2) + { + return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); + }; + + if desc.sample_count == 4 + && !format_features + .flags + .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4) + { + return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); + }; + if desc.sample_count == 8 + && !format_features + .flags + .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8) + { + return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); + }; } let mips = desc.mip_level_count; @@ -2663,7 +2677,7 @@ impl Device { break Some(pipeline::ColorStateError::FormatNotColor(cs.format)); } if desc.multisample.count > 1 - && !format_features.flags.contains(Tfff::MULTISAMPLE) + && !format_features.flags.contains(Tfff::MULTISAMPLE_X4) { break Some(pipeline::ColorStateError::FormatNotMultisampled(cs.format)); } @@ -2697,7 +2711,8 @@ impl Device { ds.format, )); } - if desc.multisample.count > 1 && !format_features.flags.contains(Tfff::MULTISAMPLE) + if desc.multisample.count > 1 + && !format_features.flags.contains(Tfff::MULTISAMPLE_X4) { break Some(pipeline::DepthStencilStateError::FormatNotMultisampled( ds.format, diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index ad9ea88f55..7d6b94ed51 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -230,7 +230,6 @@ impl Adapter { use hal::TextureFormatCapabilities as Tfc; let caps = unsafe { self.raw.adapter.texture_format_capabilities(format) }; - let sample_count = unsafe { self.raw.adapter.texture_format_sample_count(format) }; let mut allowed_usages = wgt::TextureUsages::empty(); allowed_usages.set(wgt::TextureUsages::COPY_SRC, caps.contains(Tfc::COPY_SRC)); @@ -269,9 +268,18 @@ impl Adapter { ); flags.set( - wgt::TextureFormatFeatureFlags::MULTISAMPLE, - caps.contains(Tfc::MULTISAMPLE), + wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2, + caps.contains(Tfc::MULTISAMPLE_X2), ); + flags.set( + wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4, + caps.contains(Tfc::MULTISAMPLE_X4), + ); + flags.set( + wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8, + caps.contains(Tfc::MULTISAMPLE_X8), + ); + flags.set( wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE, caps.contains(Tfc::MULTISAMPLE_RESOLVE), @@ -280,7 +288,6 @@ impl Adapter { wgt::TextureFormatFeatures { allowed_usages, flags, - sample_count, } } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 785cbff877..41da2fa585 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -184,9 +184,8 @@ impl Global { hal_usage: conv::map_texture_usage(config.usage, config.format.into()), format_features: wgt::TextureFormatFeatures { allowed_usages: wgt::TextureUsages::RENDER_ATTACHMENT, - flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE + flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4 | wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE, - sample_count: wgt::TextureFormatSampleCountFlags::_1, }, initialization_status: TextureInitTracker::new(1, 1), full_range: track::TextureSelector { diff --git a/wgpu-hal/src/dx11/adapter.rs b/wgpu-hal/src/dx11/adapter.rs index 993b54e4e5..9ea3243ab8 100644 --- a/wgpu-hal/src/dx11/adapter.rs +++ b/wgpu-hal/src/dx11/adapter.rs @@ -18,13 +18,6 @@ impl crate::Adapter for super::Adapter { todo!() } - unsafe fn texture_format_sample_count( - &self, - format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags { - todo!() - } - unsafe fn surface_capabilities( &self, surface: &super::Surface, diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index f82d4585e3..e4b3838d8d 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -447,29 +447,12 @@ impl crate::Adapter for super::Adapter { | d3d12::D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL) != 0 && data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET == 0; - caps.set(Tfc::MULTISAMPLE, !no_msaa_load && !no_msaa_target); + caps.set( Tfc::MULTISAMPLE_RESOLVE, data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE != 0, ); - caps - } - - #[allow(trivial_casts)] - unsafe fn texture_format_sample_count( - &self, - format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags { - use wgt::TextureFormatSampleCountFlags as Tfsc; - - let raw_format = match auxil::dxgi::conv::map_texture_format_failable(format) { - Some(f) => f, - None => return Tfsc::empty(), - }; - - let mut flags = Tfsc::empty(); - let mut ms_levels = d3d12::D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS { Format: raw_format, SampleCount: 0, @@ -477,24 +460,25 @@ impl crate::Adapter for super::Adapter { NumQualityLevels: 0, }; - for i in 0..(mem::size_of::() * 8) { - let bit = Tfsc::from_bits(1 << i); - if bit.is_some() { - ms_levels.SampleCount = 1 << i; - - if self.device.CheckFeatureSupport( - d3d12::D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, - &mut ms_levels as *mut _ as *mut _, - mem::size_of::() as _, - ) == winerror::S_OK - && ms_levels.NumQualityLevels != 0 - { - flags.set(Tfsc::from_bits(ms_levels.SampleCount as u8).unwrap(), true); - } + let mut set_sample_count = |sc: u32, tfc: Tfc| { + ms_levels.SampleCount = sc; + + if self.device.CheckFeatureSupport( + d3d12::D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, + &mut ms_levels as *mut _ as *mut _, + mem::size_of::() as _, + ) == winerror::S_OK + && ms_levels.NumQualityLevels != 0 + { + caps.set(tfc, !no_msaa_load && !no_msaa_target); } - } + }; - flags + set_sample_count(2, Tfc::MULTISAMPLE_X2); + set_sample_count(4, Tfc::MULTISAMPLE_X4); + set_sample_count(8, Tfc::MULTISAMPLE_X8); + + caps } unsafe fn surface_capabilities( diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index aa277255aa..a761ef7fb1 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -90,12 +90,6 @@ impl crate::Adapter for Context { crate::TextureFormatCapabilities::empty() } - unsafe fn texture_format_sample_count( - &self, - format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags { - wgt::TextureFormatSampleCountFlags::empty() - } unsafe fn surface_capabilities(&self, surface: &Context) -> Option { None } diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 996be593c2..2b2163d56c 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -665,10 +665,10 @@ impl crate::Adapter for super::Adapter { let empty = Tfc::empty(); let base = Tfc::COPY_SRC | Tfc::COPY_DST; let unfilterable = base | Tfc::SAMPLED; - let depth = base | Tfc::SAMPLED | Tfc::MULTISAMPLE | Tfc::DEPTH_STENCIL_ATTACHMENT; + let depth = base | Tfc::SAMPLED | Tfc::MULTISAMPLE_X4 | Tfc::DEPTH_STENCIL_ATTACHMENT; let filterable = unfilterable | Tfc::SAMPLED_LINEAR; let renderable = - unfilterable | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE | Tfc::MULTISAMPLE_RESOLVE; + unfilterable | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4 | Tfc::MULTISAMPLE_RESOLVE; let filterable_renderable = filterable | renderable | Tfc::COLOR_ATTACHMENT_BLEND; let storage = base | Tfc::STORAGE | Tfc::STORAGE_READ_WRITE; @@ -785,13 +785,6 @@ impl crate::Adapter for super::Adapter { } } - unsafe fn texture_format_sample_count( - &self, - _format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags { - wgt::TextureFormatSampleCountFlags::_1 | wgt::TextureFormatSampleCountFlags::_4 - } - unsafe fn surface_capabilities( &self, surface: &super::Surface, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 4413f98deb..1e3c78caee 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -228,12 +228,6 @@ pub trait Adapter: Send + Sync { format: wgt::TextureFormat, ) -> TextureFormatCapabilities; - /// Returns the set of supported sample count for a texture format. - unsafe fn texture_format_sample_count( - &self, - format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags; - /// Returns the capabilities of working with a specified surface. /// /// `None` means presentation is not supported for it. @@ -588,15 +582,20 @@ bitflags!( /// Format can be used as depth-stencil and input attachment. const DEPTH_STENCIL_ATTACHMENT = 1 << 8; - /// Format can be multisampled. - const MULTISAMPLE = 1 << 9; + /// Format can be multisampled by x2. + const MULTISAMPLE_X2 = 1 << 9; + /// Format can be multisampled by x4. + const MULTISAMPLE_X4 = 1 << 10; + /// Format can be multisampled by x8. + const MULTISAMPLE_X8 = 1 << 11; + /// Format can be used for render pass resolve targets. - const MULTISAMPLE_RESOLVE = 1 << 10; + const MULTISAMPLE_RESOLVE = 1 << 12; /// Format can be copied from. - const COPY_SRC = 1 << 11; + const COPY_SRC = 1 << 13; /// Format can be copied to. - const COPY_DST = 1 << 12; + const COPY_DST = 1 << 14; } ); diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index c03befd9a6..f1a581e249 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -57,12 +57,12 @@ impl crate::Adapter for super::Adapter { } }; let msaa_desktop_if = if pc.msaa_desktop { - Tfc::MULTISAMPLE + Tfc::MULTISAMPLE_X4 } else { Tfc::empty() }; let msaa_apple7x_if = if pc.msaa_desktop | pc.msaa_apple7 { - Tfc::MULTISAMPLE + Tfc::MULTISAMPLE_X4 } else { Tfc::empty() }; @@ -90,7 +90,7 @@ impl crate::Adapter for super::Adapter { | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE + | Tfc::MULTISAMPLE_X4 | Tfc::MULTISAMPLE_RESOLVE; let extra = match format { @@ -110,7 +110,7 @@ impl crate::Adapter for super::Adapter { | Tf::Rgba8Sint | Tf::Rgba16Uint | Tf::Rgba16Sint => { - read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE + read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4 } Tf::R16Unorm | Tf::R16Snorm @@ -275,18 +275,10 @@ impl crate::Adapter for super::Adapter { } } }; - + // self.shared.private_caps.sample_count_mask Tfc::COPY_SRC | Tfc::COPY_DST | Tfc::SAMPLED | extra } - #[allow(trivial_casts)] - unsafe fn texture_format_sample_count( - &self, - _format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags { - self.shared.private_caps.sample_count_mask - } - unsafe fn surface_capabilities( &self, surface: &super::Surface, @@ -497,13 +489,12 @@ impl super::PrivateCapabilities { version.is_mac = os_is_mac; let family_check = version.at_least((10, 15), (13, 0)); - let mut sample_count_mask = - wgt::TextureFormatSampleCountFlags::_1 | wgt::TextureFormatSampleCountFlags::_4; // 1 and 4 samples are supported on all devices + let mut sample_count_mask = wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4; // 1 and 4 samples are supported on all devices if device.supports_texture_sample_count(2) { - sample_count_mask |= wgt::TextureFormatSampleCountFlags::_2; + sample_count_mask |= wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2; } if device.supports_texture_sample_count(8) { - sample_count_mask |= wgt::TextureFormatSampleCountFlags::_8; + sample_count_mask |= wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8; } let rw_texture_tier = if version.at_least((10, 13), (11, 0)) { diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 9adc287d90..851868b023 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -219,7 +219,7 @@ struct PrivateCapabilities { max_varying_components: u32, max_threads_per_group: u32, max_total_threadgroup_memory: u32, - sample_count_mask: wgt::TextureFormatSampleCountFlags, + sample_count_mask: wgt::TextureFormatFeatureFlags, supports_debug_markers: bool, supports_binary_archives: bool, supports_capture_manager: bool, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 0d2b48977b..759e981b0f 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1428,20 +1428,9 @@ impl crate::Adapter for super::Adapter { ), ); // Vulkan is very permissive about MSAA - flags.set( - Tfc::MULTISAMPLE | Tfc::MULTISAMPLE_RESOLVE, - !format.describe().is_compressed(), - ); - flags - } - - unsafe fn texture_format_sample_count( - &self, - format: wgt::TextureFormat, - ) -> wgt::TextureFormatSampleCountFlags { - use wgt::TextureFormatSampleCountFlags as Tfsc; - let mut flags = Tfsc::empty(); + flags.set(Tfc::MULTISAMPLE_RESOLVE, !format.describe().is_compressed()); + // get the supported sample counts let format_aspect = crate::FormatAspects::from(format); let limits = self.phd_capabilities.properties.limits; @@ -1462,20 +1451,16 @@ impl crate::Adapter for super::Adapter { }; flags.set( - Tfsc::_1, - sample_flags.contains(vk::SampleCountFlags::TYPE_1), - ); - flags.set( - Tfsc::_2, + Tfc::MULTISAMPLE_X2, sample_flags.contains(vk::SampleCountFlags::TYPE_2), ); flags.set( - Tfsc::_4, + Tfc::MULTISAMPLE_X4, sample_flags.contains(vk::SampleCountFlags::TYPE_4), ); flags.set( - Tfsc::_8, + Tfc::MULTISAMPLE_X8, sample_flags.contains(vk::SampleCountFlags::TYPE_8), ); diff --git a/wgpu-info/src/main.rs b/wgpu-info/src/main.rs index 6bb7a1d045..e78c99d323 100644 --- a/wgpu-info/src/main.rs +++ b/wgpu-info/src/main.rs @@ -230,7 +230,7 @@ mod inner { } } - println!("\tTexture Format Features: ┌──────────┬──────────┬──────────Allowed┬Usages───────────┬───────────────────┐ ┌────────────┬─────────────┬──────────────Feature┬Flags───────────────┬─────────────────┬──────────┬Sample─Flags─"); + println!("\tTexture Format Features: ┌──────────┬──────────┬──────────Allowed┬Usages───────────┬───────────────────┐ ┌────────────┬────────────────┬──────────────Feature┬Flags──────┬─────────────────────┬────────────────────┬─"); for format in TEXTURE_FORMAT_LIST { let features = adapter.get_texture_format_features(format); let format_name = match format { @@ -272,25 +272,9 @@ mod inner { } } - for i in 0..(size_of::()*8) { - let bit = wgpu::TextureFormatSampleCountFlags::from_bits(1 << i); - if let Some(bit) = bit { - if i == 0 { - print!("│"); - } - if features.sample_count.contains(bit) { - print!("{:?}," , bit.bits()); - } - else { - let length = format!("{:?},",bit.bits()).len(); - print!("{}", " ".repeat(length)) - } - } - } - println!(" │"); } - println!("\t └──────────┴──────────┴─────────────────┴─────────────────┴───────────────────┘ └────────────┴─────────────┴─────────────────────┴────────────────────┴─────────────────┘"); + println!("\t └──────────┴──────────┴─────────────────┴─────────────────┴───────────────────┘ └────────────┴────────────────┴────────────────┴────────────────┴─────────────────────┘"); } pub fn main() { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 226d2ccf4d..2f73b3e6c1 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1629,43 +1629,29 @@ bitflags::bitflags! { /// If not present, the texture can't be sampled with a filtering sampler. /// This may overwrite TextureSampleType::Float.filterable const FILTERABLE = 1 << 0; - /// Allows [`TextureDescriptor::sample_count`] greater than `1`. - const MULTISAMPLE = 1 << 1; + /// Allows [`TextureDescriptor::sample_count`] to be `2`. + const MULTISAMPLE_X2 = 1 << 1; + /// Allows [`TextureDescriptor::sample_count`] to be `4`. + const MULTISAMPLE_X4 = 1 << 2 ; + /// Allows [`TextureDescriptor::sample_count`] to be `8`. + const MULTISAMPLE_X8 = 1 << 3 ; /// Allows a texture of this format to back a view passed as `resolve_target` /// to a render pass for an automatic driver-implemented resolve. - const MULTISAMPLE_RESOLVE = 1 << 2; + const MULTISAMPLE_RESOLVE = 1 << 4; /// When used as a STORAGE texture, then a texture with this format can be bound with /// [`StorageTextureAccess::ReadOnly`] or [`StorageTextureAccess::ReadWrite`]. - const STORAGE_READ_WRITE = 1 << 3; + const STORAGE_READ_WRITE = 1 << 5; /// When used as a STORAGE texture, then a texture with this format can be written to with atomics. // TODO: No access flag exposed as of writing - const STORAGE_ATOMICS = 1 << 4; + const STORAGE_ATOMICS = 1 << 6; /// If not present, the texture can't be blended into the render target. - const BLENDABLE = 1 << 5; + const BLENDABLE = 1 << 7; } } #[cfg(feature = "bitflags_serde_shim")] bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatFeatureFlags); -bitflags::bitflags! { - /// Texture format sample count flags. - #[repr(transparent)] - pub struct TextureFormatSampleCountFlags: u8 { - /// - const _1 = 1 << 0; - /// requires [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] to be enabled - const _2 = 1 << 1; - /// - const _4 = 1 << 2; - /// requires [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] to be enabled - const _8 = 1 << 3; - } -} - -#[cfg(feature = "bitflags_serde_shim")] -bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatSampleCountFlags); - /// Features supported by a given texture format /// /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled. @@ -1675,8 +1661,6 @@ pub struct TextureFormatFeatures { pub allowed_usages: TextureUsages, /// Additional property flags for the format. pub flags: TextureFormatFeatureFlags, - /// supported sample count - pub sample_count: TextureFormatSampleCountFlags, } /// Information about a texture format. @@ -2329,9 +2313,9 @@ impl TextureFormat { // Multisampling let noaa = TextureFormatFeatureFlags::empty(); - let msaa = TextureFormatFeatureFlags::MULTISAMPLE; - let msaa_resolve = - TextureFormatFeatureFlags::MULTISAMPLE | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE; + let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4; + let msaa_resolve = TextureFormatFeatureFlags::MULTISAMPLE_X4 + | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE; // Flags let basic = @@ -2482,7 +2466,6 @@ impl TextureFormat { guaranteed_format_features: TextureFormatFeatures { allowed_usages, flags, - sample_count: TextureFormatSampleCountFlags::_1 | TextureFormatSampleCountFlags::_4, }, } } diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index 0f64964af1..8866933c34 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -130,21 +130,21 @@ impl framework::Example for Example { ) -> Self { log::info!("Press left/right arrow keys to change sample_count."); - let sample_flags = _adapter - .get_texture_format_features(config.format) - .sample_count; + let sample_flags = _adapter.get_texture_format_features(config.format).flags; + + log::info!("sample_flags :{:?}", sample_flags); let max_sample_count = { - if sample_flags.contains(wgpu::TextureFormatSampleCountFlags::_8) { - wgpu::TextureFormatSampleCountFlags::_8.bits() - } else if sample_flags.contains(wgpu::TextureFormatSampleCountFlags::_4) { - wgpu::TextureFormatSampleCountFlags::_4.bits() - } else if sample_flags.contains(wgpu::TextureFormatSampleCountFlags::_2) { - wgpu::TextureFormatSampleCountFlags::_2.bits() + if sample_flags.contains(wgpu::TextureFormatFeatureFlags::MULTISAMPLE_X8) { + 8 + } else if sample_flags.contains(wgpu::TextureFormatFeatureFlags::MULTISAMPLE_X4) { + 4 + } else if sample_flags.contains(wgpu::TextureFormatFeatureFlags::MULTISAMPLE_X2) { + 2 } else { - wgpu::TextureFormatSampleCountFlags::_1.bits() + 1 } - } as u32; + }; let sample_count = max_sample_count; diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 3369084b9b..7338e7df42 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -37,11 +37,10 @@ pub use wgt::{ RenderBundleDepthStencil, SamplerBindingType, SamplerBorderColor, ShaderLocation, ShaderModel, ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, SurfaceConfiguration, SurfaceStatus, TextureAspect, TextureDimension, TextureFormat, - TextureFormatFeatureFlags, TextureFormatFeatures, TextureFormatSampleCountFlags, - TextureSampleType, TextureUsages, TextureViewDimension, VertexAttribute, VertexFormat, - VertexStepMode, COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, - PUSH_CONSTANT_ALIGNMENT, QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, - VERTEX_STRIDE_ALIGNMENT, + TextureFormatFeatureFlags, TextureFormatFeatures, TextureSampleType, TextureUsages, + TextureViewDimension, VertexAttribute, VertexFormat, VertexStepMode, COPY_BUFFER_ALIGNMENT, + COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, + QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_STRIDE_ALIGNMENT, }; use backend::{BufferMappedRange, Context as C, QueueWriteBuffer}; From 9145cfc3b8f2595d13ac183ed01cfb54114ab076 Mon Sep 17 00:00:00 2001 From: 39ali Date: Thu, 27 Oct 2022 16:02:04 +0300 Subject: [PATCH 4/6] Refactored Metal adapter and updated CHANGELOG.md --- CHANGELOG.md | 2 +- wgpu-hal/src/metal/adapter.rs | 34 +++++++++++++++++++-------------- wgpu-hal/src/metal/mod.rs | 2 +- wgpu/examples/msaa-line/main.rs | 2 -- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 845906c39b..cc70c07d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,7 +71,7 @@ Bottom level categories: #### WebGPU -- Add `TextureFormatSampleCountFlags` to `TextureFormatFeatures` to query supported sample count for the current texture format. By @39ali in [3140](https://github.com/gfx-rs/wgpu/pull/3140) +- Add `MULTISAMPLE_X2`, `MULTISAMPLE_X4` and `MULTISAMPLE_X8` to `TextureFormatFeatureFlags`. By @39ali in [3140](https://github.com/gfx-rs/wgpu/pull/3140) ### Bug Fixes diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index f1a581e249..e86aa8eb3c 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -122,11 +122,11 @@ impl crate::Adapter for super::Adapter { | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE + | Tfc::MULTISAMPLE_X4 | msaa_resolve_desktop_if } Tf::Rg8Unorm | Tf::Rg16Float | Tf::Bgra8Unorm => all_caps, - Tf::Rg8Uint | Tf::Rg8Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE, + Tf::Rg8Uint | Tf::Rg8Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4, Tf::R32Uint | Tf::R32Sint => { read_write_tier1_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_desktop_if } @@ -137,11 +137,13 @@ impl crate::Adapter for super::Adapter { Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE + | Tfc::MULTISAMPLE_X4 }; read_write_tier1_if | flags } - Tf::Rg16Uint | Tf::Rg16Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE, + Tf::Rg16Uint | Tf::Rg16Sint => { + Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4 + } Tf::Rgba8UnormSrgb | Tf::Bgra8UnormSrgb => { let mut flags = all_caps; flags.set(Tfc::STORAGE, pc.format_rgba8_srgb_all); @@ -176,7 +178,7 @@ impl crate::Adapter for super::Adapter { if pc.format_rgba32float_all { flags |= all_caps } else if pc.msaa_apple7 { - flags |= Tfc::MULTISAMPLE + flags |= Tfc::MULTISAMPLE_X4 }; flags } @@ -189,7 +191,7 @@ impl crate::Adapter for super::Adapter { }*/ Tf::Depth16Unorm => { let mut flags = - Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE | msaa_resolve_apple3x_if; + Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE_X4 | msaa_resolve_apple3x_if; if pc.format_depth16unorm { flags |= Tfc::SAMPLED_LINEAR } @@ -197,14 +199,14 @@ impl crate::Adapter for super::Adapter { } Tf::Depth32Float | Tf::Depth32FloatStencil8 => { let mut flags = - Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE | msaa_resolve_apple3x_if; + Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE_X4 | msaa_resolve_apple3x_if; if pc.format_depth32float_filter { flags |= Tfc::SAMPLED_LINEAR } flags } Tf::Depth24Plus | Tf::Depth24PlusStencil8 => { - let mut flags = Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE; + let mut flags = Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE_X4; if pc.format_depth24_stencil8 { flags |= Tfc::SAMPLED_LINEAR | Tfc::MULTISAMPLE_RESOLVE } else { @@ -224,7 +226,7 @@ impl crate::Adapter for super::Adapter { Tfc::SAMPLED_LINEAR | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE + | Tfc::MULTISAMPLE_X4 | Tfc::MULTISAMPLE_RESOLVE } } @@ -275,8 +277,12 @@ impl crate::Adapter for super::Adapter { } } }; - // self.shared.private_caps.sample_count_mask - Tfc::COPY_SRC | Tfc::COPY_DST | Tfc::SAMPLED | extra + + Tfc::COPY_SRC + | Tfc::COPY_DST + | Tfc::SAMPLED + | extra + | self.shared.private_caps.sample_count_mask } unsafe fn surface_capabilities( @@ -489,12 +495,12 @@ impl super::PrivateCapabilities { version.is_mac = os_is_mac; let family_check = version.at_least((10, 15), (13, 0)); - let mut sample_count_mask = wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4; // 1 and 4 samples are supported on all devices + let mut sample_count_mask = crate::TextureFormatCapabilities::MULTISAMPLE_X4; // 1 and 4 samples are supported on all devices if device.supports_texture_sample_count(2) { - sample_count_mask |= wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2; + sample_count_mask |= crate::TextureFormatCapabilities::MULTISAMPLE_X2; } if device.supports_texture_sample_count(8) { - sample_count_mask |= wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8; + sample_count_mask |= crate::TextureFormatCapabilities::MULTISAMPLE_X8; } let rw_texture_tier = if version.at_least((10, 13), (11, 0)) { diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 851868b023..00a8aa164b 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -219,7 +219,7 @@ struct PrivateCapabilities { max_varying_components: u32, max_threads_per_group: u32, max_total_threadgroup_memory: u32, - sample_count_mask: wgt::TextureFormatFeatureFlags, + sample_count_mask: crate::TextureFormatCapabilities, supports_debug_markers: bool, supports_binary_archives: bool, supports_capture_manager: bool, diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index 8866933c34..6a5a766025 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -132,8 +132,6 @@ impl framework::Example for Example { let sample_flags = _adapter.get_texture_format_features(config.format).flags; - log::info!("sample_flags :{:?}", sample_flags); - let max_sample_count = { if sample_flags.contains(wgpu::TextureFormatFeatureFlags::MULTISAMPLE_X8) { 8 From 20f1c4e0848afd960ba2f436f9c0ad02fe4b9383 Mon Sep 17 00:00:00 2001 From: 39ali Date: Tue, 1 Nov 2022 22:01:02 +0200 Subject: [PATCH 5/6] Accurately query texture sample count support (metal , gles). --- wgpu-core/src/device/mod.rs | 44 ++++++++++++++--------------------- wgpu-core/src/resource.rs | 4 ++-- wgpu-hal/src/dx12/adapter.rs | 2 +- wgpu-hal/src/gles/adapter.rs | 19 +++++++++++++-- wgpu-hal/src/metal/adapter.rs | 23 +++++------------- wgpu-types/src/lib.rs | 18 ++++++++++++++ 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 786aa97126..f1693b2878 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -800,34 +800,22 @@ impl Device { return Err(CreateTextureError::MultisampledNotRenderAttachment); } - if !format_features - .flags - .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4) - { + if !format_features.flags.intersects( + wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4 + | wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2 + | wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8, + ) { return Err(CreateTextureError::InvalidMultisampledFormat(desc.format)); } - if desc.sample_count == 2 - && !format_features - .flags - .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X2) - { - return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); - }; - - if desc.sample_count == 4 - && !format_features - .flags - .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X4) - { - return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); - }; - if desc.sample_count == 8 - && !format_features - .flags - .contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_X8) + if !format_features + .flags + .sample_count_supported(desc.sample_count) { - return Err(CreateTextureError::InvalidSampleCount(desc.sample_count)); + return Err(CreateTextureError::InvalidSampleCount( + desc.sample_count, + desc.format, + )); }; } @@ -2677,7 +2665,9 @@ impl Device { break Some(pipeline::ColorStateError::FormatNotColor(cs.format)); } if desc.multisample.count > 1 - && !format_features.flags.contains(Tfff::MULTISAMPLE_X4) + && !format_features + .flags + .sample_count_supported(desc.multisample.count) { break Some(pipeline::ColorStateError::FormatNotMultisampled(cs.format)); } @@ -2712,7 +2702,9 @@ impl Device { )); } if desc.multisample.count > 1 - && !format_features.flags.contains(Tfff::MULTISAMPLE_X4) + && !format_features + .flags + .sample_count_supported(desc.multisample.count) { break Some(pipeline::DepthStencilStateError::FormatNotMultisampled( ds.format, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 66a11ecfd6..37705df04e 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -515,8 +515,8 @@ pub enum CreateTextureError { MultisampledNotRenderAttachment, #[error("Texture format {0:?} can't be used due to missing features.")] MissingFeatures(wgt::TextureFormat, #[source] MissingFeatures), - #[error("Sample count {0} is invalid")] - InvalidSampleCount(u32), + #[error("Sample count {0} is not supported by format {1:?} on this device. It may be supported by your adapter through the TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES feature.")] + InvalidSampleCount(u32, wgt::TextureFormat), } impl Resource for Texture { diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index e4b3838d8d..2c645874bf 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -465,7 +465,7 @@ impl crate::Adapter for super::Adapter { if self.device.CheckFeatureSupport( d3d12::D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, - &mut ms_levels as *mut _ as *mut _, + <*mut _>::cast(&mut ms_levels), mem::size_of::() as _, ) == winerror::S_OK && ms_levels.NumQualityLevels != 0 diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 2b2163d56c..fb2698fa82 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -658,6 +658,21 @@ impl crate::Adapter for super::Adapter { use crate::TextureFormatCapabilities as Tfc; use wgt::TextureFormat as Tf; + let sample_count = { + let max_samples = self + .shared + .context + .lock() + .get_parameter_i32(glow::MAX_SAMPLES); + if max_samples >= 8 { + Tfc::MULTISAMPLE_X2 | Tfc::MULTISAMPLE_X4 | Tfc::MULTISAMPLE_X8 + } else if max_samples >= 4 { + Tfc::MULTISAMPLE_X2 | Tfc::MULTISAMPLE_X4 + } else { + Tfc::MULTISAMPLE_X2 + } + }; + // Base types are pulled from the table in the OpenGLES 3.0 spec in section 3.8. // // The storage types are based on table 8.26, in section @@ -665,10 +680,10 @@ impl crate::Adapter for super::Adapter { let empty = Tfc::empty(); let base = Tfc::COPY_SRC | Tfc::COPY_DST; let unfilterable = base | Tfc::SAMPLED; - let depth = base | Tfc::SAMPLED | Tfc::MULTISAMPLE_X4 | Tfc::DEPTH_STENCIL_ATTACHMENT; + let depth = base | Tfc::SAMPLED | sample_count | Tfc::DEPTH_STENCIL_ATTACHMENT; let filterable = unfilterable | Tfc::SAMPLED_LINEAR; let renderable = - unfilterable | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4 | Tfc::MULTISAMPLE_RESOLVE; + unfilterable | Tfc::COLOR_ATTACHMENT | sample_count | Tfc::MULTISAMPLE_RESOLVE; let filterable_renderable = filterable | renderable | Tfc::COLOR_ATTACHMENT_BLEND; let storage = base | Tfc::STORAGE | Tfc::STORAGE_READ_WRITE; diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index e86aa8eb3c..f19e06ee3f 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -56,16 +56,8 @@ impl crate::Adapter for super::Adapter { (Tfc::STORAGE_READ_WRITE, Tfc::STORAGE_READ_WRITE) } }; - let msaa_desktop_if = if pc.msaa_desktop { - Tfc::MULTISAMPLE_X4 - } else { - Tfc::empty() - }; - let msaa_apple7x_if = if pc.msaa_desktop | pc.msaa_apple7 { - Tfc::MULTISAMPLE_X4 - } else { - Tfc::empty() - }; + let msaa_count = pc.sample_count_mask; + let msaa_resolve_desktop_if = if pc.msaa_desktop { Tfc::MULTISAMPLE_RESOLVE } else { @@ -128,7 +120,7 @@ impl crate::Adapter for super::Adapter { Tf::Rg8Unorm | Tf::Rg16Float | Tf::Bgra8Unorm => all_caps, Tf::Rg8Uint | Tf::Rg8Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4, Tf::R32Uint | Tf::R32Sint => { - read_write_tier1_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_desktop_if + read_write_tier1_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_count } Tf::R32Float => { let flags = if pc.format_r32float_all { @@ -159,19 +151,16 @@ impl crate::Adapter for super::Adapter { flags.set(Tfc::STORAGE, pc.format_rg11b10_all); flags } - Tf::Rg32Uint | Tf::Rg32Sint => Tfc::COLOR_ATTACHMENT | Tfc::STORAGE | msaa_apple7x_if, + Tf::Rg32Uint | Tf::Rg32Sint => Tfc::COLOR_ATTACHMENT | Tfc::STORAGE | msaa_count, Tf::Rg32Float => { if pc.format_rg32float_all { all_caps } else { - Tfc::STORAGE - | Tfc::COLOR_ATTACHMENT - | Tfc::COLOR_ATTACHMENT_BLEND - | msaa_apple7x_if + Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND | msaa_count } } Tf::Rgba32Uint | Tf::Rgba32Sint => { - read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_desktop_if + read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_count } Tf::Rgba32Float => { let mut flags = read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT; diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 2f73b3e6c1..2522914ad2 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1649,6 +1649,24 @@ bitflags::bitflags! { } } +impl TextureFormatFeatureFlags { + /// Sample count supported by a given texture format. + /// + /// returns `true` if `count` is a supported sample count. + pub fn sample_count_supported(&self, count: u32) -> bool { + use TextureFormatFeatureFlags as tfsc; + + if count == 1 + || (count == 2 && self.contains(tfsc::MULTISAMPLE_X2)) + || (count == 4 && self.contains(tfsc::MULTISAMPLE_X4)) + || (count == 8 && self.contains(tfsc::MULTISAMPLE_X8)) + { + return true; + } + false + } +} + #[cfg(feature = "bitflags_serde_shim")] bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatFeatureFlags); From b6ac998f5fc91888a0757e5721c1a1e060578e8f Mon Sep 17 00:00:00 2001 From: 39ali Date: Thu, 3 Nov 2022 14:51:42 +0200 Subject: [PATCH 6/6] Refactored `metal/adapter.rs` and `wgpu-types/src/lib.rs --- wgpu-hal/src/metal/adapter.rs | 33 ++++++++++++--------------------- wgpu-types/src/lib.rs | 13 ++++++------- wgpu/examples/msaa-line/main.rs | 3 ++- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index f19e06ee3f..a33d42342b 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -82,7 +82,7 @@ impl crate::Adapter for super::Adapter { | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE_X4 + | msaa_count | Tfc::MULTISAMPLE_RESOLVE; let extra = match format { @@ -102,7 +102,7 @@ impl crate::Adapter for super::Adapter { | Tf::Rgba8Sint | Tf::Rgba16Uint | Tf::Rgba16Sint => { - read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4 + read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_count } Tf::R16Unorm | Tf::R16Snorm @@ -114,11 +114,11 @@ impl crate::Adapter for super::Adapter { | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE_X4 + | msaa_count | msaa_resolve_desktop_if } Tf::Rg8Unorm | Tf::Rg16Float | Tf::Bgra8Unorm => all_caps, - Tf::Rg8Uint | Tf::Rg8Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4, + Tf::Rg8Uint | Tf::Rg8Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_count, Tf::R32Uint | Tf::R32Sint => { read_write_tier1_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_count } @@ -126,16 +126,11 @@ impl crate::Adapter for super::Adapter { let flags = if pc.format_r32float_all { all_caps } else { - Tfc::STORAGE - | Tfc::COLOR_ATTACHMENT - | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE_X4 + Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND | msaa_count }; read_write_tier1_if | flags } - Tf::Rg16Uint | Tf::Rg16Sint => { - Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE_X4 - } + Tf::Rg16Uint | Tf::Rg16Sint => Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | msaa_count, Tf::Rgba8UnormSrgb | Tf::Bgra8UnormSrgb => { let mut flags = all_caps; flags.set(Tfc::STORAGE, pc.format_rgba8_srgb_all); @@ -167,7 +162,7 @@ impl crate::Adapter for super::Adapter { if pc.format_rgba32float_all { flags |= all_caps } else if pc.msaa_apple7 { - flags |= Tfc::MULTISAMPLE_X4 + flags |= msaa_count }; flags } @@ -180,7 +175,7 @@ impl crate::Adapter for super::Adapter { }*/ Tf::Depth16Unorm => { let mut flags = - Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE_X4 | msaa_resolve_apple3x_if; + Tfc::DEPTH_STENCIL_ATTACHMENT | msaa_count | msaa_resolve_apple3x_if; if pc.format_depth16unorm { flags |= Tfc::SAMPLED_LINEAR } @@ -188,14 +183,14 @@ impl crate::Adapter for super::Adapter { } Tf::Depth32Float | Tf::Depth32FloatStencil8 => { let mut flags = - Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE_X4 | msaa_resolve_apple3x_if; + Tfc::DEPTH_STENCIL_ATTACHMENT | msaa_count | msaa_resolve_apple3x_if; if pc.format_depth32float_filter { flags |= Tfc::SAMPLED_LINEAR } flags } Tf::Depth24Plus | Tf::Depth24PlusStencil8 => { - let mut flags = Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE_X4; + let mut flags = Tfc::DEPTH_STENCIL_ATTACHMENT | msaa_count; if pc.format_depth24_stencil8 { flags |= Tfc::SAMPLED_LINEAR | Tfc::MULTISAMPLE_RESOLVE } else { @@ -215,7 +210,7 @@ impl crate::Adapter for super::Adapter { Tfc::SAMPLED_LINEAR | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND - | Tfc::MULTISAMPLE_X4 + | msaa_count | Tfc::MULTISAMPLE_RESOLVE } } @@ -267,11 +262,7 @@ impl crate::Adapter for super::Adapter { } }; - Tfc::COPY_SRC - | Tfc::COPY_DST - | Tfc::SAMPLED - | extra - | self.shared.private_caps.sample_count_mask + Tfc::COPY_SRC | Tfc::COPY_DST | Tfc::SAMPLED | extra } unsafe fn surface_capabilities( diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 2522914ad2..0b2c3963c0 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1656,14 +1656,13 @@ impl TextureFormatFeatureFlags { pub fn sample_count_supported(&self, count: u32) -> bool { use TextureFormatFeatureFlags as tfsc; - if count == 1 - || (count == 2 && self.contains(tfsc::MULTISAMPLE_X2)) - || (count == 4 && self.contains(tfsc::MULTISAMPLE_X4)) - || (count == 8 && self.contains(tfsc::MULTISAMPLE_X8)) - { - return true; + match count { + 1 => true, + 2 => self.contains(tfsc::MULTISAMPLE_X2), + 4 => self.contains(tfsc::MULTISAMPLE_X4), + 8 => self.contains(tfsc::MULTISAMPLE_X8), + _ => false, } - false } } diff --git a/wgpu/examples/msaa-line/main.rs b/wgpu/examples/msaa-line/main.rs index 6a5a766025..b39c144877 100644 --- a/wgpu/examples/msaa-line/main.rs +++ b/wgpu/examples/msaa-line/main.rs @@ -316,7 +316,8 @@ fn msaa_line() { image_path: "/examples/msaa-line/screenshot.png", width: 1024, height: 768, - optional_features: wgpu::Features::default(), + optional_features: wgpu::Features::default() + | wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, base_test_parameters: framework::test_common::TestParameters::default(), tolerance: 64, max_outliers: 1 << 16, // MSAA is comically different between vendors, 32k is a decent limit