Merge pull request #19004 from hrydgard/fix-msaa-regression

Vulkan: Fix function loading regression affecting MSAA
This commit is contained in:
Henrik Rydgård 2024-04-05 17:57:49 +02:00 committed by GitHub
commit 32620ff12f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 46 additions and 33 deletions

View File

@ -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 =

View File

@ -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_; }

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -1516,10 +1516,12 @@ void Config::RemoveRecent(const std::string &file) {
std::lock_guard<std::mutex> guard(private_->recentIsosLock);
const auto &filename = File::ResolvePath(file);
std::remove_if(recentIsos.begin(), recentIsos.end(), [filename](const auto &str) {
auto iter = std::remove_if(recentIsos.begin(), recentIsos.end(), [filename](const auto &str) {
const auto &recent = File::ResolvePath(str);
return filename == recent;
});
// remove_if is weird.
recentIsos.erase(iter, recentIsos.end());
}
void Config::CleanRecent() {