renderer_vulkan: Update to support MoltenVK 1.2.7 (#7335)

This commit is contained in:
Steveice10 2024-01-09 11:33:47 -08:00 committed by GitHub
parent 015e42be05
commit 2ce0a9e899
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 1130 deletions

View file

@ -121,7 +121,7 @@ function(download_moltenvk)
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar") set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
if (NOT EXISTS ${MOLTENVK_DIR}) if (NOT EXISTS ${MOLTENVK_DIR})
if (NOT EXISTS ${MOLTENVK_TAR}) if (NOT EXISTS ${MOLTENVK_TAR})
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/latest/download/MoltenVK-all.tar file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.7-rc1/MoltenVK-all.tar
${MOLTENVK_TAR} SHOW_PROGRESS) ${MOLTENVK_TAR} SHOW_PROGRESS)
endif() endif()

View file

@ -395,9 +395,6 @@ if(USE_SYSTEM_VULKAN_HEADERS)
else() else()
target_include_directories(vulkan-headers SYSTEM INTERFACE ./vulkan-headers/include) target_include_directories(vulkan-headers SYSTEM INTERFACE ./vulkan-headers/include)
endif() endif()
if (APPLE)
target_include_directories(vulkan-headers SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK)
endif()
# adrenotools # adrenotools
if (ANDROID AND "arm64" IN_LIST ARCHITECTURE) if (ANDROID AND "arm64" IN_LIST ARCHITECTURE)

File diff suppressed because it is too large Load diff

@ -1 +1 @@
Subproject commit 85c2334e92e215cce34e8e0ed8b2dce4700f4a50 Subproject commit 217e93c664ec6704ec2d8c36fa116c1a4a1e2d40

View file

