mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Support 16-bit unorm/snorm formats (#2210)
* Support 16-bit unorm/snorm formats * Add Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS * Add 16-bit normalized formats to spv frontend
This commit is contained in:
@@ -3849,6 +3849,12 @@ const fn glsl_storage_format(format: crate::StorageFormat) -> &'static str {
|
||||
Sf::Rgba32Uint => "rgba32ui",
|
||||
Sf::Rgba32Sint => "rgba32i",
|
||||
Sf::Rgba32Float => "rgba32f",
|
||||
Sf::R16Unorm => "r16",
|
||||
Sf::R16Snorm => "r16_snorm",
|
||||
Sf::Rg16Unorm => "rg16",
|
||||
Sf::Rg16Snorm => "rg16_snorm",
|
||||
Sf::Rgba16Unorm => "rgba16",
|
||||
Sf::Rgba16Snorm => "rgba16_snorm",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,14 +115,14 @@ impl crate::StorageFormat {
|
||||
pub(super) const fn to_hlsl_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::R16Float => "float",
|
||||
Self::R8Unorm => "unorm float",
|
||||
Self::R8Snorm => "snorm float",
|
||||
Self::R8Unorm | Self::R16Unorm => "unorm float",
|
||||
Self::R8Snorm | Self::R16Snorm => "snorm float",
|
||||
Self::R8Uint | Self::R16Uint => "uint",
|
||||
Self::R8Sint | Self::R16Sint => "int",
|
||||
|
||||
Self::Rg16Float => "float2",
|
||||
Self::Rg8Unorm => "unorm float2",
|
||||
Self::Rg8Snorm => "snorm float2",
|
||||
Self::Rg8Unorm | Self::Rg16Unorm => "unorm float2",
|
||||
Self::Rg8Snorm | Self::Rg16Snorm => "snorm float2",
|
||||
|
||||
Self::Rg8Sint | Self::Rg16Sint => "int2",
|
||||
Self::Rg8Uint | Self::Rg16Uint => "uint2",
|
||||
@@ -130,8 +130,8 @@ impl crate::StorageFormat {
|
||||
Self::Rg11b10Float => "float3",
|
||||
|
||||
Self::Rgba16Float | Self::R32Float | Self::Rg32Float | Self::Rgba32Float => "float4",
|
||||
Self::Rgba8Unorm | Self::Rgb10a2Unorm => "unorm float4",
|
||||
Self::Rgba8Snorm => "snorm float4",
|
||||
Self::Rgba8Unorm | Self::Rgba16Unorm | Self::Rgb10a2Unorm => "unorm float4",
|
||||
Self::Rgba8Snorm | Self::Rgba16Snorm => "snorm float4",
|
||||
|
||||
Self::Rgba8Uint
|
||||
| Self::Rgba16Uint
|
||||
|
||||
@@ -979,6 +979,12 @@ impl From<crate::StorageFormat> for spirv::ImageFormat {
|
||||
Sf::Rgba32Uint => Self::Rgba32ui,
|
||||
Sf::Rgba32Sint => Self::Rgba32i,
|
||||
Sf::Rgba32Float => Self::Rgba32f,
|
||||
Sf::R16Unorm => Self::R16,
|
||||
Sf::R16Snorm => Self::R16Snorm,
|
||||
Sf::Rg16Unorm => Self::Rg16,
|
||||
Sf::Rg16Snorm => Self::Rg16Snorm,
|
||||
Sf::Rgba16Unorm => Self::Rgba16,
|
||||
Sf::Rgba16Snorm => Self::Rgba16Snorm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1987,6 +1987,12 @@ const fn storage_format_str(format: crate::StorageFormat) -> &'static str {
|
||||
Sf::Rgba32Uint => "rgba32uint",
|
||||
Sf::Rgba32Sint => "rgba32sint",
|
||||
Sf::Rgba32Float => "rgba32float",
|
||||
Sf::R16Unorm => "r16unorm",
|
||||
Sf::R16Snorm => "r16snorm",
|
||||
Sf::Rg16Unorm => "rg16unorm",
|
||||
Sf::Rg16Snorm => "rg16snorm",
|
||||
Sf::Rgba16Unorm => "rgba16unorm",
|
||||
Sf::Rgba16Snorm => "rgba16snorm",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -385,15 +385,18 @@ fn map_image_format(word: &str) -> Option<crate::StorageFormat> {
|
||||
"r11f_g11f_b10f" => Sf::Rg11b10Float,
|
||||
"r32f" => Sf::R32Float,
|
||||
"r16f" => Sf::R16Float,
|
||||
"rgba16" => Sf::Rgba16Float,
|
||||
"rgba16" => Sf::Rgba16Unorm,
|
||||
"rgb10_a2" => Sf::Rgb10a2Unorm,
|
||||
"rgba8" => Sf::Rgba8Unorm,
|
||||
"rg16" => Sf::Rg16Float,
|
||||
"rg16" => Sf::Rg16Unorm,
|
||||
"rg8" => Sf::Rg8Unorm,
|
||||
"r16" => Sf::R16Float,
|
||||
"r16" => Sf::R16Unorm,
|
||||
"r8" => Sf::R8Unorm,
|
||||
"rgba16_snorm" => Sf::Rgba16Snorm,
|
||||
"rgba8_snorm" => Sf::Rgba8Snorm,
|
||||
"rg16_snorm" => Sf::Rg16Snorm,
|
||||
"rg8_snorm" => Sf::Rg8Snorm,
|
||||
"r16_snorm" => Sf::R16Snorm,
|
||||
"r8_snorm" => Sf::R8Snorm,
|
||||
// int-image-format-qualifier:
|
||||
"rgba32i" => Sf::Rgba32Sint,
|
||||
@@ -416,9 +419,6 @@ fn map_image_format(word: &str) -> Option<crate::StorageFormat> {
|
||||
"r16ui" => Sf::R16Uint,
|
||||
"r8ui" => Sf::R8Uint,
|
||||
// TODO: These next ones seem incorrect to me
|
||||
// "rgba16_snorm" => Sf::Rgba16Float,
|
||||
// "rg16_snorm" => Sf::Rg16Float,
|
||||
// "r16_snorm" => Sf::R16Float,
|
||||
// "rgb10_a2ui" => Sf::Rgb10a2Unorm,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
@@ -84,6 +84,8 @@ pub(super) fn map_image_format(word: spirv::Word) -> Result<crate::StorageFormat
|
||||
Some(spirv::ImageFormat::R8Snorm) => Ok(crate::StorageFormat::R8Snorm),
|
||||
Some(spirv::ImageFormat::R8ui) => Ok(crate::StorageFormat::R8Uint),
|
||||
Some(spirv::ImageFormat::R8i) => Ok(crate::StorageFormat::R8Sint),
|
||||
Some(spirv::ImageFormat::R16) => Ok(crate::StorageFormat::R16Unorm),
|
||||
Some(spirv::ImageFormat::R16Snorm) => Ok(crate::StorageFormat::R16Snorm),
|
||||
Some(spirv::ImageFormat::R16ui) => Ok(crate::StorageFormat::R16Uint),
|
||||
Some(spirv::ImageFormat::R16i) => Ok(crate::StorageFormat::R16Sint),
|
||||
Some(spirv::ImageFormat::R16f) => Ok(crate::StorageFormat::R16Float),
|
||||
@@ -94,6 +96,8 @@ pub(super) fn map_image_format(word: spirv::Word) -> Result<crate::StorageFormat
|
||||
Some(spirv::ImageFormat::R32ui) => Ok(crate::StorageFormat::R32Uint),
|
||||
Some(spirv::ImageFormat::R32i) => Ok(crate::StorageFormat::R32Sint),
|
||||
Some(spirv::ImageFormat::R32f) => Ok(crate::StorageFormat::R32Float),
|
||||
Some(spirv::ImageFormat::Rg16) => Ok(crate::StorageFormat::Rg16Unorm),
|
||||
Some(spirv::ImageFormat::Rg16Snorm) => Ok(crate::StorageFormat::Rg16Snorm),
|
||||
Some(spirv::ImageFormat::Rg16ui) => Ok(crate::StorageFormat::Rg16Uint),
|
||||
Some(spirv::ImageFormat::Rg16i) => Ok(crate::StorageFormat::Rg16Sint),
|
||||
Some(spirv::ImageFormat::Rg16f) => Ok(crate::StorageFormat::Rg16Float),
|
||||
@@ -106,6 +110,8 @@ pub(super) fn map_image_format(word: spirv::Word) -> Result<crate::StorageFormat
|
||||
Some(spirv::ImageFormat::Rg32ui) => Ok(crate::StorageFormat::Rg32Uint),
|
||||
Some(spirv::ImageFormat::Rg32i) => Ok(crate::StorageFormat::Rg32Sint),
|
||||
Some(spirv::ImageFormat::Rg32f) => Ok(crate::StorageFormat::Rg32Float),
|
||||
Some(spirv::ImageFormat::Rgba16) => Ok(crate::StorageFormat::Rgba16Unorm),
|
||||
Some(spirv::ImageFormat::Rgba16Snorm) => Ok(crate::StorageFormat::Rgba16Snorm),
|
||||
Some(spirv::ImageFormat::Rgba16ui) => Ok(crate::StorageFormat::Rgba16Uint),
|
||||
Some(spirv::ImageFormat::Rgba16i) => Ok(crate::StorageFormat::Rgba16Sint),
|
||||
Some(spirv::ImageFormat::Rgba16f) => Ok(crate::StorageFormat::Rgba16Float),
|
||||
|
||||
@@ -63,6 +63,8 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat
|
||||
"r8snorm" => Sf::R8Snorm,
|
||||
"r8uint" => Sf::R8Uint,
|
||||
"r8sint" => Sf::R8Sint,
|
||||
"r16unorm" => Sf::R16Unorm,
|
||||
"r16snorm" => Sf::R16Snorm,
|
||||
"r16uint" => Sf::R16Uint,
|
||||
"r16sint" => Sf::R16Sint,
|
||||
"r16float" => Sf::R16Float,
|
||||
@@ -73,6 +75,8 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat
|
||||
"r32uint" => Sf::R32Uint,
|
||||
"r32sint" => Sf::R32Sint,
|
||||
"r32float" => Sf::R32Float,
|
||||
"rg16unorm" => Sf::Rg16Unorm,
|
||||
"rg16snorm" => Sf::Rg16Snorm,
|
||||
"rg16uint" => Sf::Rg16Uint,
|
||||
"rg16sint" => Sf::Rg16Sint,
|
||||
"rg16float" => Sf::Rg16Float,
|
||||
@@ -85,6 +89,8 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat
|
||||
"rg32uint" => Sf::Rg32Uint,
|
||||
"rg32sint" => Sf::Rg32Sint,
|
||||
"rg32float" => Sf::Rg32Float,
|
||||
"rgba16unorm" => Sf::Rgba16Unorm,
|
||||
"rgba16snorm" => Sf::Rgba16Snorm,
|
||||
"rgba16uint" => Sf::Rgba16Uint,
|
||||
"rgba16sint" => Sf::Rgba16Sint,
|
||||
"rgba16float" => Sf::Rgba16Float,
|
||||
|
||||
@@ -687,6 +687,12 @@ impl crate::StorageFormat {
|
||||
Sf::Rgba32Uint => "rgba32uint",
|
||||
Sf::Rgba32Sint => "rgba32sint",
|
||||
Sf::Rgba32Float => "rgba32float",
|
||||
Sf::R16Unorm => "r16unorm",
|
||||
Sf::R16Snorm => "r16snorm",
|
||||
Sf::Rg16Unorm => "rg16unorm",
|
||||
Sf::Rg16Snorm => "rg16snorm",
|
||||
Sf::Rgba16Unorm => "rgba16unorm",
|
||||
Sf::Rgba16Snorm => "rgba16snorm",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,6 +531,14 @@ pub enum StorageFormat {
|
||||
Rgba32Uint,
|
||||
Rgba32Sint,
|
||||
Rgba32Float,
|
||||
|
||||
// Normalized 16-bit per channel formats
|
||||
R16Unorm,
|
||||
R16Snorm,
|
||||
Rg16Unorm,
|
||||
Rg16Snorm,
|
||||
Rgba16Unorm,
|
||||
Rgba16Snorm,
|
||||
}
|
||||
|
||||
/// Sub-class of the image type.
|
||||
|
||||
@@ -52,6 +52,12 @@ impl From<super::StorageFormat> for super::ScalarKind {
|
||||
Sf::Rgba32Uint => Sk::Uint,
|
||||
Sf::Rgba32Sint => Sk::Sint,
|
||||
Sf::Rgba32Float => Sk::Float,
|
||||
Sf::R16Unorm => Sk::Float,
|
||||
Sf::R16Snorm => Sk::Float,
|
||||
Sf::Rg16Unorm => Sk::Float,
|
||||
Sf::Rg16Snorm => Sk::Float,
|
||||
Sf::Rgba16Unorm => Sk::Float,
|
||||
Sf::Rgba16Snorm => Sk::Float,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,6 +435,35 @@ impl super::Validator {
|
||||
return Err(GlobalVariableError::InvalidType(var.space));
|
||||
}
|
||||
};
|
||||
let inner_ty = match &types[var.ty].inner {
|
||||
&crate::TypeInner::BindingArray { base, .. } => &types[base].inner,
|
||||
ty => ty,
|
||||
};
|
||||
if let crate::TypeInner::Image {
|
||||
class:
|
||||
crate::ImageClass::Storage {
|
||||
format:
|
||||
crate::StorageFormat::R16Unorm
|
||||
| crate::StorageFormat::R16Snorm
|
||||
| crate::StorageFormat::Rg16Unorm
|
||||
| crate::StorageFormat::Rg16Snorm
|
||||
| crate::StorageFormat::Rgba16Unorm
|
||||
| crate::StorageFormat::Rgba16Snorm,
|
||||
..
|
||||
},
|
||||
..
|
||||
} = *inner_ty
|
||||
{
|
||||
if !self
|
||||
.capabilities
|
||||
.contains(Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS)
|
||||
{
|
||||
return Err(GlobalVariableError::UnsupportedCapability(
|
||||
Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
(TypeFlags::empty(), true)
|
||||
}
|
||||
crate::AddressSpace::Private | crate::AddressSpace::WorkGroup => {
|
||||
|
||||
@@ -87,7 +87,7 @@ bitflags::bitflags! {
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub struct Capabilities: u8 {
|
||||
pub struct Capabilities: u16 {
|
||||
/// Support for [`AddressSpace:PushConstant`].
|
||||
const PUSH_CONSTANT = 0x1;
|
||||
/// Float values with width = 8.
|
||||
@@ -104,6 +104,8 @@ bitflags::bitflags! {
|
||||
const CLIP_DISTANCE = 0x40;
|
||||
/// Support for [`Builtin::CullDistance`].
|
||||
const CULL_DISTANCE = 0x80;
|
||||
/// Support for 16-bit normalized storage texture formats.
|
||||
const STORAGE_TEXTURE_16BIT_NORM_FORMATS = 0x100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user