Skip to content

Commit

Permalink
Add BGRA8UNORM_STORAGE extension
Browse files Browse the repository at this point in the history
  • Loading branch information
jinleili committed Apr 17, 2023
1 parent bf8e6fe commit 5125578
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 9 deletions.
1 change: 1 addition & 0 deletions deno_webgpu/02_idl_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ webidl.converters["GPUFeatureName"] = webidl.createEnumConverter(
"texture-compression-bc",
"texture-compression-etc2",
"texture-compression-astc",
"bgra8unorm-storage",

// extended from spec

Expand Down
7 changes: 7 additions & 0 deletions deno_webgpu/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -404,6 +407,10 @@ impl From<GpuRequiredFeatures> 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

Expand Down
4 changes: 2 additions & 2 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ impl<A: HalApi> Device<A> {
let missing_allowed_usages = desc.usage - format_features.allowed_usages;
if !missing_allowed_usages.is_empty() {
// detect downlevel incompatibilities
let wgpu_allowed_usages = desc.format.guaranteed_format_features().allowed_usages;
let wgpu_allowed_usages = desc.format.guaranteed_format_features(self.features).allowed_usages;
let wgpu_missing_usages = desc.usage - wgpu_allowed_usages;
return Err(CreateTextureError::InvalidFormatUsages(
missing_allowed_usages,
Expand Down Expand Up @@ -3252,7 +3252,7 @@ impl<A: HalApi> Device<A> {
if using_device_features || downlevel {
Ok(adapter.get_texture_format_features(format))
} else {
Ok(format.guaranteed_format_features())
Ok(format.guaranteed_format_features(self.features))
}
}

Expand Down
23 changes: 22 additions & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};

Expand Down Expand Up @@ -243,6 +245,25 @@ 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::<d3d12_ty::D3D12_FEATURE_DATA_FORMAT_SUPPORT>() as _,
)
};
hr == 0
&& (bgra8unorm_info.Support2 & d3d12_ty::D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE != 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();

Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
23 changes: 20 additions & 3 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,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;
Expand Down Expand Up @@ -2712,7 +2724,7 @@ impl TextureFormat {
/// Returns the format features guaranteed by the WebGPU spec.
///
/// Additional features are available if `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled.
pub fn guaranteed_format_features(&self) -> TextureFormatFeatures {
pub fn guaranteed_format_features(&self, device_features: Features) -> TextureFormatFeatures {
// Multisampling
let noaa = TextureFormatFeatureFlags::empty();
let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4;
Expand All @@ -2724,6 +2736,11 @@ impl TextureFormat {
let attachment = basic | TextureUsages::RENDER_ATTACHMENT;
let storage = basic | TextureUsages::STORAGE_BINDING;
let all_flags = TextureUsages::all();
let bgra8unorm = if device_features.contains(Features::BGRA8UNORM_STORAGE) {
attachment | TextureUsages::STORAGE_BINDING
} else {
attachment
};

#[rustfmt::skip] // lets make a nice table
let (
Expand Down Expand Up @@ -2752,7 +2769,7 @@ impl TextureFormat {
Self::Rgba8Snorm => ( noaa, storage),
Self::Rgba8Uint => ( msaa, all_flags),
Self::Rgba8Sint => ( msaa, all_flags),
Self::Bgra8Unorm => (msaa_resolve, attachment),
Self::Bgra8Unorm => (msaa_resolve, bgra8unorm),
Self::Bgra8UnormSrgb => (msaa_resolve, attachment),
Self::Rgb10a2Unorm => (msaa_resolve, attachment),
Self::Rg11b10Float => ( msaa, basic),
Expand Down
8 changes: 6 additions & 2 deletions wgpu/src/backend/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ fn map_map_mode(mode: crate::MapMode) -> u32 {
}
}

const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 9] = [
const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 10] = [
//TODO: update the name
(
wgt::Features::DEPTH_CLIP_CONTROL,
Expand Down Expand Up @@ -659,6 +659,10 @@ const FEATURES_MAPPING: [(wgt::Features, web_sys::GpuFeatureName); 9] = [
wgt::Features::RG11B10UFLOAT_RENDERABLE,
web_sys::GpuFeatureName::Rg11b10ufloatRenderable,
),
(
wgt::Features::BGRA8UNORM_STORAGE,
web_sys::GpuFeatureName::Bgra8unormStorage,
),
];

fn map_wgt_features(supported_features: web_sys::GpuSupportedFeatures) -> wgt::Features {
Expand Down Expand Up @@ -1099,7 +1103,7 @@ impl crate::context::Context for Context {
_adapter_data: &Self::AdapterData,
format: wgt::TextureFormat,
) -> wgt::TextureFormatFeatures {
format.guaranteed_format_features()
format.guaranteed_format_features(wgt::Features::empty())
}

fn adapter_get_presentation_timestamp(
Expand Down

0 comments on commit 5125578

Please sign in to comment.