From 939e68fafaa01239ee03d767645e762bda544f41 Mon Sep 17 00:00:00 2001 From: Christofer Nolander Date: Fri, 29 Nov 2024 10:07:23 +0100 Subject: [PATCH] feat: add missing 8/16-bit vertex formats (and 8-bit bgra) #6614 --- wgpu-core/src/validation.rs | 11 ++-- wgpu-hal/src/auxil/dxgi/conv.rs | 10 +++ wgpu-hal/src/gles/conv.rs | 10 +++ wgpu-hal/src/metal/conv.rs | 10 +++ wgpu-hal/src/vulkan/conv.rs | 10 +++ wgpu-types/src/lib.rs | 108 +++++++++++++++++++++----------- wgpu/src/backend/webgpu.rs | 10 +++ 7 files changed, 128 insertions(+), 41 deletions(-) diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index b1c0051902..9ac2d6f787 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -640,7 +640,7 @@ impl NumericType { use wgt::VertexFormat as Vf; let (dim, scalar) = match format { - Vf::Uint32 => (NumericDimension::Scalar, Scalar::U32), + Vf::Uint8 | Vf::Uint16 | Vf::Uint32 => (NumericDimension::Scalar, Scalar::U32), Vf::Uint8x2 | Vf::Uint16x2 | Vf::Uint32x2 => { (NumericDimension::Vector(Vs::Bi), Scalar::U32) } @@ -648,7 +648,7 @@ impl NumericType { Vf::Uint8x4 | Vf::Uint16x4 | Vf::Uint32x4 => { (NumericDimension::Vector(Vs::Quad), Scalar::U32) } - Vf::Sint32 => (NumericDimension::Scalar, Scalar::I32), + Vf::Sint8 | Vf::Sint16 | Vf::Sint32 => (NumericDimension::Scalar, Scalar::I32), Vf::Sint8x2 | Vf::Sint16x2 | Vf::Sint32x2 => { (NumericDimension::Vector(Vs::Bi), Scalar::I32) } @@ -656,7 +656,9 @@ impl NumericType { Vf::Sint8x4 | Vf::Sint16x4 | Vf::Sint32x4 => { (NumericDimension::Vector(Vs::Quad), Scalar::I32) } - Vf::Float32 => (NumericDimension::Scalar, Scalar::F32), + Vf::Unorm8 | Vf::Unorm16 | Vf::Snorm8 | Vf::Snorm16 | Vf::Float16 | Vf::Float32 => { + (NumericDimension::Scalar, Scalar::F32) + } Vf::Unorm8x2 | Vf::Snorm8x2 | Vf::Unorm16x2 @@ -670,7 +672,8 @@ impl NumericType { | Vf::Snorm16x4 | Vf::Float16x4 | Vf::Float32x4 - | Vf::Unorm10_10_10_2 => (NumericDimension::Vector(Vs::Quad), Scalar::F32), + | Vf::Unorm10_10_10_2 + | Vf::Unorm8x4Bgra => (NumericDimension::Vector(Vs::Quad), Scalar::F32), Vf::Float64 => (NumericDimension::Scalar, Scalar::F64), Vf::Float64x2 => (NumericDimension::Vector(Vs::Bi), Scalar::F64), Vf::Float64x3 => (NumericDimension::Vector(Vs::Tri), Scalar::F64), diff --git a/wgpu-hal/src/auxil/dxgi/conv.rs b/wgpu-hal/src/auxil/dxgi/conv.rs index 878dab39e9..f545ae21c9 100644 --- a/wgpu-hal/src/auxil/dxgi/conv.rs +++ b/wgpu-hal/src/auxil/dxgi/conv.rs @@ -234,6 +234,10 @@ pub fn map_vertex_format(format: wgt::VertexFormat) -> Dxgi::Common::DXGI_FORMAT use Dxgi::Common::*; match format { + Vf::Unorm8 => DXGI_FORMAT_R8_UNORM, + Vf::Snorm8 => DXGI_FORMAT_R8_SNORM, + Vf::Uint8 => DXGI_FORMAT_R8_UINT, + Vf::Sint8 => DXGI_FORMAT_R8_SINT, Vf::Unorm8x2 => DXGI_FORMAT_R8G8_UNORM, Vf::Snorm8x2 => DXGI_FORMAT_R8G8_SNORM, Vf::Uint8x2 => DXGI_FORMAT_R8G8_UINT, @@ -242,6 +246,11 @@ pub fn map_vertex_format(format: wgt::VertexFormat) -> Dxgi::Common::DXGI_FORMAT Vf::Snorm8x4 => DXGI_FORMAT_R8G8B8A8_SNORM, Vf::Uint8x4 => DXGI_FORMAT_R8G8B8A8_UINT, Vf::Sint8x4 => DXGI_FORMAT_R8G8B8A8_SINT, + Vf::Unorm16 => DXGI_FORMAT_R16_UNORM, + Vf::Snorm16 => DXGI_FORMAT_R16_SNORM, + Vf::Uint16 => DXGI_FORMAT_R16_UINT, + Vf::Sint16 => DXGI_FORMAT_R16_SINT, + Vf::Float16 => DXGI_FORMAT_R16_FLOAT, Vf::Unorm16x2 => DXGI_FORMAT_R16G16_UNORM, Vf::Snorm16x2 => DXGI_FORMAT_R16G16_SNORM, Vf::Uint16x2 => DXGI_FORMAT_R16G16_UINT, @@ -265,6 +274,7 @@ pub fn map_vertex_format(format: wgt::VertexFormat) -> Dxgi::Common::DXGI_FORMAT Vf::Sint32x4 => DXGI_FORMAT_R32G32B32A32_SINT, Vf::Float32x4 => DXGI_FORMAT_R32G32B32A32_FLOAT, Vf::Unorm10_10_10_2 => DXGI_FORMAT_R10G10B10A2_UNORM, + Vf::Unorm8x4Bgra => DXGI_FORMAT_B8G8R8A8_UNORM, Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(), } } diff --git a/wgpu-hal/src/gles/conv.rs b/wgpu-hal/src/gles/conv.rs index 3a6d5ebb2e..b5461b126b 100644 --- a/wgpu-hal/src/gles/conv.rs +++ b/wgpu-hal/src/gles/conv.rs @@ -182,6 +182,10 @@ pub(super) fn describe_vertex_format(vertex_format: wgt::VertexFormat) -> super: use wgt::VertexFormat as Vf; let (element_count, element_format, attrib_kind) = match vertex_format { + Vf::Unorm8 => (1, glow::UNSIGNED_BYTE, Vak::Float), + Vf::Snorm8 => (1, glow::BYTE, Vak::Float), + Vf::Uint8 => (1, glow::UNSIGNED_BYTE, Vak::Integer), + Vf::Sint8 => (1, glow::BYTE, Vak::Integer), Vf::Unorm8x2 => (2, glow::UNSIGNED_BYTE, Vak::Float), Vf::Snorm8x2 => (2, glow::BYTE, Vak::Float), Vf::Uint8x2 => (2, glow::UNSIGNED_BYTE, Vak::Integer), @@ -190,6 +194,11 @@ pub(super) fn describe_vertex_format(vertex_format: wgt::VertexFormat) -> super: Vf::Snorm8x4 => (4, glow::BYTE, Vak::Float), Vf::Uint8x4 => (4, glow::UNSIGNED_BYTE, Vak::Integer), Vf::Sint8x4 => (4, glow::BYTE, Vak::Integer), + Vf::Unorm16 => (1, glow::UNSIGNED_SHORT, Vak::Float), + Vf::Snorm16 => (1, glow::SHORT, Vak::Float), + Vf::Uint16 => (1, glow::UNSIGNED_SHORT, Vak::Integer), + Vf::Sint16 => (1, glow::SHORT, Vak::Integer), + Vf::Float16 => (1, glow::HALF_FLOAT, Vak::Float), Vf::Unorm16x2 => (2, glow::UNSIGNED_SHORT, Vak::Float), Vf::Snorm16x2 => (2, glow::SHORT, Vak::Float), Vf::Uint16x2 => (2, glow::UNSIGNED_SHORT, Vak::Integer), @@ -213,6 +222,7 @@ pub(super) fn describe_vertex_format(vertex_format: wgt::VertexFormat) -> super: Vf::Sint32x4 => (4, glow::INT, Vak::Integer), Vf::Float32x4 => (4, glow::FLOAT, Vak::Float), Vf::Unorm10_10_10_2 => (4, glow::UNSIGNED_INT_10_10_10_2, Vak::Float), + Vf::Unorm8x4Bgra => (4, glow::BGRA, Vak::Float), Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(), }; diff --git a/wgpu-hal/src/metal/conv.rs b/wgpu-hal/src/metal/conv.rs index 6ebabee1a6..9282519c7e 100644 --- a/wgpu-hal/src/metal/conv.rs +++ b/wgpu-hal/src/metal/conv.rs @@ -192,6 +192,10 @@ pub fn map_vertex_format(format: wgt::VertexFormat) -> metal::MTLVertexFormat { use wgt::VertexFormat as Vf; match format { + Vf::Unorm8 => UCharNormalized, + Vf::Snorm8 => CharNormalized, + Vf::Uint8 => UChar, + Vf::Sint8 => Char, Vf::Unorm8x2 => UChar2Normalized, Vf::Snorm8x2 => Char2Normalized, Vf::Uint8x2 => UChar2, @@ -200,6 +204,11 @@ pub fn map_vertex_format(format: wgt::VertexFormat) -> metal::MTLVertexFormat { Vf::Snorm8x4 => Char4Normalized, Vf::Uint8x4 => UChar4, Vf::Sint8x4 => Char4, + Vf::Unorm16 => UShortNormalized, + Vf::Snorm16 => ShortNormalized, + Vf::Uint16 => UShort, + Vf::Sint16 => Short, + Vf::Float16 => Half, Vf::Unorm16x2 => UShort2Normalized, Vf::Snorm16x2 => Short2Normalized, Vf::Uint16x2 => UShort2, @@ -223,6 +232,7 @@ pub fn map_vertex_format(format: wgt::VertexFormat) -> metal::MTLVertexFormat { Vf::Sint32x4 => Int4, Vf::Float32x4 => Float4, Vf::Unorm10_10_10_2 => UInt1010102Normalized, + Vf::Unorm8x4Bgra => UChar4Normalized_BGRA, Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(), } } diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 75b807a29c..bfca1ea98d 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -365,22 +365,31 @@ pub fn map_index_format(index_format: wgt::IndexFormat) -> vk::IndexType { pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> vk::Format { use wgt::VertexFormat as Vf; match vertex_format { + Vf::Uint8 => vk::Format::R8_UINT, Vf::Uint8x2 => vk::Format::R8G8_UINT, Vf::Uint8x4 => vk::Format::R8G8B8A8_UINT, + Vf::Sint8 => vk::Format::R8_SINT, Vf::Sint8x2 => vk::Format::R8G8_SINT, Vf::Sint8x4 => vk::Format::R8G8B8A8_SINT, + Vf::Unorm8 => vk::Format::R8_UNORM, Vf::Unorm8x2 => vk::Format::R8G8_UNORM, Vf::Unorm8x4 => vk::Format::R8G8B8A8_UNORM, + Vf::Snorm8 => vk::Format::R8_SNORM, Vf::Snorm8x2 => vk::Format::R8G8_SNORM, Vf::Snorm8x4 => vk::Format::R8G8B8A8_SNORM, + Vf::Uint16 => vk::Format::R16_UINT, Vf::Uint16x2 => vk::Format::R16G16_UINT, Vf::Uint16x4 => vk::Format::R16G16B16A16_UINT, + Vf::Sint16 => vk::Format::R16_SINT, Vf::Sint16x2 => vk::Format::R16G16_SINT, Vf::Sint16x4 => vk::Format::R16G16B16A16_SINT, + Vf::Unorm16 => vk::Format::R16_UNORM, Vf::Unorm16x2 => vk::Format::R16G16_UNORM, Vf::Unorm16x4 => vk::Format::R16G16B16A16_UNORM, + Vf::Snorm16 => vk::Format::R16_SNORM, Vf::Snorm16x2 => vk::Format::R16G16_SNORM, Vf::Snorm16x4 => vk::Format::R16G16B16A16_SNORM, + Vf::Float16 => vk::Format::R16_SFLOAT, Vf::Float16x2 => vk::Format::R16G16_SFLOAT, Vf::Float16x4 => vk::Format::R16G16B16A16_SFLOAT, Vf::Float32 => vk::Format::R32_SFLOAT, @@ -400,6 +409,7 @@ pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> vk::Format { Vf::Float64x3 => vk::Format::R64G64B64_SFLOAT, Vf::Float64x4 => vk::Format::R64G64B64A64_SFLOAT, Vf::Unorm10_10_10_2 => vk::Format::A2B10G10R10_UNORM_PACK32, + Vf::Unorm8x4Bgra => vk::Format::B8G8R8A8_UNORM, } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ec05e86e43..74b8415efe 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -5165,77 +5165,98 @@ pub struct VertexAttribute { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum VertexFormat { + /// One unsigned byte (u8). `u32` in shaders. + Uint8 = 0, /// Two unsigned bytes (u8). `vec2` in shaders. - Uint8x2 = 0, + Uint8x2 = 1, /// Four unsigned bytes (u8). `vec4` in shaders. - Uint8x4 = 1, + Uint8x4 = 2, + /// One signed byte (i8). `i32` in shaders. + Sint8 = 3, /// Two signed bytes (i8). `vec2` in shaders. - Sint8x2 = 2, + Sint8x2 = 4, /// Four signed bytes (i8). `vec4` in shaders. - Sint8x4 = 3, + Sint8x4 = 5, + /// One unsigned byte (u8). [0, 255] converted to float [0, 1] `f32` in shaders. + Unorm8 = 6, /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2` in shaders. - Unorm8x2 = 4, + Unorm8x2 = 7, /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4` in shaders. - Unorm8x4 = 5, + Unorm8x4 = 8, + /// One signed byte (i8). [-127, 127] converted to float [-1, 1] `f32` in shaders. + Snorm8 = 9, /// Two signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec2` in shaders. - Snorm8x2 = 6, + Snorm8x2 = 10, /// Four signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec4` in shaders. - Snorm8x4 = 7, + Snorm8x4 = 11, + /// One unsigned short (u16). `u32` in shaders. + Uint16 = 12, /// Two unsigned shorts (u16). `vec2` in shaders. - Uint16x2 = 8, + Uint16x2 = 13, /// Four unsigned shorts (u16). `vec4` in shaders. - Uint16x4 = 9, + Uint16x4 = 14, + /// One signed short (u16). `i32` in shaders. + Sint16 = 15, /// Two signed shorts (i16). `vec2` in shaders. - Sint16x2 = 10, + Sint16x2 = 16, /// Four signed shorts (i16). `vec4` in shaders. - Sint16x4 = 11, + Sint16x4 = 17, + /// One unsigned short (u16). [0, 65535] converted to float [0, 1] `f32` in shaders. + Unorm16 = 18, /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2` in shaders. - Unorm16x2 = 12, + Unorm16x2 = 19, /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4` in shaders. - Unorm16x4 = 13, + Unorm16x4 = 20, + /// One signed short (i16). [-32767, 32767] converted to float [-1, 1] `f32` in shaders. + Snorm16 = 21, /// Two signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec2` in shaders. - Snorm16x2 = 14, + Snorm16x2 = 22, /// Four signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec4` in shaders. - Snorm16x4 = 15, + Snorm16x4 = 23, + /// One half-precision float (no Rust equiv). `f32` in shaders. + Float16 = 24, /// Two half-precision floats (no Rust equiv). `vec2` in shaders. - Float16x2 = 16, + Float16x2 = 25, /// Four half-precision floats (no Rust equiv). `vec4` in shaders. - Float16x4 = 17, + Float16x4 = 26, /// One single-precision float (f32). `f32` in shaders. - Float32 = 18, + Float32 = 27, /// Two single-precision floats (f32). `vec2` in shaders. - Float32x2 = 19, + Float32x2 = 28, /// Three single-precision floats (f32). `vec3` in shaders. - Float32x3 = 20, + Float32x3 = 29, /// Four single-precision floats (f32). `vec4` in shaders. - Float32x4 = 21, + Float32x4 = 30, /// One unsigned int (u32). `u32` in shaders. - Uint32 = 22, + Uint32 = 31, /// Two unsigned ints (u32). `vec2` in shaders. - Uint32x2 = 23, + Uint32x2 = 32, /// Three unsigned ints (u32). `vec3` in shaders. - Uint32x3 = 24, + Uint32x3 = 33, /// Four unsigned ints (u32). `vec4` in shaders. - Uint32x4 = 25, + Uint32x4 = 34, /// One signed int (i32). `i32` in shaders. - Sint32 = 26, + Sint32 = 35, /// Two signed ints (i32). `vec2` in shaders. - Sint32x2 = 27, + Sint32x2 = 36, /// Three signed ints (i32). `vec3` in shaders. - Sint32x3 = 28, + Sint32x3 = 37, /// Four signed ints (i32). `vec4` in shaders. - Sint32x4 = 29, + Sint32x4 = 38, /// One double-precision float (f64). `f32` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`]. - Float64 = 30, + Float64 = 39, /// Two double-precision floats (f64). `vec2` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`]. - Float64x2 = 31, + Float64x2 = 40, /// Three double-precision floats (f64). `vec3` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`]. - Float64x3 = 32, + Float64x3 = 41, /// Four double-precision floats (f64). `vec4` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`]. - Float64x4 = 33, + Float64x4 = 42, /// Three unsigned 10-bit integers and one 2-bit integer, packed into a 32-bit integer (u32). [0, 1024] converted to float [0, 1] `vec4` in shaders. #[cfg_attr(feature = "serde", serde(rename = "unorm10-10-10-2"))] - Unorm10_10_10_2 = 34, + Unorm10_10_10_2 = 43, + /// Four unsigned 8-bit integers, packed into a 32-bit integer (u32). [0, 255] converted to float [0, 1] `vec4` in shaders. + #[cfg_attr(feature = "serde", serde(rename = "unorm8x4-bgra"))] + Unorm8x4Bgra = 44, } impl VertexFormat { @@ -5243,7 +5264,16 @@ impl VertexFormat { #[must_use] pub const fn size(&self) -> u64 { match self { - Self::Uint8x2 | Self::Sint8x2 | Self::Unorm8x2 | Self::Snorm8x2 => 2, + Self::Uint8 | Self::Sint8 | Self::Unorm8 | Self::Snorm8 => 1, + Self::Uint8x2 + | Self::Sint8x2 + | Self::Unorm8x2 + | Self::Snorm8x2 + | Self::Uint16 + | Self::Sint16 + | Self::Unorm16 + | Self::Snorm16 + | Self::Float16 => 2, Self::Uint8x4 | Self::Sint8x4 | Self::Unorm8x4 @@ -5267,7 +5297,11 @@ impl VertexFormat { | Self::Sint32x2 | Self::Float64 => 8, Self::Float32x3 | Self::Uint32x3 | Self::Sint32x3 => 12, - Self::Float32x4 | Self::Uint32x4 | Self::Sint32x4 | Self::Float64x2 => 16, + Self::Float32x4 + | Self::Uint32x4 + | Self::Sint32x4 + | Self::Unorm8x4Bgra + | Self::Float64x2 => 16, Self::Float64x3 => 24, Self::Float64x4 => 32, } diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index ba96875066..afc573cc8a 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -534,22 +534,31 @@ fn map_vertex_format(format: wgt::VertexFormat) -> webgpu_sys::GpuVertexFormat { use webgpu_sys::GpuVertexFormat as vf; use wgt::VertexFormat; match format { + VertexFormat::Uint8 => vf::Uint8, VertexFormat::Uint8x2 => vf::Uint8x2, VertexFormat::Uint8x4 => vf::Uint8x4, + VertexFormat::Sint8 => vf::Sint8, VertexFormat::Sint8x2 => vf::Sint8x2, VertexFormat::Sint8x4 => vf::Sint8x4, + VertexFormat::Unorm8 => vf::Unorm8, VertexFormat::Unorm8x2 => vf::Unorm8x2, VertexFormat::Unorm8x4 => vf::Unorm8x4, + VertexFormat::Snorm8 => vf::Snorm8, VertexFormat::Snorm8x2 => vf::Snorm8x2, VertexFormat::Snorm8x4 => vf::Snorm8x4, + VertexFormat::Uint16 => vf::Uint16, VertexFormat::Uint16x2 => vf::Uint16x2, VertexFormat::Uint16x4 => vf::Uint16x4, + VertexFormat::Sint16 => vf::Sint16, VertexFormat::Sint16x2 => vf::Sint16x2, VertexFormat::Sint16x4 => vf::Sint16x4, + VertexFormat::Unorm16 => vf::Unorm16, VertexFormat::Unorm16x2 => vf::Unorm16x2, VertexFormat::Unorm16x4 => vf::Unorm16x4, + VertexFormat::Snorm16 => vf::Snorm16, VertexFormat::Snorm16x2 => vf::Snorm16x2, VertexFormat::Snorm16x4 => vf::Snorm16x4, + VertexFormat::Float16 => vf::Float16, VertexFormat::Float16x2 => vf::Float16x2, VertexFormat::Float16x4 => vf::Float16x4, VertexFormat::Float32 => vf::Float32, @@ -565,6 +574,7 @@ fn map_vertex_format(format: wgt::VertexFormat) -> webgpu_sys::GpuVertexFormat { VertexFormat::Sint32x3 => vf::Sint32x3, VertexFormat::Sint32x4 => vf::Sint32x4, VertexFormat::Unorm10_10_10_2 => vf::Unorm1010102, + VertexFormat::Unorm8x4Bgra => vf::Unorm8x4Bgra, VertexFormat::Float64 | VertexFormat::Float64x2 | VertexFormat::Float64x3