mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-21 18:10:06 +00:00
renderer_vulkan: Update to support MoltenVK 1.2.7 (#7335)
This commit is contained in:
parent
015e42be05
commit
2ce0a9e899
@ -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()
|
||||||
|
|
||||||
|
3
externals/CMakeLists.txt
vendored
3
externals/CMakeLists.txt
vendored
@ -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)
|
||||||
|
1071
externals/moltenvk/mvk_config.h
vendored
1071
externals/moltenvk/mvk_config.h
vendored
File diff suppressed because it is too large
Load Diff
2
externals/vulkan-headers
vendored
2
externals/vulkan-headers
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 85c2334e92e215cce34e8e0ed8b2dce4700f4a50
|
Subproject commit 217e93c664ec6704ec2d8c36fa116c1a4a1e2d40
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user