From 92dc9c9e71c3988e134983d0c2e371afca6aea58 Mon Sep 17 00:00:00 2001 From: past-due <30942300+past-due@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:39:38 -0400 Subject: [PATCH] [Vulkan] Add support for VK_EXT_layer_settings Set MoltenVK layer settings to workaround an issue --- lib/ivis_opengl/gfx_api_vk.cpp | 56 ++++++++++++++++++++++++++++++++-- lib/ivis_opengl/gfx_api_vk.h | 3 ++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/lib/ivis_opengl/gfx_api_vk.cpp b/lib/ivis_opengl/gfx_api_vk.cpp index b03dcd00720..3b713d3480a 100644 --- a/lib/ivis_opengl/gfx_api_vk.cpp +++ b/lib/ivis_opengl/gfx_api_vk.cpp @@ -79,9 +79,12 @@ const size_t MAX_FRAMES_IN_FLIGHT = 2; // Vulkan version where extension is promoted to core; extension name #define VK_NOT_PROMOTED_TO_CORE_YET 0 const std::vector> optionalInstanceExtensions = { - { VK_MAKE_VERSION(1, 1, 0) , VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME }, // used for Vulkan info output + { VK_MAKE_VERSION(1, 1, 0) , VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME } // used for Vulkan info output #if defined(VK_KHR_portability_enumeration) - { VK_NOT_PROMOTED_TO_CORE_YET , VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME} + , { VK_NOT_PROMOTED_TO_CORE_YET , VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME} +#endif +#if defined(VK_EXT_layer_settings) + , { VK_NOT_PROMOTED_TO_CORE_YET , VK_EXT_LAYER_SETTINGS_EXTENSION_NAME} #endif }; @@ -159,6 +162,15 @@ const std::vector> vulk , {_vkl_env_text("DISABLE_GAMEPP_LAYER"), _vkl_env_text("1"), true} // Gamepp }; +#if defined(VK_EXT_layer_settings) +// layer settings +// - MoltenVK: +const VkBool32 setting_mvk_config_use_metal_argument_buffers = VK_FALSE; // Disable MoltenVK Metal argument buffers (currently triggers Metal API Validation asserts) +const std::vector vulkan_mvk_layer_settings = { + {"MoltenVK", "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", vk::LayerSettingTypeEXT::eBool32, 1, &setting_mvk_config_use_metal_argument_buffers} +}; +#endif + #if defined(WZ_DEBUG_GFX_API_LEAKS) static std::unordered_set debugLiveTextures; #endif @@ -3363,6 +3375,30 @@ bool VkRoot::setupDebugReportCallbacks(const std::vector& extension return true; } +#if defined(VK_EXT_layer_settings) +std::vector VkRoot::initLayerSettings() +{ + std::vector result; +#ifdef WZ_OS_MAC + // MoltenVK layer settings + for (const auto &it : vulkan_mvk_layer_settings) + { + if (getenv(it.pSettingName) == nullptr) + { + result.push_back(it); + debug(LOG_3D, "Setting [%s]:%s", it.pLayerName, it.pSettingName); + } + else + { + // environment variable is already set - log a warning, but allow it to take precedence + debug(LOG_INFO, "Warning: Environment variable %s is already set, and will *not* be overridden", it.pSettingName); + } + } +#endif + return result; +} +#endif + // Attempts to create a Vulkan instance (vk::Instance) with the specified extensions and layers // If successful, sets the following variable in VkRoot: // - inst (vk::Instance) @@ -3431,6 +3467,22 @@ bool VkRoot::createVulkanInstance(uint32_t apiVersion, const std::vector layerSettings; + vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo; + bool requesting_layer_settings_extension = std::any_of(extensions.begin(), extensions.end(), + [](const char *extensionName) { return (strcmp(extensionName, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) == 0);}); + if (requesting_layer_settings_extension) + { + layerSettings = initLayerSettings(); + layerSettingsCreateInfo.settingCount = static_cast(layerSettings.size()); + layerSettingsCreateInfo.pSettings = layerSettings.data(); + layerSettingsCreateInfo.pNext = instanceCreateInfo.pNext; + instanceCreateInfo.pNext = &layerSettingsCreateInfo; + debug(LOG_3D, "Using layer settings, settingCount: %" PRIu32, layerSettingsCreateInfo.settingCount); + } +#endif + VkResult result = _vkCreateInstance(reinterpret_cast(&instanceCreateInfo), nullptr, reinterpret_cast(&inst)); if (result != VK_SUCCESS) { diff --git a/lib/ivis_opengl/gfx_api_vk.h b/lib/ivis_opengl/gfx_api_vk.h index fa57a4b1b30..d1319fbe95e 100644 --- a/lib/ivis_opengl/gfx_api_vk.h +++ b/lib/ivis_opengl/gfx_api_vk.h @@ -771,6 +771,9 @@ struct VkRoot final : gfx_api::context bool getSupportedInstanceExtensions(std::vector &output, PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr); bool findSupportedInstanceExtensions(std::vector extensionsToFind, std::vector &output, PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr); +#if defined(VK_EXT_layer_settings) + std::vector initLayerSettings(); +#endif bool createVulkanInstance(uint32_t apiVersion, const std::vector& extensions, const std::vector& layers, PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr); bool setupDebugUtilsCallbacks(const std::vector& extensions, PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr); bool setupDebugReportCallbacks(const std::vector& extensions, PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr);