diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d71f4badc..6fd4e5348e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ SurfaceConfiguration { ### Added/New Features - Add `Buffer::size()` and `Buffer::usage()`; by @kpreid in [#2923](https://github.com/gfx-rs/wgpu/pull/2923) +- Split Blendability and Filterability into Two Different TextureFormatFeatureFlags; by @stakka in [#3012](https://github.com/gfx-rs/wgpu/pull/3012) - Expose `alpha_mode` on SurfaceConfiguration, by @jinleili in [#2836](https://github.com/gfx-rs/wgpu/pull/2836) - Introduce fields for driver name and info in `AdapterInfo`, by @i509VCB in [#3037](https://github.com/gfx-rs/wgpu/pull/3037) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 1f2363e21a..a582f6733f 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -2625,7 +2625,14 @@ impl Device { { break Some(pipeline::ColorStateError::FormatNotRenderable(cs.format)); } - if cs.blend.is_some() && !format_features.flags.contains(Tfff::FILTERABLE) { + let blendable = format_features.flags.contains(Tfff::BLENDABLE); + let filterable = format_features.flags.contains(Tfff::FILTERABLE); + let adapter_specific = self + .features + .contains(wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES); + // according to WebGPU specifications the texture needs to be [`TextureFormatFeatureFlags::FILTERABLE`] + // if blending is set - use [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] to elude this limitation + if cs.blend.is_some() && (!blendable || (!filterable && !adapter_specific)) { break Some(pipeline::ColorStateError::FormatNotBlendable(cs.format)); } if !hal::FormatAspects::from(cs.format).contains(hal::FormatAspects::COLOR) { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 6fd32e9f47..f483c40925 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -249,14 +249,14 @@ impl Adapter { caps.contains(Tfc::STORAGE_READ_WRITE), ); - // We are currently taking the filtering and blending together, - // but we may reconsider this in the future if there are formats - // in the wild for which these two capabilities do not match. flags.set( wgt::TextureFormatFeatureFlags::FILTERABLE, - caps.contains(Tfc::SAMPLED_LINEAR) - && (!caps.contains(Tfc::COLOR_ATTACHMENT) - || caps.contains(Tfc::COLOR_ATTACHMENT_BLEND)), + caps.contains(Tfc::SAMPLED_LINEAR), + ); + + flags.set( + wgt::TextureFormatFeatureFlags::BLENDABLE, + caps.contains(Tfc::COLOR_ATTACHMENT_BLEND), ); flags.set( diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 4bd69850aa..3026053f17 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1662,6 +1662,8 @@ bitflags::bitflags! { /// 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; + /// If not present, the texture can't be blended into the render target. + const BLENDABLE = 1 << 5; } } @@ -2288,10 +2290,12 @@ impl TextureFormat { }; let mut flags = msaa_flags; + let filterable_sample_type = sample_type == TextureSampleType::Float { filterable: true }; flags.set( TextureFormatFeatureFlags::FILTERABLE, - sample_type == TextureSampleType::Float { filterable: true }, + filterable_sample_type, ); + flags.set(TextureFormatFeatureFlags::BLENDABLE, filterable_sample_type); TextureFormatInfo { required_features,