From 36b15a03b65fe0012e6839764d44a5ec1a96e958 Mon Sep 17 00:00:00 2001 From: Jinlei Li Date: Sun, 2 Apr 2023 15:43:47 +0800 Subject: [PATCH] Add `BGRA8UNORM_STORAGE` extension --- deno_webgpu/lib.rs | 7 +++++++ wgpu-core/src/device/mod.rs | 6 +++++- wgpu-hal/src/dx12/adapter.rs | 25 ++++++++++++++++++++++++- wgpu-hal/src/metal/adapter.rs | 3 ++- wgpu-hal/src/vulkan/adapter.rs | 9 +++++++++ wgpu-types/src/lib.rs | 14 +++++++++++++- wgpu/src/backend/web.rs | 4 ++++ 7 files changed, 64 insertions(+), 4 deletions(-) diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 46b9d8d14f5..4119cc14ec9 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -186,6 +186,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC) { return_features.push("texture-compression-astc"); } + if features.contains(wgpu_types::Features::BGRA8UNORM_STORAGE) { + return_features.push("bgra8unorm-storage"); + } // extended from spec @@ -404,6 +407,10 @@ impl From for wgpu_types::Features { wgpu_types::Features::TEXTURE_COMPRESSION_ASTC, required_features.0.contains("texture-compression-astc"), ); + features.set( + wgpu_types::Features::BGRA8UNORM_STORAGE, + required_features.0.contains("bgra8unorm-storage"), + ); // extended from spec diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 1b35d862e9e..50e3617c4c6 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -3240,7 +3240,11 @@ impl Device { if using_device_features || downlevel { Ok(adapter.get_texture_format_features(format)) } else { - Ok(format.guaranteed_format_features()) + let mut features = format.guaranteed_format_features(); + if self.features.contains(wgt::Features::BGRA8UNORM_STORAGE) { + features.allowed_usages |= wgt::TextureUsages::STORAGE_BINDING; + } + Ok(features) } } diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index a77484c3019..1cc4c964175 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -4,7 +4,9 @@ use crate::{ }; use std::{mem, ptr, sync::Arc, thread}; use winapi::{ - shared::{dxgi, dxgi1_2, minwindef::DWORD, windef, winerror}, + shared::{ + dxgi, dxgi1_2, dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM, minwindef::DWORD, windef, winerror, + }, um::{d3d12 as d3d12_ty, d3d12sdklayers, winuser}, }; @@ -243,6 +245,27 @@ impl super::Adapter { shader_model_support.HighestShaderModel >= d3d12_ty::D3D_SHADER_MODEL_5_1, ); + let bgra8unorm_storage_supported = { + let mut bgra8unorm_info: d3d12_ty::D3D12_FEATURE_DATA_FORMAT_SUPPORT = + unsafe { mem::zeroed() }; + bgra8unorm_info.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + let hr = unsafe { + device.CheckFeatureSupport( + d3d12_ty::D3D12_FEATURE_FORMAT_SUPPORT, + &mut bgra8unorm_info as *mut _ as *mut _, + mem::size_of::() as _, + ) + }; + hr == 0 + && (bgra8unorm_info.Support1 + & d3d12_ty::D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW + != 0) + }; + features.set( + wgt::Features::BGRA8UNORM_STORAGE, + bgra8unorm_storage_supported, + ); + // TODO: Determine if IPresentationManager is supported let presentation_timer = auxil::dxgi::time::PresentationTimer::new_dxgi(); diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index e7fb3317bd0..5830b3e8e80 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -765,7 +765,8 @@ impl super::PrivateCapabilities { | F::TEXTURE_FORMAT_16BIT_NORM | F::SHADER_F16 | F::DEPTH32FLOAT_STENCIL8 - | F::MULTI_DRAW_INDIRECT; + | F::MULTI_DRAW_INDIRECT + | F::BGRA8UNORM_STORAGE; features.set(F::TEXTURE_COMPRESSION_ASTC, self.format_astc); features.set(F::TEXTURE_COMPRESSION_ASTC_HDR, self.format_astc_hdr); diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index ab07b7f854c..44d69c19232 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -526,6 +526,15 @@ impl PhysicalDeviceFeatures { features.set(F::DEPTH32FLOAT_STENCIL8, texture_d32_s8); + let bgra8unorm_storage = supports_format( + instance, + phd, + vk::Format::B8G8R8A8_UNORM, + vk::ImageTiling::OPTIMAL, + vk::FormatFeatureFlags::STORAGE_IMAGE, + ); + features.set(F::BGRA8UNORM_STORAGE, bgra8unorm_storage); + (features, dl_flags) } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 1202882d0d7..98593b36a79 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -287,7 +287,19 @@ bitflags::bitflags! { // // ? const FORMATS_TIER_1 = 1 << 14; (https://github.com/gpuweb/gpuweb/issues/3837) // ? const RW_STORAGE_TEXTURE_TIER_1 = 1 << 15; (https://github.com/gpuweb/gpuweb/issues/3838) - // TODO const BGRA8UNORM_STORAGE = 1 << 16; + + /// Allows the [`wgpu::TextureUsages::STORAGE_BINDING`] usage on textures with format [`TextureFormat::Bgra8unorm`] + /// + /// Note: this is not supported in naga yet. + /// + /// Supported Platforms: + /// - Vulkan + /// - DX12 + /// - Metal + /// + /// This is a web and native feature. + const BGRA8UNORM_STORAGE = 1 << 16; + // ? 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; diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index bb39335d1c5..f69ce26ada4 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -583,6 +583,10 @@ const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 8] = [ wgt::Features::SHADER_F16, web_sys::GpuFeatureName::ShaderF16, ), + ( + wgt::Features::BGRA8UNORM_STORAGE, + web_sys::GpuFeatureName::Bgra8unormStorage, + ), ]; fn map_wgt_features(supported_features: web_sys::GpuSupportedFeatures) -> wgt::Features {