From 8040c17ebbb4d8f0d4e528afc2157b13eefe586e Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 23 Nov 2023 14:19:03 +0100 Subject: [PATCH 01/19] Add feature float32-filterable --- deno_webgpu/01_webgpu.js | 1 + deno_webgpu/lib.rs | 7 +++++++ deno_webgpu/webgpu.idl | 1 + wgpu-hal/src/metal/adapter.rs | 7 ++++++- wgpu-hal/src/metal/mod.rs | 1 + wgpu-types/src/lib.rs | 23 +++++++++++++++++++---- wgpu/src/backend/web.rs | 4 ++++ 7 files changed, 39 insertions(+), 5 deletions(-) diff --git a/deno_webgpu/01_webgpu.js b/deno_webgpu/01_webgpu.js index 0e38aee70d..06a74ce9d7 100644 --- a/deno_webgpu/01_webgpu.js +++ b/deno_webgpu/01_webgpu.js @@ -5164,6 +5164,7 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter( "texture-compression-astc", "rg11b10ufloat-renderable", "bgra8unorm-storage", + "float32-filterable", // extended from spec diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index bf1c246ad2..b3fa484eae 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -266,6 +266,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::BGRA8UNORM_STORAGE) { return_features.push("bgra8unorm-storage"); } + if features.contains(wgpu_types::Features::FLOAT32_FILTERABLE) { + return_features.push("float32-filterable"); + } // extended from spec @@ -498,6 +501,10 @@ impl From for wgpu_types::Features { wgpu_types::Features::BGRA8UNORM_STORAGE, required_features.0.contains("bgra8unorm-storage"), ); + features.set( + wgpu_types::Features::FLOAT32_FILTERABLE, + required_features.0.contains("float32-filterable"), + ); // extended from spec diff --git a/deno_webgpu/webgpu.idl b/deno_webgpu/webgpu.idl index 0b6b04eb4e..bf4da0124b 100644 --- a/deno_webgpu/webgpu.idl +++ b/deno_webgpu/webgpu.idl @@ -103,6 +103,7 @@ enum GPUFeatureName { "shader-f16", "rg11b10ufloat-renderable", "bgra8unorm-storage", + "float32-filterable", // extended from spec diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 99efa280a1..69ffda6c9d 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -612,6 +612,7 @@ impl super::PrivateCapabilities { function_specialization: Self::supports_any(device, FUNCTION_SPECIALIZATION_SUPPORT), depth_clip_mode: Self::supports_any(device, DEPTH_CLIP_MODE), texture_cube_array: Self::supports_any(device, TEXTURE_CUBE_ARRAY_SUPPORT), + supports_float_filtering: device.supports_32bit_float_filtering(), format_depth24_stencil8: os_is_mac && device.d24_s8_supported(), format_depth32_stencil8_filter: os_is_mac, format_depth32_stencil8_none: !os_is_mac, @@ -828,7 +829,11 @@ impl super::PrivateCapabilities { | F::SHADER_F16 | F::DEPTH32FLOAT_STENCIL8 | F::BGRA8UNORM_STORAGE; - + + features.set( + F::FLOAT32_FILTERABLE, + self.supports_float_filtering, + ); features.set( F::INDIRECT_FIRST_INSTANCE | F::MULTI_DRAW_INDIRECT, self.indirect_draw_dispatch, diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 0ddf96ed4a..8890092d31 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -191,6 +191,7 @@ struct PrivateCapabilities { function_specialization: bool, depth_clip_mode: bool, texture_cube_array: bool, + supports_float_filtering: bool, format_depth24_stencil8: bool, format_depth32_stencil8_filter: bool, format_depth32_stencil8_none: bool, diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 13447bdf05..da13a521f6 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -337,7 +337,17 @@ bitflags::bitflags! { // ? const NORM16_FILTERABLE = 1 << 17; (https://github.com/gpuweb/gpuweb/issues/3839) // ? const NORM16_RESOLVE = 1 << 18; (https://github.com/gpuweb/gpuweb/issues/3839) - // TODO const FLOAT32_FILTERABLE = 1 << 19; + + /// Allows textures with formats "r32float", "rg32float", and "rgba32float" to be filterable. + /// + /// Supported Platforms: (TODO is this correct?) + /// - Vulkan + /// - DX12 + /// - Metal + /// + /// This is a web and native feature. + const FLOAT32_FILTERABLE = 1 << 19; + // ? const FLOAT32_BLENDABLE = 1 << 20; (https://github.com/gpuweb/gpuweb/issues/3556) // ? const 32BIT_FORMAT_MULTISAMPLE = 1 << 21; (https://github.com/gpuweb/gpuweb/issues/3844) // ? const 32BIT_FORMAT_RESOLVE = 1 << 22; (https://github.com/gpuweb/gpuweb/issues/3844) @@ -3068,7 +3078,7 @@ impl TextureFormat { let noaa = TextureFormatFeatureFlags::empty(); let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4; let msaa_resolve = msaa | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE; - + // Flags let basic = TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING; @@ -3172,9 +3182,14 @@ impl TextureFormat { Self::Astc { .. } => ( noaa, basic), }; + + let sample_type = self.sample_type(None); + let mut is_filterable = + sample_type == Some(TextureSampleType::Float { filterable: true }); + if device_features.contains(Features::FLOAT32_FILTERABLE) { + is_filterable |= sample_type == Some(TextureSampleType::Float { filterable: false }); + } - let is_filterable = - self.sample_type(None) == Some(TextureSampleType::Float { filterable: true }); flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable); flags.set(TextureFormatFeatureFlags::BLENDABLE, is_filterable); diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 2830ffc3f1..380968aea8 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -701,6 +701,10 @@ const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 10] = [ wgt::Features::BGRA8UNORM_STORAGE, web_sys::GpuFeatureName::Bgra8unormStorage, ), + ( + wgt::Features::FLOAT32_FILTERABLE, + web_sys::GpuFeatureName::Float32Filterable, + ), ]; fn map_wgt_features(supported_features: web_sys::GpuSupportedFeatures) -> wgt::Features { From 34ec93181c919f4637cfac729514e041b8e4bc88 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 23 Nov 2023 14:25:53 +0100 Subject: [PATCH 02/19] fmt --- deno_webgpu/lib.rs | 2 +- wgpu-hal/src/metal/adapter.rs | 7 ++----- wgpu-types/src/lib.rs | 13 ++++++------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index b3fa484eae..48dd903f98 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -268,7 +268,7 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { } if features.contains(wgpu_types::Features::FLOAT32_FILTERABLE) { return_features.push("float32-filterable"); - } + } // extended from spec diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 69ffda6c9d..05c47c148e 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -829,11 +829,8 @@ impl super::PrivateCapabilities { | F::SHADER_F16 | F::DEPTH32FLOAT_STENCIL8 | F::BGRA8UNORM_STORAGE; - - features.set( - F::FLOAT32_FILTERABLE, - self.supports_float_filtering, - ); + + features.set(F::FLOAT32_FILTERABLE, self.supports_float_filtering); features.set( F::INDIRECT_FIRST_INSTANCE | F::MULTI_DRAW_INDIRECT, self.indirect_draw_dispatch, diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index da13a521f6..4a5c37d76b 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -337,7 +337,7 @@ bitflags::bitflags! { // ? const NORM16_FILTERABLE = 1 << 17; (https://github.com/gpuweb/gpuweb/issues/3839) // ? const NORM16_RESOLVE = 1 << 18; (https://github.com/gpuweb/gpuweb/issues/3839) - + /// Allows textures with formats "r32float", "rg32float", and "rgba32float" to be filterable. /// /// Supported Platforms: (TODO is this correct?) @@ -347,7 +347,7 @@ bitflags::bitflags! { /// /// This is a web and native feature. const FLOAT32_FILTERABLE = 1 << 19; - + // ? const FLOAT32_BLENDABLE = 1 << 20; (https://github.com/gpuweb/gpuweb/issues/3556) // ? const 32BIT_FORMAT_MULTISAMPLE = 1 << 21; (https://github.com/gpuweb/gpuweb/issues/3844) // ? const 32BIT_FORMAT_RESOLVE = 1 << 22; (https://github.com/gpuweb/gpuweb/issues/3844) @@ -3078,7 +3078,7 @@ impl TextureFormat { let noaa = TextureFormatFeatureFlags::empty(); let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4; let msaa_resolve = msaa | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE; - + // Flags let basic = TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING; @@ -3182,13 +3182,12 @@ impl TextureFormat { Self::Astc { .. } => ( noaa, basic), }; - + let sample_type = self.sample_type(None); - let mut is_filterable = - sample_type == Some(TextureSampleType::Float { filterable: true }); + let mut is_filterable = sample_type == Some(TextureSampleType::Float { filterable: true }); if device_features.contains(Features::FLOAT32_FILTERABLE) { is_filterable |= sample_type == Some(TextureSampleType::Float { filterable: false }); - } + } flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable); flags.set(TextureFormatFeatureFlags::BLENDABLE, is_filterable); From e9a8dd70f4ff72f6f9a28a7ae7a12d6bd9dff149 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 24 Nov 2023 21:35:03 +0100 Subject: [PATCH 03/19] float32-filterable on gles --- wgpu-hal/src/gles/adapter.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index ed1fa9cd54..a90935b4fd 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -549,6 +549,13 @@ impl super::Adapter { ); } + features.set( + wgt::Features::FLOAT32_FILTERABLE, + extensions.contains("GL_ARB_color_buffer_float") + || extensions.contains("GL_EXT_color_buffer_float") + || extensions.contains("OES_texture_float_linear"), + ); + // We *might* be able to emulate bgra8unorm-storage but currently don't attempt to. let mut private_caps = super::PrivateCapabilities::empty(); From a1074ad50f4ef54a1e4cc0c0c3dc667c3203ec28 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 24 Nov 2023 21:46:47 +0100 Subject: [PATCH 04/19] floa32-filterable for d3d11 and d3d12 --- wgpu-hal/src/dx11/adapter.rs | 4 ++++ wgpu-hal/src/dx12/adapter.rs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/wgpu-hal/src/dx11/adapter.rs b/wgpu-hal/src/dx11/adapter.rs index 41b4b4e573..3d465ae21f 100644 --- a/wgpu-hal/src/dx11/adapter.rs +++ b/wgpu-hal/src/dx11/adapter.rs @@ -155,6 +155,10 @@ impl super::Adapter { // bgra8unorm-storage is never supported on dx11 according to: // https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware#dxgi_format_b8g8r8a8_unormfcs-87 + // float32-filterable should always be available on dx11 + // https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware#dxgi_format_r32g32b32a32_floatfcs-2 + features.set(wgt::Features::FLOAT32_FILTERABLE, true); + // // Fill out limits and alignments // diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 04295508a3..861fe57753 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -293,6 +293,9 @@ impl super::Adapter { bgra8unorm_storage_supported, ); + // float32-filterable should always be available on d3d12 + features.set(wgt::Features::FLOAT32_FILTERABLE, true); + // TODO: Determine if IPresentationManager is supported let presentation_timer = auxil::dxgi::time::PresentationTimer::new_dxgi(); From 1247f99a19c810af6fd5d8c1a48094aa4c2f6996 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 24 Nov 2023 22:01:30 +0100 Subject: [PATCH 05/19] Add for Vulkan --- wgpu-hal/src/vulkan/adapter.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 1990bb82bd..10e43cbb3c 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -535,6 +535,8 @@ impl PhysicalDeviceFeatures { supports_bgra8unorm_storage(instance, phd, caps.device_api_version), ); + features.set(F::FLOAT32_FILTERABLE, is_float32_filterable_supported(instance, phd) ); + (features, dl_flags) } @@ -1756,6 +1758,15 @@ fn is_format_16bit_norm_supported(instance: &ash::Instance, phd: vk::PhysicalDev r16unorm && r16snorm && rg16unorm && rg16snorm && rgba16unorm && rgba16snorm } +fn is_float32_filterable_supported(instance: &ash::Instance, phd: vk::PhysicalDevice) -> bool { + let tiling = vk::ImageTiling::OPTIMAL; + let features = vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_LINEAR; + let r_float = supports_format(instance, phd, vk::Format::R32_SFLOAT, tiling, features); + let rg_float = supports_format(instance, phd, vk::Format::R32G32_SFLOAT, tiling, features); + let rgba_float = supports_format(instance, phd, vk::Format::R32G32B32A32_SFLOAT, tiling, features); + r_float && rg_float && rgba_float +} + fn supports_format( instance: &ash::Instance, phd: vk::PhysicalDevice, From ee4ec411a69c34157f12dad3f7bb3bfa8b0b9c52 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 24 Nov 2023 22:28:26 +0100 Subject: [PATCH 06/19] Update description Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> --- wgpu-types/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index da13a521f6..4fc3ccd41b 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -340,10 +340,11 @@ bitflags::bitflags! { /// Allows textures with formats "r32float", "rg32float", and "rgba32float" to be filterable. /// - /// Supported Platforms: (TODO is this correct?) - /// - Vulkan + /// Supported Platforms: + /// - Vulkan (mainly on Desktop GPUs) /// - DX12 - /// - Metal + /// - Metal on macOS or Apple9+ GPUs, optional on iOS/iPadOS with Apple7/8 GPUs + /// - GL with one of `GL_ARB_color_buffer_float`/`GL_EXT_color_buffer_float`/`OES_texture_float_linear` /// /// This is a web and native feature. const FLOAT32_FILTERABLE = 1 << 19; From 7f7ae4239e14881e5bb57c5aca5c5a37db3ad218 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 24 Nov 2023 22:28:53 +0100 Subject: [PATCH 07/19] Update querying support for metal Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> --- wgpu-hal/src/metal/adapter.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 69ffda6c9d..06d2abde4a 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -612,7 +612,9 @@ impl super::PrivateCapabilities { function_specialization: Self::supports_any(device, FUNCTION_SPECIALIZATION_SUPPORT), depth_clip_mode: Self::supports_any(device, DEPTH_CLIP_MODE), texture_cube_array: Self::supports_any(device, TEXTURE_CUBE_ARRAY_SUPPORT), - supports_float_filtering: device.supports_32bit_float_filtering(), + supports_float_filtering: os_is_mac + || (version.at_least((11, 0), (14, 0), os_is_mac) + && device.supports_32bit_float_filtering()), format_depth24_stencil8: os_is_mac && device.d24_s8_supported(), format_depth32_stencil8_filter: os_is_mac, format_depth32_stencil8_none: !os_is_mac, From 3bd6c10a2c132d0c983970539d210f6648d8040d Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sat, 25 Nov 2023 22:45:50 +0100 Subject: [PATCH 08/19] fix is_blendable --- wgpu-types/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 10d36d2343..5b2e1ebef5 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -3186,12 +3186,13 @@ impl TextureFormat { let sample_type = self.sample_type(None); let mut is_filterable = sample_type == Some(TextureSampleType::Float { filterable: true }); + let is_blendable = is_filterable; if device_features.contains(Features::FLOAT32_FILTERABLE) { is_filterable |= sample_type == Some(TextureSampleType::Float { filterable: false }); } flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable); - flags.set(TextureFormatFeatureFlags::BLENDABLE, is_filterable); + flags.set(TextureFormatFeatureFlags::BLENDABLE, is_blendable); TextureFormatFeatures { allowed_usages, From 1bedb7b3e2f9bfab9b5a2fc27946f239ccba1e92 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sun, 26 Nov 2023 00:28:52 +0100 Subject: [PATCH 09/19] fmt --- wgpu-hal/src/vulkan/adapter.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 10e43cbb3c..6832a14ba7 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -535,7 +535,10 @@ impl PhysicalDeviceFeatures { supports_bgra8unorm_storage(instance, phd, caps.device_api_version), ); - features.set(F::FLOAT32_FILTERABLE, is_float32_filterable_supported(instance, phd) ); + features.set( + F::FLOAT32_FILTERABLE, + is_float32_filterable_supported(instance, phd), + ); (features, dl_flags) } @@ -1763,7 +1766,13 @@ fn is_float32_filterable_supported(instance: &ash::Instance, phd: vk::PhysicalDe let features = vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_LINEAR; let r_float = supports_format(instance, phd, vk::Format::R32_SFLOAT, tiling, features); let rg_float = supports_format(instance, phd, vk::Format::R32G32_SFLOAT, tiling, features); - let rgba_float = supports_format(instance, phd, vk::Format::R32G32B32A32_SFLOAT, tiling, features); + let rgba_float = supports_format( + instance, + phd, + vk::Format::R32G32B32A32_SFLOAT, + tiling, + features, + ); r_float && rg_float && rgba_float } From e6a90aa08c0e6b2f8c0a959cd5020d7cbe41f4a9 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sun, 26 Nov 2023 00:29:18 +0100 Subject: [PATCH 10/19] Add unit test for float32-filterable --- tests/tests/bgra8unorm_storage.rs | 2 +- tests/tests/float32_filterable.rs | 85 +++++++++++++++++++++++++++++++ tests/tests/root.rs | 1 + 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tests/tests/float32_filterable.rs diff --git a/tests/tests/bgra8unorm_storage.rs b/tests/tests/bgra8unorm_storage.rs index 5cfcb27a29..91f7b49280 100644 --- a/tests/tests/bgra8unorm_storage.rs +++ b/tests/tests/bgra8unorm_storage.rs @@ -1,4 +1,4 @@ -//! Tests for texture copy bounds checks. +//! Tests for BGRA8UNORM_STORAGE feature use std::borrow::Cow; diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs new file mode 100644 index 0000000000..b4329f8631 --- /dev/null +++ b/tests/tests/float32_filterable.rs @@ -0,0 +1,85 @@ +//! Tests for FLOAT32_FILTERABLE feature. + +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters}; + +fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, filterable: bool) { + let texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: format, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + + let view = texture.create_view(&wgpu::TextureViewDescriptor { + label: None, + format: None, + dimension: None, + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + base_array_layer: 0, + mip_level_count: Some(1), + array_layer_count: Some(1), + }); + + let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { + filterable: filterable, + }, + multisampled: false, + view_dimension: wgpu::TextureViewDimension::D2, + }, + count: None, + }], + }); + + let bg = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &bgl, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&view), + }], + }); +} + +#[gpu_test] +static FLOAT32_FILTERABLE_WITHOUT_FEATURE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default()) + .run_sync(|ctx| { + let device = &ctx.device; + // Unorm textures are always filterable + create_texture_binding(device, wgpu::TextureFormat::R8Unorm, true); + create_texture_binding(device, wgpu::TextureFormat::R8Unorm, false); + // As are float16 textures + create_texture_binding(device, wgpu::TextureFormat::R16Float, true); + create_texture_binding(device, wgpu::TextureFormat::R16Float, false); + // Float 32 textures can be used as non-filterable only + create_texture_binding(device, wgpu::TextureFormat::R32Float, false); + fail(&ctx.device, || { + create_texture_binding(device, wgpu::TextureFormat::R32Float, true); + }); + }); + +#[gpu_test] +static FLOAT32_FILTERABLE_WITH_FEATURE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().features(wgpu::Features::FLOAT32_FILTERABLE)) + .run_sync(|ctx| { + let device = &ctx.device; + // With the feature enabled, it does work! + create_texture_binding(device, wgpu::TextureFormat::R32Float, true); + create_texture_binding(device, wgpu::TextureFormat::Rg32Float, true); + create_texture_binding(device, wgpu::TextureFormat::Rgba32Float, true); + }); diff --git a/tests/tests/root.rs b/tests/tests/root.rs index fbb56a7b2f..61dfd095c2 100644 --- a/tests/tests/root.rs +++ b/tests/tests/root.rs @@ -15,6 +15,7 @@ mod create_surface_error; mod device; mod encoder; mod external_texture; +mod float32_filterable; mod instance; mod life_cycle; mod mem_leaks; From d4ce1629e8cce848de8d11d65509b825ffe7e03f Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sun, 26 Nov 2023 01:19:47 +0100 Subject: [PATCH 11/19] Fix error about unused variable --- tests/tests/float32_filterable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs index b4329f8631..98609fc0b9 100644 --- a/tests/tests/float32_filterable.rs +++ b/tests/tests/float32_filterable.rs @@ -45,7 +45,7 @@ fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, fi }], }); - let bg = device.create_bind_group(&wgpu::BindGroupDescriptor { + let _bg = device.create_bind_group(&wgpu::BindGroupDescriptor { label: None, layout: &bgl, entries: &[wgpu::BindGroupEntry { From 0bb7ec1e0ecd73aa307ccaeee7c123efb4bde00c Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sun, 26 Nov 2023 01:21:13 +0100 Subject: [PATCH 12/19] Fix more format errors --- tests/tests/float32_filterable.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs index 98609fc0b9..7967aedd0d 100644 --- a/tests/tests/float32_filterable.rs +++ b/tests/tests/float32_filterable.rs @@ -13,7 +13,7 @@ fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, fi mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: format, + format, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, view_formats: &[], }); @@ -35,9 +35,7 @@ fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, fi binding: 0, visibility: wgpu::ShaderStages::FRAGMENT, ty: wgpu::BindingType::Texture { - sample_type: wgpu::TextureSampleType::Float { - filterable: filterable, - }, + sample_type: wgpu::TextureSampleType::Float { filterable }, multisampled: false, view_dimension: wgpu::TextureViewDimension::D2, }, From 5fe75c77584bddeac24bfd725c71da75e7817931 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Tue, 28 Nov 2023 16:19:35 +0100 Subject: [PATCH 13/19] in gles backend, use float32-filterable feature instead of PrivateCapabilities --- tests/tests/float32_filterable.rs | 1 + wgpu-hal/src/gles/adapter.rs | 11 +---------- wgpu-hal/src/gles/mod.rs | 2 -- wgpu/src/backend/web.rs | 2 +- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs index 7967aedd0d..d17b122df3 100644 --- a/tests/tests/float32_filterable.rs +++ b/tests/tests/float32_filterable.rs @@ -66,6 +66,7 @@ static FLOAT32_FILTERABLE_WITHOUT_FEATURE: GpuTestConfiguration = GpuTestConfigu create_texture_binding(device, wgpu::TextureFormat::R16Float, false); // Float 32 textures can be used as non-filterable only create_texture_binding(device, wgpu::TextureFormat::R32Float, false); + // This is supposed to fail, since we have not activated the feature fail(&ctx.device, || { create_texture_binding(device, wgpu::TextureFormat::R32Float, true); }); diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index a90935b4fd..b8579c0108 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -601,14 +601,6 @@ impl super::Adapter { super::PrivateCapabilities::COLOR_BUFFER_FLOAT, color_buffer_float, ); - private_caps.set( - super::PrivateCapabilities::TEXTURE_FLOAT_LINEAR, - if full_ver.is_some() { - color_buffer_float - } else { - extensions.contains("OES_texture_float_linear") - }, - ); private_caps.set(super::PrivateCapabilities::QUERY_BUFFERS, query_buffers); private_caps.set(super::PrivateCapabilities::QUERY_64BIT, full_ver.is_some()); private_caps.set( @@ -1030,8 +1022,7 @@ impl crate::Adapter for super::Adapter { | Tfc::MULTISAMPLE_RESOLVE, ); - let texture_float_linear = - private_caps_fn(super::PrivateCapabilities::TEXTURE_FLOAT_LINEAR, filterable); + let texture_float_linear = feature_fn(wgt::Features::FLOAT32_FILTERABLE, filterable); match format { Tf::R8Unorm => filterable_renderable, diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index b071981b5b..b48db4efe4 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -186,8 +186,6 @@ bitflags::bitflags! { const COLOR_BUFFER_HALF_FLOAT = 1 << 8; /// Supports `f11/f10` and `f32` color buffers const COLOR_BUFFER_FLOAT = 1 << 9; - /// Supports linear flitering `f32` textures. - const TEXTURE_FLOAT_LINEAR = 1 << 10; /// Supports query buffer objects. const QUERY_BUFFERS = 1 << 11; /// Supports 64 bit queries via `glGetQueryObjectui64v` diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 380968aea8..ba5e3da0b3 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -659,7 +659,7 @@ fn map_map_mode(mode: crate::MapMode) -> u32 { } } -const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 10] = [ +const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 11] = [ //TODO: update the name ( wgt::Features::DEPTH_CLIP_CONTROL, From 21816236a852abb6d82f8e3c727055269dab3541 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Wed, 29 Nov 2023 09:44:45 +0100 Subject: [PATCH 14/19] Fix sample_type() --- wgpu-core/src/device/resource.rs | 7 ++++--- wgpu-hal/src/gles/command.rs | 9 ++++++++- wgpu-hal/src/gles/device.rs | 2 +- wgpu-hal/src/vulkan/adapter.rs | 5 +++-- wgpu-hal/src/vulkan/conv.rs | 3 ++- wgpu-types/src/lib.rs | 25 ++++++++++++++++--------- 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 8fc4a9abb3..31dab84e05 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -2048,7 +2048,7 @@ impl Device { .views .add_single(&*texture_view_guard, id) .ok_or(Error::InvalidTextureView(id))?; - let (pub_usage, internal_use) = Self::texture_use_parameters( + let (pub_usage, internal_use) = self.texture_use_parameters( binding, decl, view, @@ -2079,7 +2079,7 @@ impl Device { .add_single(&*texture_view_guard, id) .ok_or(Error::InvalidTextureView(id))?; let (pub_usage, internal_use) = - Self::texture_use_parameters(binding, decl, view, + self.texture_use_parameters(binding, decl, view, "SampledTextureArray, ReadonlyStorageTextureArray or WriteonlyStorageTextureArray")?; Self::create_texture_binding( view, @@ -2181,6 +2181,7 @@ impl Device { } pub(crate) fn texture_use_parameters( + self: &Arc, binding: u32, decl: &wgt::BindGroupLayoutEntry, view: &TextureView, @@ -2211,7 +2212,7 @@ impl Device { let compat_sample_type = view .desc .format - .sample_type(Some(view.desc.range.aspect)) + .sample_type(Some(view.desc.range.aspect), self.features) .unwrap(); match (sample_type, compat_sample_type) { (Tst::Uint, Tst::Uint) | diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 133e99598e..c95d3b7346 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -604,8 +604,15 @@ impl crate::CommandEncoder for super::CommandEncoder { { if !cat.ops.contains(crate::AttachmentOps::LOAD) { let c = &cat.clear_value; + let stub_device_features = wgt::Features::empty(); // Don't need the actual device features in this case self.cmd_buffer.commands.push( - match cat.target.view.format.sample_type(None).unwrap() { + match cat + .target + .view + .format + .sample_type(None, stub_device_features) + .unwrap() + { wgt::TextureSampleType::Float { .. } => C::ClearColorF { draw_buffer: i as u32, color: [c.r as f32, c.g as f32, c.b as f32, c.a as f32], diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index e610d37fb5..63702d0d97 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -746,7 +746,7 @@ impl crate::Device for super::Device { unsafe { gl.bind_texture(target, Some(raw)) }; //Note: this has to be done before defining the storage! - match desc.format.sample_type(None) { + match desc.format.sample_type(None, self.shared.features) { Some( wgt::TextureSampleType::Float { filterable: false } | wgt::TextureSampleType::Uint diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 6832a14ba7..d7294fb6e4 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1556,8 +1556,9 @@ impl crate::Adapter for super::Adapter { .framebuffer_stencil_sample_counts .min(limits.sampled_image_stencil_sample_counts) } else { - match format.sample_type(None).unwrap() { - wgt::TextureSampleType::Float { filterable: _ } => limits + let stub_device_features = wgt::Features::empty(); // Actual features not required in this case + match format.sample_type(None, stub_device_features).unwrap() { + wgt::TextureSampleType::Float { .. } => limits .framebuffer_color_sample_counts .min(limits.sampled_image_color_sample_counts), wgt::TextureSampleType::Sint | wgt::TextureSampleType::Uint => { diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index c27fdf9f72..054be68320 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -194,12 +194,13 @@ impl crate::Attachment<'_, super::Api> { impl crate::ColorAttachment<'_, super::Api> { pub(super) unsafe fn make_vk_clear_color(&self) -> vk::ClearColorValue { let cv = &self.clear_value; + let stub_device_features = wgt::Features::empty(); match self .target .view .attachment .view_format - .sample_type(None) + .sample_type(None, stub_device_features) .unwrap() { wgt::TextureSampleType::Float { .. } => vk::ClearColorValue { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 5b2e1ebef5..7d7a035e88 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -3184,12 +3184,13 @@ impl TextureFormat { Self::Astc { .. } => ( noaa, basic), }; - let sample_type = self.sample_type(None); - let mut is_filterable = sample_type == Some(TextureSampleType::Float { filterable: true }); - let is_blendable = is_filterable; - if device_features.contains(Features::FLOAT32_FILTERABLE) { - is_filterable |= sample_type == Some(TextureSampleType::Float { filterable: false }); - } + // Get whether the format is filterable, taking features into account + let sample_type1 = self.sample_type(None, device_features); + let is_filterable = sample_type1 == Some(TextureSampleType::Float { filterable: true }); + + // Features that enable filtering don't affect blendability + let sample_type2 = self.sample_type(None, Features::empty()); + let is_blendable = sample_type2 == Some(TextureSampleType::Float { filterable: true }); flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable); flags.set(TextureFormatFeatureFlags::BLENDABLE, is_blendable); @@ -3204,9 +3205,15 @@ impl TextureFormat { /// /// Returns `None` only if the format is combined depth-stencil /// and `TextureAspect::All` or no `aspect` was provided - pub fn sample_type(&self, aspect: Option) -> Option { + pub fn sample_type( + &self, + aspect: Option, + device_features: Features, + ) -> Option { let float = TextureSampleType::Float { filterable: true }; - let unfilterable_float = TextureSampleType::Float { filterable: false }; + let float32_sample_type = TextureSampleType::Float { + filterable: device_features.contains(Features::FLOAT32_FILTERABLE), + }; let depth = TextureSampleType::Depth; let uint = TextureSampleType::Uint; let sint = TextureSampleType::Sint; @@ -3227,7 +3234,7 @@ impl TextureFormat { | Self::Rgb10a2Unorm | Self::Rg11b10Float => Some(float), - Self::R32Float | Self::Rg32Float | Self::Rgba32Float => Some(unfilterable_float), + Self::R32Float | Self::Rg32Float | Self::Rgba32Float => Some(float32_sample_type), Self::R8Uint | Self::Rg8Uint From c813c4855d71448791dccfeddc3cbc9cd6693d10 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Wed, 29 Nov 2023 11:14:11 +0100 Subject: [PATCH 15/19] Fix test --- tests/tests/float32_filterable.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/tests/float32_filterable.rs b/tests/tests/float32_filterable.rs index d17b122df3..c170deda9b 100644 --- a/tests/tests/float32_filterable.rs +++ b/tests/tests/float32_filterable.rs @@ -18,16 +18,7 @@ fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, fi view_formats: &[], }); - let view = texture.create_view(&wgpu::TextureViewDescriptor { - label: None, - format: None, - dimension: None, - aspect: wgpu::TextureAspect::All, - base_mip_level: 0, - base_array_layer: 0, - mip_level_count: Some(1), - array_layer_count: Some(1), - }); + let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: None, From f6f89458f2b02ccddb77016f10b1efe442fe5e15 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 30 Nov 2023 21:56:25 +0100 Subject: [PATCH 16/19] Fix for dx12 and gl --- wgpu-core/src/device/resource.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 06fa71bc85..22b6d5eb80 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -3198,6 +3198,25 @@ impl Device { Ok(pipeline) } + pub(crate) fn get_texture_format_features( + &self, + adapter: &Adapter, + format: TextureFormat, + ) -> wgt::TextureFormatFeatures { + // Variant of adapter.get_texture_format_features that takes device features into account + use wgt::TextureFormatFeatureFlags as tfsc; + let mut format_features = adapter.get_texture_format_features(format); + if format == TextureFormat::R32Float + || format == TextureFormat::Rg32Float + || format == TextureFormat::Rgba32Float + { + if !self.features.contains(wgt::Features::FLOAT32_FILTERABLE) { + format_features.flags.set(tfsc::FILTERABLE, false); + } + } + format_features + } + pub(crate) fn describe_format_features( &self, adapter: &Adapter, @@ -3213,7 +3232,7 @@ impl Device { let downlevel = !self.downlevel.is_webgpu_compliant(); if using_device_features || downlevel { - Ok(adapter.get_texture_format_features(format)) + Ok(self.get_texture_format_features(adapter, format)) } else { Ok(format.guaranteed_format_features(self.features)) } From 757b37bd96328da6ef26e7229d018e824c8ca4a1 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 30 Nov 2023 22:08:09 +0100 Subject: [PATCH 17/19] Make second arg of sample_type() optional --- wgpu-core/src/device/resource.rs | 2 +- wgpu-hal/src/gles/command.rs | 9 +-------- wgpu-hal/src/gles/device.rs | 2 +- wgpu-hal/src/vulkan/adapter.rs | 3 +-- wgpu-hal/src/vulkan/conv.rs | 3 +-- wgpu-types/src/lib.rs | 10 ++++++---- 6 files changed, 11 insertions(+), 18 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 22b6d5eb80..52d3e76d8b 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -2227,7 +2227,7 @@ impl Device { let compat_sample_type = view .desc .format - .sample_type(Some(view.desc.range.aspect), self.features) + .sample_type(Some(view.desc.range.aspect), Some(self.features)) .unwrap(); match (sample_type, compat_sample_type) { (Tst::Uint, Tst::Uint) | diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index c95d3b7346..28dbf1688d 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -604,15 +604,8 @@ impl crate::CommandEncoder for super::CommandEncoder { { if !cat.ops.contains(crate::AttachmentOps::LOAD) { let c = &cat.clear_value; - let stub_device_features = wgt::Features::empty(); // Don't need the actual device features in this case self.cmd_buffer.commands.push( - match cat - .target - .view - .format - .sample_type(None, stub_device_features) - .unwrap() - { + match cat.target.view.format.sample_type(None, None).unwrap() { wgt::TextureSampleType::Float { .. } => C::ClearColorF { draw_buffer: i as u32, color: [c.r as f32, c.g as f32, c.b as f32, c.a as f32], diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 63702d0d97..35c6f910de 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -746,7 +746,7 @@ impl crate::Device for super::Device { unsafe { gl.bind_texture(target, Some(raw)) }; //Note: this has to be done before defining the storage! - match desc.format.sample_type(None, self.shared.features) { + match desc.format.sample_type(None, Some(self.shared.features)) { Some( wgt::TextureSampleType::Float { filterable: false } | wgt::TextureSampleType::Uint diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 80dbe38761..44092841ad 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1572,8 +1572,7 @@ impl crate::Adapter for super::Adapter { .framebuffer_stencil_sample_counts .min(limits.sampled_image_stencil_sample_counts) } else { - let stub_device_features = wgt::Features::empty(); // Actual features not required in this case - match format.sample_type(None, stub_device_features) { + match format.sample_type(None, None) { Some(wgt::TextureSampleType::Float { .. }) => limits .framebuffer_color_sample_counts .min(limits.sampled_image_color_sample_counts), diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 3827123104..70dbb5714d 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -195,13 +195,12 @@ impl crate::Attachment<'_, super::Api> { impl crate::ColorAttachment<'_, super::Api> { pub(super) unsafe fn make_vk_clear_color(&self) -> vk::ClearColorValue { let cv = &self.clear_value; - let stub_device_features = wgt::Features::empty(); match self .target .view .attachment .view_format - .sample_type(None, stub_device_features) + .sample_type(None, None) .unwrap() { wgt::TextureSampleType::Float { .. } => vk::ClearColorValue { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index b9e8a0e70a..48310309df 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -3224,11 +3224,11 @@ impl TextureFormat { }; // Get whether the format is filterable, taking features into account - let sample_type1 = self.sample_type(None, device_features); + let sample_type1 = self.sample_type(None, Some(device_features)); let is_filterable = sample_type1 == Some(TextureSampleType::Float { filterable: true }); // Features that enable filtering don't affect blendability - let sample_type2 = self.sample_type(None, Features::empty()); + let sample_type2 = self.sample_type(None, None); let is_blendable = sample_type2 == Some(TextureSampleType::Float { filterable: true }); flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable); @@ -3247,11 +3247,13 @@ impl TextureFormat { pub fn sample_type( &self, aspect: Option, - device_features: Features, + device_features: Option, ) -> Option { let float = TextureSampleType::Float { filterable: true }; let float32_sample_type = TextureSampleType::Float { - filterable: device_features.contains(Features::FLOAT32_FILTERABLE), + filterable: device_features + .unwrap_or(Features::empty()) + .contains(Features::FLOAT32_FILTERABLE), }; let depth = TextureSampleType::Depth; let uint = TextureSampleType::Uint; From a295e3e749661151134e1c042ac5ef304be1d890 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 30 Nov 2023 22:12:27 +0100 Subject: [PATCH 18/19] Add to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 881c879560..1a4fe90827 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ Previously, `DeviceExt::create_texture_with_data` only allowed data to be provid #### General - Added `DownlevelFlags::VERTEX_AND_INSTANCE_INDEX_RESPECTS_RESPECTIVE_FIRST_VALUE_IN_INDIRECT_DRAW` to know if `@builtin(vertex_index)` and `@builtin(instance_index)` will respect the `first_vertex` / `first_instance` in indirect calls. If this is not present, both will always start counting from 0. Currently enabled on all backends except DX12. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722) - No longer validate surfaces against their allowed extent range on configure. This caused warnings that were almost impossible to avoid. As before, the resulting behavior depends on the compositor. By @wumpf in [#????](https://github.com/gfx-rs/wgpu/pull/????) +- Added support for the float32-filterable feature. By @almarklein in [#4759](https://github.com/gfx-rs/wgpu/pull/4759) #### OpenGL - `@builtin(instance_index)` now properly reflects the range provided in the draw call instead of always counting from 0. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722). From f90d383fdf7c5e35da5075834238e411dc78ec37 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 30 Nov 2023 22:26:23 +0100 Subject: [PATCH 19/19] clippy --- wgpu-core/src/device/resource.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 74221bf48c..b6ee9aec07 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -3207,13 +3207,12 @@ impl Device { // Variant of adapter.get_texture_format_features that takes device features into account use wgt::TextureFormatFeatureFlags as tfsc; let mut format_features = adapter.get_texture_format_features(format); - if format == TextureFormat::R32Float + if (format == TextureFormat::R32Float || format == TextureFormat::Rg32Float - || format == TextureFormat::Rgba32Float + || format == TextureFormat::Rgba32Float) + && !self.features.contains(wgt::Features::FLOAT32_FILTERABLE) { - if !self.features.contains(wgt::Features::FLOAT32_FILTERABLE) { - format_features.flags.set(tfsc::FILTERABLE, false); - } + format_features.flags.set(tfsc::FILTERABLE, false); } format_features }