From a97ec9df91271078646199a88805cf860aa99bd4 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sun, 24 Jan 2021 21:59:09 -0500 Subject: [PATCH] Add SHADER_FLOAT64 feature (#1154) * Add SHADER_FLOAT64 feature * Also enable SHADER_FLOAT64 hal feature when creating the device * Update wgpu-core/src/instance.rs Co-authored-by: monocodus[bot] <49363530+monocodus[bot]@users.noreply.github.com> * Add warning about 64-bit float performance * Add (currently unsupported) VERTEX_ATTRIBUTE_64BIT feature Co-authored-by: monocodus[bot] <49363530+monocodus[bot]@users.noreply.github.com> --- wgpu-core/src/conv.rs | 4 ++++ wgpu-core/src/device/mod.rs | 13 +++++++++++ wgpu-core/src/instance.rs | 8 +++++++ wgpu-core/src/validation.rs | 44 ++++++++++++++++++++----------------- wgpu-types/src/lib.rs | 33 ++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 22ba707eae..28289357b7 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -496,6 +496,10 @@ pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> hal::format::Forma Vf::Int2 => H::Rg32Sint, Vf::Int3 => H::Rgb32Sint, Vf::Int4 => H::Rgba32Sint, + Vf::Double => H::R64Sfloat, + Vf::Double2 => H::Rg64Sfloat, + Vf::Double3 => H::Rgb64Sfloat, + Vf::Double4 => H::Rgba64Sfloat, } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 83bede8b50..7399fdc95f 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1948,6 +1948,19 @@ impl Device { }, ); } + + if let wgt::VertexFormat::Double + | wgt::VertexFormat::Double2 + | wgt::VertexFormat::Double3 + | wgt::VertexFormat::Double4 = attribute.format + { + if !self.features.contains(wgt::Features::VERTEX_ATTRIBUTE_64BIT) { + return Err(pipeline::CreateRenderPipelineError::MissingFeature( + wgt::Features::VERTEX_ATTRIBUTE_64BIT, + )); + } + } + attributes.alloc().init(hal::pso::AttributeDesc { location: attribute.shader_location, binding: i as u32, diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 0b2b34b29c..d346c3e158 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -188,6 +188,10 @@ impl Adapter { wgt::Features::PIPELINE_STATISTICS_QUERY, adapter_features.contains(hal::Features::PIPELINE_STATISTICS_QUERY), ); + features.set( + wgt::Features::SHADER_FLOAT64, + adapter_features.contains(hal::Features::SHADER_FLOAT64), + ); #[cfg(not(target_os = "ios"))] //TODO: https://github.com/gfx-rs/gfx/issues/3346 features.set(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true); @@ -435,6 +439,10 @@ impl Adapter { desc.features .contains(wgt::Features::PIPELINE_STATISTICS_QUERY), ); + enabled_features.set( + hal::Features::SHADER_FLOAT64, + desc.features.contains(wgt::Features::SHADER_FLOAT64), + ); let family = self .raw diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 10bafedce3..eb923b7e88 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -520,29 +520,33 @@ impl NumericType { use naga::{ScalarKind as Sk, VectorSize as Vs}; use wgt::VertexFormat as Vf; - let (dim, kind) = match format { - Vf::Uchar2 | Vf::Ushort2 => (NumericDimension::Vector(Vs::Bi), Sk::Uint), - Vf::Uchar4 | Vf::Ushort4 => (NumericDimension::Vector(Vs::Quad), Sk::Uint), - Vf::Char2 | Vf::Short2 => (NumericDimension::Vector(Vs::Bi), Sk::Sint), - Vf::Char4 | Vf::Short4 => (NumericDimension::Vector(Vs::Quad), Sk::Sint), + let (dim, kind, width) = match format { + Vf::Uchar2 | Vf::Ushort2 => (NumericDimension::Vector(Vs::Bi), Sk::Uint, 4), + Vf::Uchar4 | Vf::Ushort4 => (NumericDimension::Vector(Vs::Quad), Sk::Uint, 4), + Vf::Char2 | Vf::Short2 => (NumericDimension::Vector(Vs::Bi), Sk::Sint, 4), + Vf::Char4 | Vf::Short4 => (NumericDimension::Vector(Vs::Quad), Sk::Sint, 4), Vf::Uchar2Norm | Vf::Char2Norm | Vf::Ushort2Norm | Vf::Short2Norm | Vf::Half2 => { - (NumericDimension::Vector(Vs::Bi), Sk::Float) + (NumericDimension::Vector(Vs::Bi), Sk::Float, 4) } Vf::Uchar4Norm | Vf::Char4Norm | Vf::Ushort4Norm | Vf::Short4Norm | Vf::Half4 => { - (NumericDimension::Vector(Vs::Quad), Sk::Float) + (NumericDimension::Vector(Vs::Quad), Sk::Float, 4) } - Vf::Float => (NumericDimension::Scalar, Sk::Float), - Vf::Float2 => (NumericDimension::Vector(Vs::Bi), Sk::Float), - Vf::Float3 => (NumericDimension::Vector(Vs::Tri), Sk::Float), - Vf::Float4 => (NumericDimension::Vector(Vs::Quad), Sk::Float), - Vf::Uint => (NumericDimension::Scalar, Sk::Uint), - Vf::Uint2 => (NumericDimension::Vector(Vs::Bi), Sk::Uint), - Vf::Uint3 => (NumericDimension::Vector(Vs::Tri), Sk::Uint), - Vf::Uint4 => (NumericDimension::Vector(Vs::Quad), Sk::Uint), - Vf::Int => (NumericDimension::Scalar, Sk::Sint), - Vf::Int2 => (NumericDimension::Vector(Vs::Bi), Sk::Sint), - Vf::Int3 => (NumericDimension::Vector(Vs::Tri), Sk::Sint), - Vf::Int4 => (NumericDimension::Vector(Vs::Quad), Sk::Sint), + Vf::Float => (NumericDimension::Scalar, Sk::Float, 4), + Vf::Float2 => (NumericDimension::Vector(Vs::Bi), Sk::Float, 4), + Vf::Float3 => (NumericDimension::Vector(Vs::Tri), Sk::Float, 4), + Vf::Float4 => (NumericDimension::Vector(Vs::Quad), Sk::Float, 4), + Vf::Uint => (NumericDimension::Scalar, Sk::Uint, 4), + Vf::Uint2 => (NumericDimension::Vector(Vs::Bi), Sk::Uint, 4), + Vf::Uint3 => (NumericDimension::Vector(Vs::Tri), Sk::Uint, 4), + Vf::Uint4 => (NumericDimension::Vector(Vs::Quad), Sk::Uint, 4), + Vf::Int => (NumericDimension::Scalar, Sk::Sint, 4), + Vf::Int2 => (NumericDimension::Vector(Vs::Bi), Sk::Sint, 4), + Vf::Int3 => (NumericDimension::Vector(Vs::Tri), Sk::Sint, 4), + Vf::Int4 => (NumericDimension::Vector(Vs::Quad), Sk::Sint, 4), + Vf::Double => (NumericDimension::Scalar, Sk::Float, 8), + Vf::Double2 => (NumericDimension::Vector(Vs::Bi), Sk::Float, 8), + Vf::Double3 => (NumericDimension::Vector(Vs::Tri), Sk::Float, 8), + Vf::Double4 => (NumericDimension::Vector(Vs::Quad), Sk::Float, 8), }; NumericType { @@ -550,7 +554,7 @@ impl NumericType { kind, //Note: Shader always sees data as int, uint, or float. // It doesn't know if the original is normalized in a tighter form. - width: 4, + width, } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 7320303834..cba91acb24 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -388,6 +388,24 @@ bitflags::bitflags! { /// /// This is a native-only feature. const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 0x0000_0000_1000_0000; + /// Enables 64-bit floating point types in SPIR-V shaders. + /// + /// Note: even when supported by GPU hardware, 64-bit floating point operations are + /// frequently between 16 and 64 _times_ slower than equivelent operations on 32-bit floats. + /// + /// Supported Platforms: + /// - Vulkan + /// + /// This is a native-only feature. + const SHADER_FLOAT64 = 0x0000_0000_2000_0000; + /// Enables using 64-bit types for vertex attributes. + /// + /// Requires SHADER_FLOAT64. + /// + /// Supported Platforms: N/A + /// + /// This is a native-only feature. + const VERTEX_ATTRIBUTE_64BIT = 0x0000_0000_4000_0000; /// Features which are part of the upstream WebGPU standard. const ALL_WEBGPU = 0x0000_0000_0000_FFFF; /// Features that are only available when targeting native (not web). @@ -1680,6 +1698,14 @@ pub enum VertexFormat { Int3 = 28, /// Four signed ints (i32). `ivec4` in shaders. Int4 = 29, + /// One double-precision float (f64). `double` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features. + Double = 30, + /// Two double-precision floats (f64). `dvec2` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features. + Double2 = 31, + /// Three double-precision floats (f64). `dvec3` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features. + Double3 = 32, + /// Four double-precision floats (f64). `dvec4` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features. + Double4 = 33, } impl VertexFormat { @@ -1705,9 +1731,12 @@ impl VertexFormat { | Self::Half4 | Self::Float2 | Self::Uint2 - | Self::Int2 => 8, + | Self::Int2 + | Self::Double => 8, Self::Float3 | Self::Uint3 | Self::Int3 => 12, - Self::Float4 | Self::Uint4 | Self::Int4 => 16, + Self::Float4 | Self::Uint4 | Self::Int4 | Self::Double2 => 16, + Self::Double3 => 24, + Self::Double4 => 32, } } }