@ -15,10 +15,6 @@
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
#ifdef __APPLE__
#include <mvk_config.h>
#endif
namespace Vulkan { namespace Vulkan {
namespace { namespace {
@ -606,12 +602,6 @@ bool Instance::CreateDevice() {
#undef PROP_GET #undef PROP_GET
#undef FEAT_SET #undef FEAT_SET
#ifdef __APPLE__
if (!SetMoltenVkConfig()) {
LOG_WARNING(Render_Vulkan, "Unable to set MoltenVK configuration");
}
#endif
try { try {
device = physical_device.createDeviceUnique(device_chain.get()); device = physical_device.createDeviceUnique(device_chain.get());
} catch (vk::ExtensionNotPresentError& err) { } catch (vk::ExtensionNotPresentError& err) {
@ -689,42 +679,4 @@ void Instance::CollectToolingInfo() {
} }
} }
bool Instance::SetMoltenVkConfig() {
#ifdef __APPLE__
std::size_t mvk_config_size = sizeof(MVKConfiguration);
MVKConfiguration mvk_config{};
const auto _vkGetMoltenVKConfigurationMVK =
library->GetSymbol<PFN_vkGetMoltenVKConfigurationMVK>("vkGetMoltenVKConfigurationMVK");
if (!_vkGetMoltenVKConfigurationMVK) {
return false;
}
const auto _vkSetMoltenVKConfigurationMVK =
library->GetSymbol<PFN_vkSetMoltenVKConfigurationMVK>("vkSetMoltenVKConfigurationMVK");
if (!_vkSetMoltenVKConfigurationMVK) {
return false;
}
if (_vkGetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &mvk_config, &mvk_config_size) !=
VK_SUCCESS) {
return false;
}
// Use synchronous queue submits if async presentation is enabled, to avoid threading
// indirection.
mvk_config.synchronousQueueSubmits = Settings::values.async_presentation.GetValue();
// If the device is lost, make an attempt to resume if possible to avoid crashes.
mvk_config.resumeLostDevice = true;
// Maximize concurrency to improve shader compilation performance.
mvk_config.shouldMaximizeConcurrentCompilation = true;
if (_vkSetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &mvk_config, &mvk_config_size) !=
VK_SUCCESS) {
return false;
}
#endif
return true;
}
} // namespace Vulkan } // namespace Vulkan

View file

@ -289,9 +289,6 @@ private:
void CollectTelemetryParameters(Core::TelemetrySession& telemetry); void CollectTelemetryParameters(Core::TelemetrySession& telemetry);
void CollectToolingInfo(); void CollectToolingInfo();
/// Sets MoltenVK configuration to the desired state.
bool SetMoltenVkConfig();
private: private:
std::shared_ptr<Common::DynamicLibrary> library; std::shared_ptr<Common::DynamicLibrary> library;
vk::UniqueInstance instance; vk::UniqueInstance instance;

View file

@ -206,10 +206,12 @@ std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window
// Add the windowing system specific extension // Add the windowing system specific extension
std::vector<const char*> extensions; std::vector<const char*> extensions;
extensions.reserve(6); extensions.reserve(7);
#if defined(__APPLE__) #if defined(__APPLE__)
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
// For configuring MoltenVK.
extensions.push_back(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME);
#endif #endif
switch (window_type) { switch (window_type) {
@ -281,10 +283,21 @@ vk::UniqueInstance CreateInstance(const Common::DynamicLibrary& library,
throw std::runtime_error("Failed to load Vulkan driver library"); throw std::runtime_error("Failed to load Vulkan driver library");
} }
const auto vkGetInstanceProcAddr = auto vkGetInstanceProcAddr =
library.GetSymbol<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr"); library.GetSymbol<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
if (!vkGetInstanceProcAddr) { if (!vkGetInstanceProcAddr) {
#ifdef __APPLE__
// MoltenVK now hides most Vulkan symbols by default to avoid clashes,
// so we may need to use the ICD hook instead.
vkGetInstanceProcAddr =
library.GetSymbol<PFN_vkGetInstanceProcAddr>("vk_icdGetInstanceProcAddr");
if (!vkGetInstanceProcAddr) {
throw std::runtime_error(
"Failed GetSymbol vkGetInstanceProcAddr or vk_icdGetInstanceProcAddr");
}
#else
throw std::runtime_error("Failed GetSymbol vkGetInstanceProcAddr"); throw std::runtime_error("Failed GetSymbol vkGetInstanceProcAddr");
#endif
} }
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
@ -315,7 +328,7 @@ vk::UniqueInstance CreateInstance(const Common::DynamicLibrary& library,
layers.push_back("VK_LAYER_LUNARG_api_dump"); layers.push_back("VK_LAYER_LUNARG_api_dump");
} }
const vk::InstanceCreateInfo instance_ci = { vk::InstanceCreateInfo instance_ci = {
.flags = GetInstanceFlags(), .flags = GetInstanceFlags(),
.pApplicationInfo = &application_info, .pApplicationInfo = &application_info,
.enabledLayerCount = static_cast<u32>(layers.size()), .enabledLayerCount = static_cast<u32>(layers.size()),
@ -324,6 +337,36 @@ vk::UniqueInstance CreateInstance(const Common::DynamicLibrary& library,
.ppEnabledExtensionNames = extensions.data(), .ppEnabledExtensionNames = extensions.data(),
}; };
#ifdef __APPLE__
// Use synchronous queue submits if async presentation is enabled, to avoid threading
// indirection.
const auto synchronous_queue_submits = Settings::values.async_presentation.GetValue();
// If the device is lost, make an attempt to resume if possible to avoid crashes.
constexpr auto resume_lost_device = true;
// Maximize concurrency to improve shader compilation performance.
constexpr auto maximize_concurrent_compilation = true;
constexpr auto layer_name = "MoltenVK";
const vk::LayerSettingEXT layer_settings[] = {
{layer_name, "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS", vk::LayerSettingTypeEXT::eBool32, 1,
&synchronous_queue_submits},
{layer_name, "MVK_CONFIG_RESUME_LOST_DEVICE", vk::LayerSettingTypeEXT::eBool32, 1,
&resume_lost_device},
{layer_name, "MVK_CONFIG_SHOULD_MAXIMIZE_CONCURRENT_COMPILATION",
vk::LayerSettingTypeEXT::eBool32, 1, &maximize_concurrent_compilation},
};
const vk::LayerSettingsCreateInfoEXT layer_settings_ci = {
.pNext = nullptr,
.settingCount = static_cast<uint32_t>(std::size(layer_settings)),
.pSettings = layer_settings,
};
if (std::find(extensions.begin(), extensions.end(), VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) !=
extensions.end()) {
instance_ci.pNext = &layer_settings_ci;
}
#endif
auto instance = vk::createInstanceUnique(instance_ci); auto instance = vk::createInstanceUnique(instance_ci);
VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance); VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance);