Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

Commit

Permalink
Support 16-bit unorm/snorm formats (#2210)
Browse files Browse the repository at this point in the history
* Support 16-bit unorm/snorm formats

* Add Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS

* Add 16-bit normalized formats to spv frontend
  • Loading branch information
fintelia authored Jan 18, 2023
1 parent 1cffd23 commit 1be8024
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 13 deletions.
6 changes: 6 additions & 0 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/back/hlsl/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,23 @@ 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",

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
Expand Down
6 changes: 6 additions & 0 deletions src/back/spv/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/back/wgsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/front/glsl/parser/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
};
Expand Down
6 changes: 6 additions & 0 deletions src/front/spv/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand Down
6 changes: 6 additions & 0 deletions src/front/wgsl/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions src/front/wgsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions src/proc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions src/valid/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
4 changes: 3 additions & 1 deletion src/valid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}
}

Expand Down

0 comments on commit 1be8024

Please sign in to comment.