diff --git a/Common/GPU/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp index dc5b9246bc..56f99d1ce7 100644 --- a/Common/GPU/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -161,12 +161,12 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { // Temporary hack for libretro. For some reason, when we try to load the functions from this extension, // we get null pointers when running libretro. Quite strange. #if !defined(__LIBRETRO__) - if (EnableInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + if (EnableInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1)) { extensionsLookup_.KHR_get_physical_device_properties2 = true; } #endif - if (EnableInstanceExtension(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME)) { + if (EnableInstanceExtension(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, 0)) { extensionsLookup_.EXT_swapchain_colorspace = true; } @@ -217,7 +217,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { return res; } - VulkanLoadInstanceFunctions(instance_, extensionsLookup_); + VulkanLoadInstanceFunctions(instance_, extensionsLookup_, vulkanApiVersion_); if (!CheckLayers(instance_layer_properties_, instance_layer_names_)) { WARN_LOG(G3D, "CheckLayers for instance failed"); // init_error_ = "Failed to validate instance layers"; @@ -259,7 +259,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { props2.pNext = &pushProps; pushProps.pNext = &extHostMemProps; extHostMemProps.pNext = &depthStencilResolveProps; - vkGetPhysicalDeviceProperties2KHR(physical_devices_[i], &props2); + vkGetPhysicalDeviceProperties2(physical_devices_[i], &props2); // Don't want bad pointers sitting around. props2.pNext = nullptr; pushProps.pNext = nullptr; @@ -604,7 +604,7 @@ void VulkanContext::ChooseDevice(int physical_device) { presentWaitFeatures.pNext = &presentIdFeatures; presentIdFeatures.pNext = nullptr; - vkGetPhysicalDeviceFeatures2KHR(physical_devices_[physical_device_], &features2); + vkGetPhysicalDeviceFeatures2(physical_devices_[physical_device_], &features2); deviceFeatures_.available.standard = features2.features; deviceFeatures_.available.multiview = multiViewFeatures; deviceFeatures_.available.presentWait = presentWaitFeatures; @@ -632,7 +632,10 @@ bool VulkanContext::EnableDeviceExtension(const char *extension, uint32_t coreVe return false; } -bool VulkanContext::EnableInstanceExtension(const char *extension) { +bool VulkanContext::EnableInstanceExtension(const char *extension, uint32_t coreVersion) { + if (coreVersion != 0 && vulkanApiVersion_ >= coreVersion) { + return true; + } for (auto &iter : instance_extension_properties_) { if (!strcmp(iter.extensionName, extension)) { instance_extensions_enabled_.push_back(extension); @@ -747,7 +750,7 @@ VkResult VulkanContext::CreateDevice() { init_error_ = "Unable to create Vulkan device"; ERROR_LOG(G3D, "Unable to create Vulkan device"); } else { - VulkanLoadDeviceFunctions(device_, extensionsLookup_); + VulkanLoadDeviceFunctions(device_, extensionsLookup_, vulkanApiVersion_); } INFO_LOG(G3D, "Vulkan Device created: %s", physicalDeviceProperties_[physical_device_].properties.deviceName); @@ -1762,7 +1765,7 @@ void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequiremen VkMemoryDedicatedRequirementsKHR memDedicatedReq{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR}; memReq2.pNext = &memDedicatedReq; - vkGetImageMemoryRequirements2KHR(GetDevice(), &memReqInfo2, &memReq2); + vkGetImageMemoryRequirements2(GetDevice(), &memReqInfo2, &memReq2); *mem_reqs = memReq2.memoryRequirements; *dedicatedAllocation = diff --git a/Common/GPU/Vulkan/VulkanContext.h b/Common/GPU/Vulkan/VulkanContext.h index 516b41d6e3..a3d494fa4a 100644 --- a/Common/GPU/Vulkan/VulkanContext.h +++ b/Common/GPU/Vulkan/VulkanContext.h @@ -182,9 +182,11 @@ public: int GetBestPhysicalDevice(); int GetPhysicalDeviceByName(const std::string &name); void ChooseDevice(int physical_device); - bool EnableInstanceExtension(const char *extension); - // The core version is to avoid enabling extensions that are merged into core Vulkan from a certain version. + + // The coreVersion is to avoid enabling extensions that are merged into core Vulkan from a certain version. + bool EnableInstanceExtension(const char *extension, uint32_t coreVersion); bool EnableDeviceExtension(const char *extension, uint32_t coreVersion); + VkResult CreateDevice(); const std::string &InitError() const { return init_error_; } diff --git a/Common/GPU/Vulkan/VulkanFramebuffer.cpp b/Common/GPU/Vulkan/VulkanFramebuffer.cpp index 815d68bb61..f91c49a1aa 100644 --- a/Common/GPU/Vulkan/VulkanFramebuffer.cpp +++ b/Common/GPU/Vulkan/VulkanFramebuffer.cpp @@ -524,7 +524,7 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas rp2.pCorrelatedViewMasks = multiview ? &viewMask : nullptr; rp2.pSubpasses = &subpass2; rp2.subpassCount = 1; - res = vkCreateRenderPass2KHR(vulkan->GetDevice(), &rp2, nullptr, &pass); + res = vkCreateRenderPass2(vulkan->GetDevice(), &rp2, nullptr, &pass); } else { res = vkCreateRenderPass(vulkan->GetDevice(), &rp, nullptr, &pass); } diff --git a/Common/GPU/Vulkan/VulkanLoader.cpp b/Common/GPU/Vulkan/VulkanLoader.cpp index ca404021f8..34abe21723 100644 --- a/Common/GPU/Vulkan/VulkanLoader.cpp +++ b/Common/GPU/Vulkan/VulkanLoader.cpp @@ -74,10 +74,8 @@ PFN_vkBindBufferMemory2 vkBindBufferMemory2; PFN_vkBindImageMemory vkBindImageMemory; PFN_vkBindImageMemory2 vkBindImageMemory2; PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; -PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2; PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements; PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; -PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2; PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements; PFN_vkCreateFence vkCreateFence; PFN_vkDestroyFence vkDestroyFence; @@ -233,11 +231,12 @@ PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT; PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT; // Assorted other extensions. -PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR; -PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; -PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; -PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; -PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR; +PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2; +PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2; +PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2; +PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2; +PFN_vkCreateRenderPass2 vkCreateRenderPass2; + PFN_vkWaitForPresentKHR vkWaitForPresentKHR; PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE; PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE; @@ -263,7 +262,13 @@ bool g_vulkanAvailabilityChecked = false; bool g_vulkanMayBeAvailable = false; #define LOAD_INSTANCE_FUNC(instance, x) x = (PFN_ ## x)vkGetInstanceProcAddr(instance, #x); if (!x) {INFO_LOG(G3D, "Missing (instance): %s", #x);} +#define LOAD_INSTANCE_FUNC_CORE(instance, x, ext_x, min_core) \ + x = (PFN_ ## x)vkGetInstanceProcAddr(instance, vulkanApiVersion >= min_core ? #x : #ext_x); \ + if (!x) {INFO_LOG(G3D, "Missing (instance): %s (%s)", #x, #ext_x);} #define LOAD_DEVICE_FUNC(instance, x) x = (PFN_ ## x)vkGetDeviceProcAddr(instance, #x); if (!x) {INFO_LOG(G3D, "Missing (device): %s", #x);} +#define LOAD_DEVICE_FUNC_CORE(instance, x, ext_x, min_core) \ + x = (PFN_ ## x)vkGetDeviceProcAddr(instance, vulkanApiVersion >= min_core ? #x : #ext_x); \ + if (!x) {INFO_LOG(G3D, "Missing (device): %s (%s)", #x, #ext_x);} #define LOAD_GLOBAL_FUNC(x) x = (PFN_ ## x)dlsym(vulkanLibrary, #x); if (!x) {INFO_LOG(G3D,"Missing (global): %s", #x);} #define LOAD_GLOBAL_FUNC_LOCAL(lib, x) (PFN_ ## x)dlsym(lib, #x); @@ -579,7 +584,7 @@ bool VulkanLoad(std::string *errorStr) { } } -void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions) { +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions, uint32_t vulkanApiVersion) { // OK, let's use the above functions to get the rest. LOAD_INSTANCE_FUNC(instance, vkDestroyInstance); LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices); @@ -632,8 +637,8 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &en LOAD_INSTANCE_FUNC(instance, vkDestroySurfaceKHR); if (enabledExtensions.KHR_get_physical_device_properties2) { - LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceProperties2KHR); - LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceFeatures2KHR); + LOAD_INSTANCE_FUNC_CORE(instance, vkGetPhysicalDeviceProperties2, vkGetPhysicalDeviceProperties2KHR, VK_API_VERSION_1_1); + LOAD_INSTANCE_FUNC_CORE(instance, vkGetPhysicalDeviceFeatures2, vkGetPhysicalDeviceFeatures2KHR, VK_API_VERSION_1_1); } if (enabledExtensions.EXT_debug_utils) { @@ -652,7 +657,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &en // On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may // increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very // good for multi-device - not likely we'll ever try that anyway though. -void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions) { +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions, uint32_t vulkanApiVersion) { INFO_LOG(G3D, "Vulkan device functions loaded."); LOAD_DEVICE_FUNC(device, vkQueueSubmit); @@ -785,11 +790,11 @@ void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledE LOAD_DEVICE_FUNC(device, vkGetRefreshCycleDurationGOOGLE); } if (enabledExtensions.KHR_dedicated_allocation) { - LOAD_DEVICE_FUNC(device, vkGetBufferMemoryRequirements2KHR); - LOAD_DEVICE_FUNC(device, vkGetImageMemoryRequirements2KHR); + LOAD_DEVICE_FUNC_CORE(device, vkGetBufferMemoryRequirements2, vkGetBufferMemoryRequirements2KHR, VK_API_VERSION_1_1); + LOAD_DEVICE_FUNC_CORE(device, vkGetImageMemoryRequirements2, vkGetImageMemoryRequirements2KHR, VK_API_VERSION_1_1); } if (enabledExtensions.KHR_create_renderpass2) { - LOAD_DEVICE_FUNC(device, vkCreateRenderPass2KHR); + LOAD_DEVICE_FUNC_CORE(device, vkCreateRenderPass2, vkCreateRenderPass2KHR, VK_API_VERSION_1_2); } } diff --git a/Common/GPU/Vulkan/VulkanLoader.h b/Common/GPU/Vulkan/VulkanLoader.h index a08c232daa..1d1c3d0a17 100644 --- a/Common/GPU/Vulkan/VulkanLoader.h +++ b/Common/GPU/Vulkan/VulkanLoader.h @@ -230,12 +230,13 @@ extern PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT; extern PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT; // Assorted other extensions. -extern PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR; -extern PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; +extern PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2; +extern PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2; +extern PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2; +extern PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2; +extern PFN_vkCreateRenderPass2 vkCreateRenderPass2; + extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT; -extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; -extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; -extern PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR; extern PFN_vkWaitForPresentKHR vkWaitForPresentKHR; extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE; extern PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE; @@ -268,8 +269,8 @@ bool VulkanMayBeAvailable(); void VulkanSetAvailable(bool available); bool VulkanLoad(std::string *errorStr); -void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions); -void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions); +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions, uint32_t vulkanApiVersion); +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions, uint32_t vulkanApiVersion); void VulkanFree(); const char *VulkanResultToString(VkResult res);