Skip to content

Commit 0d06284

Browse files
authored
Allow wgpu-core to use new naga optimizations for dot4{I, U}8Packed (#7595)
* [wgpu-hal] Use highest available SPIR-V version * [wgpu-hal] Expose capabilities `DotProductInput*` * Introduce `{PhysicalDeviceFeatures, PrivateCapabilities}::shader_integer_dot_product`
1 parent 850c3d4 commit 0d06284

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ Naga now infers the correct binding layout when a resource appears only in an as
8585

8686
- Remove the need for dxil.dll. By @teoxoy in [#7566](https://github.com/gfx-rs/wgpu/pull/7566)
8787

88+
#### Vulkan
89+
90+
- Use highest SPIR-V version supported by Vulkan API version. By @robamler in [#7595](https://github.com/gfx-rs/wgpu/pull/7595)
91+
8892
### Bug Fixes
8993

9094
#### Naga

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ pub struct PhysicalDeviceFeatures {
123123

124124
/// Features proved by `VK_EXT_mesh_shader`
125125
mesh_shader: Option<vk::PhysicalDeviceMeshShaderFeaturesEXT<'static>>,
126+
127+
/// Features provided by `VK_KHR_shader_integer_dot_product`, promoted to Vulkan 1.3.
128+
shader_integer_dot_product:
129+
Option<vk::PhysicalDeviceShaderIntegerDotProductFeaturesKHR<'static>>,
126130
}
127131

128132
impl PhysicalDeviceFeatures {
@@ -187,6 +191,9 @@ impl PhysicalDeviceFeatures {
187191
if let Some(ref mut feature) = self.mesh_shader {
188192
info = info.push_next(feature);
189193
}
194+
if let Some(ref mut feature) = self.shader_integer_dot_product {
195+
info = info.push_next(feature);
196+
}
190197
info
191198
}
192199

@@ -499,6 +506,16 @@ impl PhysicalDeviceFeatures {
499506
} else {
500507
None
501508
},
509+
shader_integer_dot_product: if device_api_version >= vk::API_VERSION_1_3
510+
|| enabled_extensions.contains(&khr::shader_integer_dot_product::NAME)
511+
{
512+
Some(
513+
vk::PhysicalDeviceShaderIntegerDotProductFeaturesKHR::default()
514+
.shader_integer_dot_product(private_caps.shader_integer_dot_product),
515+
)
516+
} else {
517+
None
518+
},
502519
}
503520
}
504521

@@ -1006,6 +1023,11 @@ impl PhysicalDeviceProperties {
10061023
if requested_features.intersects(wgt::Features::EXPERIMENTAL_MESH_SHADER) {
10071024
extensions.push(khr::maintenance4::NAME);
10081025
}
1026+
1027+
// Optional `VK_KHR_shader_integer_dot_product`
1028+
if self.supports_extension(khr::shader_integer_dot_product::NAME) {
1029+
extensions.push(khr::shader_integer_dot_product::NAME);
1030+
}
10091031
}
10101032

10111033
// Optional `VK_KHR_swapchain_mutable_format`
@@ -1496,6 +1518,16 @@ impl super::InstanceShared {
14961518
features2 = features2.push_next(next);
14971519
}
14981520

1521+
// `VK_KHR_shader_integer_dot_product` is promoted to 1.3
1522+
if capabilities.device_api_version >= vk::API_VERSION_1_3
1523+
|| capabilities.supports_extension(khr::shader_integer_dot_product::NAME)
1524+
{
1525+
let next = features
1526+
.shader_integer_dot_product
1527+
.insert(vk::PhysicalDeviceShaderIntegerDotProductFeatures::default());
1528+
features2 = features2.push_next(next);
1529+
}
1530+
14991531
unsafe { get_device_properties.get_physical_device_features2(phd, &mut features2) };
15001532
features2.features
15011533
} else {
@@ -1679,6 +1711,9 @@ impl super::Instance {
16791711
.properties
16801712
.limits
16811713
.max_sampler_allocation_count,
1714+
shader_integer_dot_product: phd_features
1715+
.shader_integer_dot_product
1716+
.is_some_and(|ext| ext.shader_integer_dot_product != 0),
16821717
};
16831718
let capabilities = crate::Capabilities {
16841719
limits: phd_capabilities.to_wgpu_limits(),
@@ -1971,13 +2006,24 @@ impl super::Adapter {
19712006
if features.contains(wgt::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN) {
19722007
capabilities.push(spv::Capability::RayQueryPositionFetchKHR)
19732008
}
2009+
if self.private_caps.shader_integer_dot_product {
2010+
// See <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_shader_integer_dot_product.html#_new_spir_v_capabilities>.
2011+
capabilities.extend(&[
2012+
spv::Capability::DotProductInputAllKHR,
2013+
spv::Capability::DotProductInput4x8BitKHR,
2014+
spv::Capability::DotProductInput4x8BitPackedKHR,
2015+
spv::Capability::DotProductKHR,
2016+
]);
2017+
}
19742018
spv::Options {
1975-
lang_version: if features
1976-
.intersects(wgt::Features::SUBGROUP | wgt::Features::SUBGROUP_VERTEX)
1977-
{
1978-
(1, 3)
1979-
} else {
1980-
(1, 0)
2019+
lang_version: match self.phd_capabilities.device_api_version {
2020+
// Use maximum supported SPIR-V version according to
2021+
// <https://github.com/KhronosGroup/Vulkan-Docs/blob/19b7651/appendices/spirvenv.adoc?plain=1#L21-L40>.
2022+
vk::API_VERSION_1_0..vk::API_VERSION_1_1 => (1, 0),
2023+
vk::API_VERSION_1_1..vk::API_VERSION_1_2 => (1, 3),
2024+
vk::API_VERSION_1_2..vk::API_VERSION_1_3 => (1, 5),
2025+
vk::API_VERSION_1_3.. => (1, 6),
2026+
_ => unreachable!(),
19812027
},
19822028
flags,
19832029
capabilities: Some(capabilities.iter().cloned().collect()),

wgpu-hal/src/vulkan/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ struct PrivateCapabilities {
528528
zero_initialize_workgroup_memory: bool,
529529
image_format_list: bool,
530530
maximum_samplers: u32,
531+
532+
/// True if this adapter supports the [`VK_KHR_shader_integer_dot_product`] extension
533+
/// (promoted to Vulkan 1.3).
534+
///
535+
/// This is used to generate optimized code for WGSL's `dot4{I, U}8Packed`.
536+
///
537+
/// [`VK_KHR_shader_integer_dot_product`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_shader_integer_dot_product.html
538+
shader_integer_dot_product: bool,
531539
}
532540

533541
bitflags::bitflags!(

0 commit comments

Comments
 (0)