diff --git a/deno_webgpu/02_idl_types.js b/deno_webgpu/02_idl_types.js index a328ffe8a6..082571c90d 100644 --- a/deno_webgpu/02_idl_types.js +++ b/deno_webgpu/02_idl_types.js @@ -120,6 +120,7 @@ "texture-compression-astc", "timestamp-query", "indirect-first-instance", + "shader-f16", // extended from spec "mappable-primary-buffers", "texture-binding-array", diff --git a/deno_webgpu/src/lib.rs b/deno_webgpu/src/lib.rs index 13c5345c52..d2d0c6cf8d 100644 --- a/deno_webgpu/src/lib.rs +++ b/deno_webgpu/src/lib.rs @@ -146,6 +146,9 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { if features.contains(wgpu_types::Features::INDIRECT_FIRST_INSTANCE) { return_features.push("indirect-first-instance"); } + if features.contains(wgpu_types::Features::SHADER_FLOAT16) { + return_features.push("shader-f16") + } // extended from spec if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { @@ -306,6 +309,10 @@ impl From for wgpu_types::Features { wgpu_types::Features::INDIRECT_FIRST_INSTANCE, required_features.0.contains("indirect-first-instance"), ); + features.set( + wgpu_types::Features::SHADER_FLOAT16, + required_features.0.contains("shader-f16"), + ); // extended from spec features.set( diff --git a/deno_webgpu/webgpu.idl b/deno_webgpu/webgpu.idl index 53f48ca99b..4a00c54a94 100644 --- a/deno_webgpu/webgpu.idl +++ b/deno_webgpu/webgpu.idl @@ -90,6 +90,7 @@ enum GPUFeatureName { "texture-compression-astc", "timestamp-query", "indirect-first-instance", + "shader-f16", }; [Exposed=(Window, DedicatedWorker), SecureContext] diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 39f11d9a2b..c11c98b4cd 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -751,7 +751,8 @@ impl super::PrivateCapabilities { | F::PUSH_CONSTANTS | F::POLYGON_MODE_LINE | F::CLEAR_TEXTURE - | F::TEXTURE_FORMAT_16BIT_NORM; + | F::TEXTURE_FORMAT_16BIT_NORM + | F::SHADER_FLOAT16; features.set(F::TEXTURE_COMPRESSION_ASTC_LDR, self.format_astc); features.set(F::TEXTURE_COMPRESSION_ASTC_HDR, self.format_astc_hdr); diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 8fb81c50cc..a6ad22e5c0 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -25,6 +25,10 @@ pub struct PhysicalDeviceFeatures { depth_clip_enable: Option, multiview: Option, astc_hdr: Option, + shader_float16: Option<( + vk::PhysicalDeviceShaderFloat16Int8Features, + vk::PhysicalDevice16BitStorageFeatures, + )>, } // This is safe because the structs have `p_next: *mut c_void`, which we null out/never read. @@ -62,6 +66,10 @@ impl PhysicalDeviceFeatures { if let Some(ref mut feature) = self.astc_hdr { info = info.push_next(feature); } + if let Some((ref mut f16_i8_feature, ref mut _16bit_feature)) = self.shader_float16 { + info = info.push_next(f16_i8_feature); + info = info.push_next(_16bit_feature); + } info } @@ -326,6 +334,19 @@ impl PhysicalDeviceFeatures { } else { None }, + shader_float16: if requested_features.contains(wgt::Features::SHADER_FLOAT16) { + Some(( + vk::PhysicalDeviceShaderFloat16Int8Features::builder() + .shader_float16(true) + .build(), + vk::PhysicalDevice16BitStorageFeatures::builder() + .storage_buffer16_bit_access(true) + .uniform_and_storage_buffer16_bit_access(true) + .build(), + )) + } else { + None + }, } } @@ -531,6 +552,15 @@ impl PhysicalDeviceFeatures { ); } + if let Some((ref f16_i8, ref bit16)) = self.shader_float16 { + features.set( + F::SHADER_FLOAT16, + f16_i8.shader_float16 != 0 + && bit16.storage_buffer16_bit_access != 0 + && bit16.uniform_and_storage_buffer16_bit_access != 0, + ); + } + (features, dl_flags) } @@ -642,7 +672,12 @@ impl PhysicalDeviceCapabilities { extensions.push(vk::KhrPortabilitySubsetFn::name()); if requested_features.contains(wgt::Features::TEXTURE_COMPRESSION_ASTC_HDR) { - extensions.push(vk::ExtTextureCompressionAstcHdrFn::name()) + extensions.push(vk::ExtTextureCompressionAstcHdrFn::name()); + } + + if requested_features.contains(wgt::Features::SHADER_FLOAT16) { + extensions.push(vk::KhrShaderFloat16Int8Fn::name()); + extensions.push(vk::Khr16bitStorageFn::name()); } extensions @@ -883,6 +918,16 @@ impl super::InstanceShared { .insert(vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT::default()); builder = builder.push_next(next); } + if capabilities.supports_extension(vk::KhrShaderFloat16Int8Fn::name()) + && capabilities.supports_extension(vk::Khr16bitStorageFn::name()) + { + let next = features.shader_float16.insert(( + vk::PhysicalDeviceShaderFloat16Int8FeaturesKHR::default(), + vk::PhysicalDevice16BitStorageFeaturesKHR::default(), + )); + builder = builder.push_next(&mut next.0); + builder = builder.push_next(&mut next.1); + } let mut features2 = builder.build(); unsafe { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index d82a05e334..9277eb16ab 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -241,6 +241,16 @@ bitflags::bitflags! { /// /// This is a web and native feature. const PIPELINE_STATISTICS_QUERY = 1 << 4; + /// Allows shaders to acquire the FP16 ability + /// + /// Note: this is not supported in naga yet,only through spir-v passthrough right now. + /// + /// Supported Platforms: + /// - Vulkan + /// - Metal + /// + /// This is a web and native feature. + const SHADER_FLOAT16 = 1 << 5; /// Webgpu only allows the MAP_READ and MAP_WRITE buffer usage to be matched with /// COPY_DST and COPY_SRC respectively. This removes this requirement. ///