diff --git a/CHANGELOG.md b/CHANGELOG.md index 95c000c9b4..b92c3f02df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,6 +85,10 @@ Naga now infers the correct binding layout when a resource appears only in an as - Remove the need for dxil.dll. By @teoxoy in [#7566](https://github.com/gfx-rs/wgpu/pull/7566) +#### Vulkan + +- Use highest SPIR-V version supported by Vulkan API version. By @robamler in [#7595](https://github.com/gfx-rs/wgpu/pull/7595) + ### Bug Fixes #### Naga diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 7ac9b3629d..419f8eee50 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -123,6 +123,10 @@ pub struct PhysicalDeviceFeatures { /// Features proved by `VK_EXT_mesh_shader` mesh_shader: Option>, + + /// Features provided by `VK_KHR_shader_integer_dot_product`, promoted to Vulkan 1.3. + shader_integer_dot_product: + Option>, } impl PhysicalDeviceFeatures { @@ -187,6 +191,9 @@ impl PhysicalDeviceFeatures { if let Some(ref mut feature) = self.mesh_shader { info = info.push_next(feature); } + if let Some(ref mut feature) = self.shader_integer_dot_product { + info = info.push_next(feature); + } info } @@ -499,6 +506,16 @@ impl PhysicalDeviceFeatures { } else { None }, + shader_integer_dot_product: if device_api_version >= vk::API_VERSION_1_3 + || enabled_extensions.contains(&khr::shader_integer_dot_product::NAME) + { + Some( + vk::PhysicalDeviceShaderIntegerDotProductFeaturesKHR::default() + .shader_integer_dot_product(private_caps.shader_integer_dot_product), + ) + } else { + None + }, } } @@ -1006,6 +1023,11 @@ impl PhysicalDeviceProperties { if requested_features.intersects(wgt::Features::EXPERIMENTAL_MESH_SHADER) { extensions.push(khr::maintenance4::NAME); } + + // Optional `VK_KHR_shader_integer_dot_product` + if self.supports_extension(khr::shader_integer_dot_product::NAME) { + extensions.push(khr::shader_integer_dot_product::NAME); + } } // Optional `VK_KHR_swapchain_mutable_format` @@ -1496,6 +1518,16 @@ impl super::InstanceShared { features2 = features2.push_next(next); } + // `VK_KHR_shader_integer_dot_product` is promoted to 1.3 + if capabilities.device_api_version >= vk::API_VERSION_1_3 + || capabilities.supports_extension(khr::shader_integer_dot_product::NAME) + { + let next = features + .shader_integer_dot_product + .insert(vk::PhysicalDeviceShaderIntegerDotProductFeatures::default()); + features2 = features2.push_next(next); + } + unsafe { get_device_properties.get_physical_device_features2(phd, &mut features2) }; features2.features } else { @@ -1679,6 +1711,9 @@ impl super::Instance { .properties .limits .max_sampler_allocation_count, + shader_integer_dot_product: phd_features + .shader_integer_dot_product + .is_some_and(|ext| ext.shader_integer_dot_product != 0), }; let capabilities = crate::Capabilities { limits: phd_capabilities.to_wgpu_limits(), @@ -1971,13 +2006,24 @@ impl super::Adapter { if features.contains(wgt::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN) { capabilities.push(spv::Capability::RayQueryPositionFetchKHR) } + if self.private_caps.shader_integer_dot_product { + // See . + capabilities.extend(&[ + spv::Capability::DotProductInputAllKHR, + spv::Capability::DotProductInput4x8BitKHR, + spv::Capability::DotProductInput4x8BitPackedKHR, + spv::Capability::DotProductKHR, + ]); + } spv::Options { - lang_version: if features - .intersects(wgt::Features::SUBGROUP | wgt::Features::SUBGROUP_VERTEX) - { - (1, 3) - } else { - (1, 0) + lang_version: match self.phd_capabilities.device_api_version { + // Use maximum supported SPIR-V version according to + // . + vk::API_VERSION_1_0..vk::API_VERSION_1_1 => (1, 0), + vk::API_VERSION_1_1..vk::API_VERSION_1_2 => (1, 3), + vk::API_VERSION_1_2..vk::API_VERSION_1_3 => (1, 5), + vk::API_VERSION_1_3.. => (1, 6), + _ => unreachable!(), }, flags, capabilities: Some(capabilities.iter().cloned().collect()), diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index a8e71cfa68..b492f33987 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -528,6 +528,14 @@ struct PrivateCapabilities { zero_initialize_workgroup_memory: bool, image_format_list: bool, maximum_samplers: u32, + + /// True if this adapter supports the [`VK_KHR_shader_integer_dot_product`] extension + /// (promoted to Vulkan 1.3). + /// + /// This is used to generate optimized code for WGSL's `dot4{I, U}8Packed`. + /// + /// [`VK_KHR_shader_integer_dot_product`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_shader_integer_dot_product.html + shader_integer_dot_product: bool, } bitflags::bitflags!(