@@ -72,7 +72,7 @@ impl PhysicalDeviceFeatures {
72
72
///
73
73
/// `requested_features` should be the same as what was used to generate `enabled_extensions`.
74
74
fn from_extensions_and_requested_features (
75
- api_version : u32 ,
75
+ effective_api_version : u32 ,
76
76
enabled_extensions : & [ & ' static CStr ] ,
77
77
requested_features : wgt:: Features ,
78
78
downlevel_flags : wgt:: DownlevelFlags ,
@@ -207,7 +207,7 @@ impl PhysicalDeviceFeatures {
207
207
} else {
208
208
None
209
209
} ,
210
- imageless_framebuffer : if api_version >= vk:: API_VERSION_1_2
210
+ imageless_framebuffer : if effective_api_version >= vk:: API_VERSION_1_2
211
211
|| enabled_extensions. contains ( & vk:: KhrImagelessFramebufferFn :: name ( ) )
212
212
{
213
213
Some (
@@ -218,7 +218,7 @@ impl PhysicalDeviceFeatures {
218
218
} else {
219
219
None
220
220
} ,
221
- timeline_semaphore : if api_version >= vk:: API_VERSION_1_2
221
+ timeline_semaphore : if effective_api_version >= vk:: API_VERSION_1_2
222
222
|| enabled_extensions. contains ( & vk:: KhrTimelineSemaphoreFn :: name ( ) )
223
223
{
224
224
Some (
@@ -262,7 +262,7 @@ impl PhysicalDeviceFeatures {
262
262
} else {
263
263
None
264
264
} ,
265
- multiview : if api_version >= vk:: API_VERSION_1_1
265
+ multiview : if effective_api_version >= vk:: API_VERSION_1_1
266
266
|| enabled_extensions. contains ( & vk:: KhrMultiviewFn :: name ( ) )
267
267
{
268
268
Some (
@@ -511,6 +511,20 @@ pub struct PhysicalDeviceCapabilities {
511
511
supported_extensions : Vec < vk:: ExtensionProperties > ,
512
512
properties : vk:: PhysicalDeviceProperties ,
513
513
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 ,
514
528
}
515
529
516
530
// This is safe because the structs have `p_next: *mut c_void`, which we null out/never read.
@@ -534,7 +548,7 @@ impl PhysicalDeviceCapabilities {
534
548
535
549
extensions. push ( khr:: Swapchain :: name ( ) ) ;
536
550
537
- if self . properties . api_version < vk:: API_VERSION_1_1 {
551
+ if self . effective_api_version < vk:: API_VERSION_1_1 {
538
552
extensions. push ( vk:: KhrMaintenance1Fn :: name ( ) ) ;
539
553
extensions. push ( vk:: KhrMaintenance2Fn :: name ( ) ) ;
540
554
@@ -552,7 +566,7 @@ impl PhysicalDeviceCapabilities {
552
566
}
553
567
}
554
568
555
- if self . properties . api_version < vk:: API_VERSION_1_2 {
569
+ if self . effective_api_version < vk:: API_VERSION_1_2 {
556
570
if self . supports_extension ( vk:: KhrImagelessFramebufferFn :: name ( ) ) {
557
571
extensions. push ( vk:: KhrImagelessFramebufferFn :: name ( ) ) ;
558
572
extensions. push ( vk:: KhrImageFormatListFn :: name ( ) ) ; // Required for `KhrImagelessFramebufferFn`
@@ -564,7 +578,7 @@ impl PhysicalDeviceCapabilities {
564
578
if requested_features. intersects ( indexing_features ( ) ) {
565
579
extensions. push ( vk:: ExtDescriptorIndexingFn :: name ( ) ) ;
566
580
567
- if self . properties . api_version < vk:: API_VERSION_1_1 {
581
+ if self . effective_api_version < vk:: API_VERSION_1_1 {
568
582
extensions. push ( vk:: KhrMaintenance3Fn :: name ( ) ) ;
569
583
}
570
584
}
@@ -755,6 +769,10 @@ impl super::InstanceShared {
755
769
unsafe { self . raw . get_physical_device_properties ( phd) }
756
770
} ;
757
771
772
+ // Set the effective api version
773
+ capabilities. effective_api_version = self
774
+ . driver_api_version
775
+ . min ( capabilities. properties . api_version ) ;
758
776
capabilities
759
777
} ;
760
778
@@ -765,7 +783,7 @@ impl super::InstanceShared {
765
783
let mut builder = vk:: PhysicalDeviceFeatures2KHR :: builder ( ) . features ( core) ;
766
784
767
785
// `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
769
787
|| capabilities. supports_extension ( vk:: KhrMultiviewFn :: name ( ) )
770
788
{
771
789
let next = features
@@ -893,7 +911,7 @@ impl super::Instance {
893
911
) ;
894
912
} ;
895
913
896
- if phd_capabilities. properties . api_version == vk:: API_VERSION_1_0
914
+ if phd_capabilities. effective_api_version == vk:: API_VERSION_1_0
897
915
&& !phd_capabilities. supports_extension ( vk:: KhrStorageBufferStorageClassFn :: name ( ) )
898
916
{
899
917
log:: warn!(
@@ -904,7 +922,7 @@ impl super::Instance {
904
922
}
905
923
if !phd_capabilities. supports_extension ( vk:: AmdNegativeViewportHeightFn :: name ( ) )
906
924
&& !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
908
926
{
909
927
log:: warn!(
910
928
"viewport Y-flip is not supported, hiding adapter: {}" ,
@@ -925,15 +943,15 @@ impl super::Instance {
925
943
}
926
944
927
945
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
929
947
|| phd_capabilities. supports_extension ( vk:: KhrMaintenance1Fn :: name ( ) ) ,
930
948
imageless_framebuffers : match phd_features. imageless_framebuffer {
931
949
Some ( features) => features. imageless_framebuffer == vk:: TRUE ,
932
950
None => phd_features
933
951
. imageless_framebuffer
934
952
. map_or ( false , |ext| ext. imageless_framebuffer != 0 ) ,
935
953
} ,
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
937
955
|| phd_capabilities. supports_extension ( vk:: KhrMaintenance2Fn :: name ( ) ) ,
938
956
timeline_semaphores : match phd_features. timeline_semaphore {
939
957
Some ( features) => features. timeline_semaphore == vk:: TRUE ,
@@ -1039,7 +1057,7 @@ impl super::Adapter {
1039
1057
uab_types : super :: UpdateAfterBindTypes ,
1040
1058
) -> PhysicalDeviceFeatures {
1041
1059
PhysicalDeviceFeatures :: from_extensions_and_requested_features (
1042
- self . phd_capabilities . properties . api_version ,
1060
+ self . phd_capabilities . effective_api_version ,
1043
1061
enabled_extensions,
1044
1062
features,
1045
1063
self . downlevel_flags ,
@@ -1093,7 +1111,7 @@ impl super::Adapter {
1093
1111
& self . instance . raw ,
1094
1112
& raw_device,
1095
1113
) ) )
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 {
1097
1115
Some ( super :: ExtensionFn :: Promoted )
1098
1116
} else {
1099
1117
None
0 commit comments