Skip to content

Commit 65e4051

Browse files
authored
vulkan: use effective api version for determining device features (#3011)
1 parent f877a8a commit 65e4051

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ SurfaceConfiguration {
122122
#### Vulkan
123123
- Remove use of Vulkan12Features/Properties types. By @i509VCB in [#2936](https://github.com/gfx-rs/wgpu/pull/2936)
124124
- Provide a means for `wgpu` users to access `vk::Queue` and the queue index. By @anlumo in [#2950](https://github.com/gfx-rs/wgpu/pull/2950)
125+
- Use the use effective api version for determining device features instead of wrongly assuming `VkPhysicalDeviceProperties.apiVersion`
126+
is the actual version of the device. By @i509VCB in [#3011](https://github.com/gfx-rs/wgpu/pull/3011)
125127

126128
### Performance
127129

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl PhysicalDeviceFeatures {
7272
///
7373
/// `requested_features` should be the same as what was used to generate `enabled_extensions`.
7474
fn from_extensions_and_requested_features(
75-
api_version: u32,
75+
effective_api_version: u32,
7676
enabled_extensions: &[&'static CStr],
7777
requested_features: wgt::Features,
7878
downlevel_flags: wgt::DownlevelFlags,
@@ -207,7 +207,7 @@ impl PhysicalDeviceFeatures {
207207
} else {
208208
None
209209
},
210-
imageless_framebuffer: if api_version >= vk::API_VERSION_1_2
210+
imageless_framebuffer: if effective_api_version >= vk::API_VERSION_1_2
211211
|| enabled_extensions.contains(&vk::KhrImagelessFramebufferFn::name())
212212
{
213213
Some(
@@ -218,7 +218,7 @@ impl PhysicalDeviceFeatures {
218218
} else {
219219
None
220220
},
221-
timeline_semaphore: if api_version >= vk::API_VERSION_1_2
221+
timeline_semaphore: if effective_api_version >= vk::API_VERSION_1_2
222222
|| enabled_extensions.contains(&vk::KhrTimelineSemaphoreFn::name())
223223
{
224224
Some(
@@ -262,7 +262,7 @@ impl PhysicalDeviceFeatures {
262262
} else {
263263
None
264264
},
265-
multiview: if api_version >= vk::API_VERSION_1_1
265+
multiview: if effective_api_version >= vk::API_VERSION_1_1
266266
|| enabled_extensions.contains(&vk::KhrMultiviewFn::name())
267267
{
268268
Some(
@@ -511,6 +511,20 @@ pub struct PhysicalDeviceCapabilities {
511511
supported_extensions: Vec<vk::ExtensionProperties>,
512512
properties: vk::PhysicalDeviceProperties,
513513
descriptor_indexing: Option<vk::PhysicalDeviceDescriptorIndexingPropertiesEXT>,
514+
/// The effective driver api version supported by the physical device.
515+
///
516+
/// The Vulkan specification states the following in the documentation for VkPhysicalDeviceProperties:
517+
/// > The value of apiVersion may be different than the version returned by vkEnumerateInstanceVersion;
518+
/// > either higher or lower. In such cases, the application must not use functionality that exceeds
519+
/// > the version of Vulkan associated with a given object.
520+
///
521+
/// For example, a Vulkan 1.1 instance cannot use functionality added in Vulkan 1.2 even if the physical
522+
/// device supports Vulkan 1.2.
523+
///
524+
/// This means that assuming that the apiVersion provided by VkPhysicalDeviceProperties is the actual
525+
/// version we can use is incorrect. Instead the effective version is the lower of the instance version
526+
/// and physical device version.
527+
effective_api_version: u32,
514528
}
515529

516530
// This is safe because the structs have `p_next: *mut c_void`, which we null out/never read.
@@ -534,7 +548,7 @@ impl PhysicalDeviceCapabilities {
534548

535549
extensions.push(khr::Swapchain::name());
536550

537-
if self.properties.api_version < vk::API_VERSION_1_1 {
551+
if self.effective_api_version < vk::API_VERSION_1_1 {
538552
extensions.push(vk::KhrMaintenance1Fn::name());
539553
extensions.push(vk::KhrMaintenance2Fn::name());
540554

@@ -552,7 +566,7 @@ impl PhysicalDeviceCapabilities {
552566
}
553567
}
554568

555-
if self.properties.api_version < vk::API_VERSION_1_2 {
569+
if self.effective_api_version < vk::API_VERSION_1_2 {
556570
if self.supports_extension(vk::KhrImagelessFramebufferFn::name()) {
557571
extensions.push(vk::KhrImagelessFramebufferFn::name());
558572
extensions.push(vk::KhrImageFormatListFn::name()); // Required for `KhrImagelessFramebufferFn`
@@ -564,7 +578,7 @@ impl PhysicalDeviceCapabilities {
564578
if requested_features.intersects(indexing_features()) {
565579
extensions.push(vk::ExtDescriptorIndexingFn::name());
566580

567-
if self.properties.api_version < vk::API_VERSION_1_1 {
581+
if self.effective_api_version < vk::API_VERSION_1_1 {
568582
extensions.push(vk::KhrMaintenance3Fn::name());
569583
}
570584
}
@@ -755,6 +769,10 @@ impl super::InstanceShared {
755769
unsafe { self.raw.get_physical_device_properties(phd) }
756770
};
757771

772+
// Set the effective api version
773+
capabilities.effective_api_version = self
774+
.driver_api_version
775+
.min(capabilities.properties.api_version);
758776
capabilities
759777
};
760778

@@ -765,7 +783,7 @@ impl super::InstanceShared {
765783
let mut builder = vk::PhysicalDeviceFeatures2KHR::builder().features(core);
766784

767785
// `VK_KHR_multiview` is promoted to 1.1
768-
if capabilities.properties.api_version >= vk::API_VERSION_1_1
786+
if capabilities.effective_api_version >= vk::API_VERSION_1_1
769787
|| capabilities.supports_extension(vk::KhrMultiviewFn::name())
770788
{
771789
let next = features
@@ -893,7 +911,7 @@ impl super::Instance {
893911
);
894912
};
895913

896-
if phd_capabilities.properties.api_version == vk::API_VERSION_1_0
914+
if phd_capabilities.effective_api_version == vk::API_VERSION_1_0
897915
&& !phd_capabilities.supports_extension(vk::KhrStorageBufferStorageClassFn::name())
898916
{
899917
log::warn!(
@@ -904,7 +922,7 @@ impl super::Instance {
904922
}
905923
if !phd_capabilities.supports_extension(vk::AmdNegativeViewportHeightFn::name())
906924
&& !phd_capabilities.supports_extension(vk::KhrMaintenance1Fn::name())
907-
&& phd_capabilities.properties.api_version < vk::API_VERSION_1_1
925+
&& phd_capabilities.effective_api_version < vk::API_VERSION_1_1
908926
{
909927
log::warn!(
910928
"viewport Y-flip is not supported, hiding adapter: {}",
@@ -925,15 +943,15 @@ impl super::Instance {
925943
}
926944

927945
let private_caps = super::PrivateCapabilities {
928-
flip_y_requires_shift: phd_capabilities.properties.api_version >= vk::API_VERSION_1_1
946+
flip_y_requires_shift: phd_capabilities.effective_api_version >= vk::API_VERSION_1_1
929947
|| phd_capabilities.supports_extension(vk::KhrMaintenance1Fn::name()),
930948
imageless_framebuffers: match phd_features.imageless_framebuffer {
931949
Some(features) => features.imageless_framebuffer == vk::TRUE,
932950
None => phd_features
933951
.imageless_framebuffer
934952
.map_or(false, |ext| ext.imageless_framebuffer != 0),
935953
},
936-
image_view_usage: phd_capabilities.properties.api_version >= vk::API_VERSION_1_1
954+
image_view_usage: phd_capabilities.effective_api_version >= vk::API_VERSION_1_1
937955
|| phd_capabilities.supports_extension(vk::KhrMaintenance2Fn::name()),
938956
timeline_semaphores: match phd_features.timeline_semaphore {
939957
Some(features) => features.timeline_semaphore == vk::TRUE,
@@ -1039,7 +1057,7 @@ impl super::Adapter {
10391057
uab_types: super::UpdateAfterBindTypes,
10401058
) -> PhysicalDeviceFeatures {
10411059
PhysicalDeviceFeatures::from_extensions_and_requested_features(
1042-
self.phd_capabilities.properties.api_version,
1060+
self.phd_capabilities.effective_api_version,
10431061
enabled_extensions,
10441062
features,
10451063
self.downlevel_flags,
@@ -1093,7 +1111,7 @@ impl super::Adapter {
10931111
&self.instance.raw,
10941112
&raw_device,
10951113
)))
1096-
} else if self.phd_capabilities.properties.api_version >= vk::API_VERSION_1_2 {
1114+
} else if self.phd_capabilities.effective_api_version >= vk::API_VERSION_1_2 {
10971115
Some(super::ExtensionFn::Promoted)
10981116
} else {
10991117
None

0 commit comments

Comments
 (0)