@@ -21,7 +21,8 @@ VulkanProbe::VulkanProbe() {
2121
2222 if (available_) {
2323 LOGI (" Vulkan available: %s (API %u.%u.%u, driver %u, VRAM %u MB, "
24- " queues %u, dedicatedCompute=%d, dedicatedTransfer=%d, swapchain=%d, mailbox=%d)" ,
24+ " queues %u, dedicatedCompute=%d, dedicatedTransfer=%d, swapchain=%d, mailbox=%d, "
25+ " vk1.3=%d, dynamicRendering=%d, synchronization2=%d)" ,
2526 deviceInfo_.deviceName .c_str (),
2627 VK_VERSION_MAJOR (deviceInfo_.apiVersion ),
2728 VK_VERSION_MINOR (deviceInfo_.apiVersion ),
@@ -32,7 +33,10 @@ VulkanProbe::VulkanProbe() {
3233 deviceInfo_.hasDedicatedComputeQueue ? 1 : 0 ,
3334 deviceInfo_.hasDedicatedTransferQueue ? 1 : 0 ,
3435 deviceInfo_.supportsSwapchain ? 1 : 0 ,
35- deviceInfo_.supportsMailboxPresentMode ? 1 : 0 );
36+ deviceInfo_.supportsMailboxPresentMode ? 1 : 0 ,
37+ deviceInfo_.meetsVulkan13 ? 1 : 0 ,
38+ deviceInfo_.supportsDynamicRendering ? 1 : 0 ,
39+ deviceInfo_.supportsSynchronization2 ? 1 : 0 );
3640 } else {
3741 LOGI (" Vulkan not available on this device" );
3842 }
@@ -49,7 +53,9 @@ bool VulkanProbe::createInstance() {
4953 appInfo.applicationVersion = VK_MAKE_VERSION (1 , 0 , 0 );
5054 appInfo.pEngineName = " osu-framework" ;
5155 appInfo.engineVersion = VK_MAKE_VERSION (1 , 0 , 0 );
52- appInfo.apiVersion = VK_API_VERSION_1_0 ;
56+ // Request Vulkan 1.3 to enable full feature queries (dynamic rendering,
57+ // synchronization2). Falls back to 1.0 on older drivers.
58+ appInfo.apiVersion = VK_API_VERSION_1_3 ;
5359
5460 VkInstanceCreateInfo createInfo{};
5561 createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ;
@@ -59,6 +65,13 @@ bool VulkanProbe::createInstance() {
5965
6066 VkResult result = vkCreateInstance (&createInfo, nullptr , &instance_);
6167
68+ if (result == VK_ERROR_INCOMPATIBLE_DRIVER ) {
69+ // Vulkan 1.0-only driver; fall back.
70+ LOGI (" Vulkan 1.3 instance not supported, falling back to 1.0" );
71+ appInfo.apiVersion = VK_API_VERSION_1_0 ;
72+ result = vkCreateInstance (&createInfo, nullptr , &instance_);
73+ }
74+
6275 if (result != VK_SUCCESS ) {
6376 LOGE (" vkCreateInstance failed: %d" , result);
6477 return false ;
@@ -130,6 +143,7 @@ bool VulkanProbe::queryDevice() {
130143 queryMemory (selected);
131144 queryQueueFamilies (selected);
132145 queryMailboxSupport (selected);
146+ queryVulkan13Features (selected);
133147
134148 return true ;
135149}
@@ -203,6 +217,33 @@ void VulkanProbe::queryMailboxSupport(VkPhysicalDevice device) {
203217 }
204218}
205219
220+ void VulkanProbe::queryVulkan13Features (VkPhysicalDevice device) {
221+ // Check if the device reports Vulkan 1.3+.
222+ uint32_t major = VK_VERSION_MAJOR (deviceInfo_.apiVersion );
223+ uint32_t minor = VK_VERSION_MINOR (deviceInfo_.apiVersion );
224+
225+ if (major < 1 || (major == 1 && minor < 3 )) {
226+ LOGI (" Device Vulkan API %u.%u < 1.3, skipping 1.3 feature query" , major, minor);
227+ return ;
228+ }
229+
230+ deviceInfo_.meetsVulkan13 = true ;
231+
232+ // vkGetPhysicalDeviceFeatures2 is available since Vulkan 1.1, and the device
233+ // reports 1.3+, so this is safe.
234+ VkPhysicalDeviceVulkan13Features features13{};
235+ features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES ;
236+
237+ VkPhysicalDeviceFeatures2 features2{};
238+ features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 ;
239+ features2.pNext = &features13;
240+
241+ vkGetPhysicalDeviceFeatures2 (device, &features2);
242+
243+ deviceInfo_.supportsDynamicRendering = features13.dynamicRendering == VK_TRUE ;
244+ deviceInfo_.supportsSynchronization2 = features13.synchronization2 == VK_TRUE ;
245+ }
246+
206247void VulkanProbe::cleanup () {
207248 if (instance_ != VK_NULL_HANDLE ) {
208249 vkDestroyInstance (instance_, nullptr );
@@ -272,4 +313,19 @@ OSU_EXPORT unsigned char nVulkanSupportsMailboxPresentMode(intptr_t ptr) {
272313 return (probe && probe->getDeviceInfo ().supportsMailboxPresentMode ) ? 1 : 0 ;
273314}
274315
316+ OSU_EXPORT unsigned char nVulkanMeetsVulkan13 (intptr_t ptr) {
317+ auto * probe = reinterpret_cast <VulkanProbe*>(ptr);
318+ return (probe && probe->getDeviceInfo ().meetsVulkan13 ) ? 1 : 0 ;
319+ }
320+
321+ OSU_EXPORT unsigned char nVulkanSupportsDynamicRendering (intptr_t ptr) {
322+ auto * probe = reinterpret_cast <VulkanProbe*>(ptr);
323+ return (probe && probe->getDeviceInfo ().supportsDynamicRendering ) ? 1 : 0 ;
324+ }
325+
326+ OSU_EXPORT unsigned char nVulkanSupportsSynchronization2 (intptr_t ptr) {
327+ auto * probe = reinterpret_cast <VulkanProbe*>(ptr);
328+ return (probe && probe->getDeviceInfo ().supportsSynchronization2 ) ? 1 : 0 ;
329+ }
330+
275331} // extern "C"
0 commit comments