From 41a9f5fa59029bc6a21140c136a2d3249f38b6f7 Mon Sep 17 00:00:00 2001 From: Stephen Saunders Date: Mon, 29 Jan 2024 20:58:28 -0500 Subject: [PATCH] macOS: Use VK_EXT_layer_settings config for all build types, add r_mvkUseMetalArgumentBuffers cvar --- neo/cmake-xcode-debug.sh | 8 +++---- neo/sys/DeviceManager_VK.cpp | 46 +++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/neo/cmake-xcode-debug.sh b/neo/cmake-xcode-debug.sh index 6087a670..7b89593a 100755 --- a/neo/cmake-xcode-debug.sh +++ b/neo/cmake-xcode-debug.sh @@ -16,8 +16,8 @@ fi # note 1: remove or set -DCMAKE_SUPPRESS_REGENERATION=OFF to reenable ZERO_CHECK target which checks for CMakeLists.txt changes and re-runs CMake before builds # however, if ZERO_CHECK is reenabled **must** add VULKAN_SDK location to Xcode Custom Paths (under Prefs/Locations) otherwise build failures may occur # note 2: policy CMAKE_POLICY_DEFAULT_CMP0142=NEW suppresses non-existant per-config suffixes on Xcode library search paths, works for cmake version 3.25 and later -# note 3: env variable MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1 enables MoltenVK's image view swizzle which may be required on older macOS versions or hardware (see vulkaninfo) -# note 4: env variable MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0 disables synchronous queue submits which is optimal for the synchronization method used by the game -# note 5: env variable MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2 enables MoltenVK's use of Metal argument buffers only if VK_EXT_descriptor_indexing is enabled -# note 6: env variable MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA=1.0 disables MoltenVK's timestampPeriod lowpass filter for non-Apple GPUs +# note 3: env variable MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1 enables MoltenVK's image view swizzle which may be required on older macOS versions or hardware (see vulkaninfo) - only used for VulkanSDK < 1.3.275 +# note 4: env variable MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0 disables synchronous queue submits which is optimal for the synchronization method used by the game - only used for VulkanSDK < 1.3.275 +# note 5: env variable MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2 enables MoltenVK's use of Metal argument buffers only if VK_EXT_descriptor_indexing is enabled - only used for VulkanSDK < 1.3.275 +# note 6: env variable MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA=1.0 disables MoltenVK's timestampPeriod lowpass filter for non-Apple GPUs - only used for VulkanSDK < 1.3.275 cmake -G Xcode -DCMAKE_BUILD_TYPE=Debug -DCMAKE_XCODE_GENERATE_SCHEME=ON -DCMAKE_XCODE_SCHEME_ENVIRONMENT="MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE=1;MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS=0;MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=2;MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA=1.0" -DCMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION=OFF -DCMAKE_SUPPRESS_REGENERATION=ON -DOPENAL_LIBRARY=$OPENAL_PREFIX/lib/libopenal.dylib -DOPENAL_INCLUDE_DIR=$OPENAL_PREFIX/include ../neo -DCMAKE_POLICY_DEFAULT_CMP0142=NEW -Wno-dev diff --git a/neo/sys/DeviceManager_VK.cpp b/neo/sys/DeviceManager_VK.cpp index d60bffa3..33f54e12 100644 --- a/neo/sys/DeviceManager_VK.cpp +++ b/neo/sys/DeviceManager_VK.cpp @@ -37,14 +37,19 @@ #include // SRS - optionally needed for MoltenVK runtime config visibility -#if defined(__APPLE__) && defined( USE_MoltenVK ) +#if defined(__APPLE__) +#if defined( USE_MoltenVK ) #if 0 #include #include // SRS - will eventually move to these mvk include files for MoltenVK >= 1.2.7 / SDK >= 1.3.275.0 #else #include // SRS - now deprecated, but provides backwards compatibility for MoltenVK < 1.2.7 / SDK < 1.3.275.0 #endif +#endif +#if defined( VK_EXT_layer_settings ) || defined( USE_MoltenVK ) idCVar r_mvkSynchronousQueueSubmits( "r_mvkSynchronousQueueSubmits", "0", CVAR_BOOL | CVAR_INIT, "Use MoltenVK's synchronous queue submit option." ); + idCVar r_mvkUseMetalArgumentBuffers( "r_mvkUseMetalArgumentBuffers", "2", CVAR_INTEGER | CVAR_INIT, "Use MoltenVK's Metal argument buffers option (0=Off, 1=Always On, 2=On when VK_EXT_descriptor_indexing enabled)", 0, 2 ); +#endif #endif #include #include @@ -509,19 +514,19 @@ bool DeviceManager_VK::createInstance() info.setFlags( vk::InstanceCreateFlagBits( VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR ) ); } #endif -#if defined( USE_MoltenVK ) && defined( VK_EXT_layer_settings ) - // SRS - when USE_MoltenVK defined, set MoltenVK runtime configuration parameters on macOS via VK_EXT_layer_settings +#if defined( VK_EXT_layer_settings ) + // SRS - set MoltenVK runtime configuration parameters on macOS via standardized VK_EXT_layer_settings extension std::vector layerSettings; vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo; const vk::Bool32 valueTrue = vk::True, valueFalse = vk::False; - const int32_t useMetalArgumentBuffers = int32_t( MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING ); - const Float32 timestampPeriodLowPassAlpha = 1.0; + const int32_t useMetalArgumentBuffers = r_mvkUseMetalArgumentBuffers.GetInteger(); + const float timestampPeriodLowPassAlpha = 1.0; if( enabledExtensions.instance.find( VK_EXT_LAYER_SETTINGS_EXTENSION_NAME ) != enabledExtensions.instance.end() ) { // SRS - use MoltenVK layer for configuration via VK_EXT_layer_settings extension - vk::LayerSettingEXT layerSetting = { kMVKMoltenVKDriverLayerName, "", vk::LayerSettingTypeEXT( 0 ), 1, nullptr }; + vk::LayerSettingEXT layerSetting = { "MoltenVK", "", vk::LayerSettingTypeEXT( 0 ), 1, nullptr }; // SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR() layerSetting.pSettingName = "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS"; @@ -547,11 +552,16 @@ bool DeviceManager_VK::createInstance() layerSetting.pValues = ×tampPeriodLowPassAlpha; layerSettings.push_back( layerSetting ); + // SRS - Only enable MoltenVK performance tracking if using API and available based on version +#if defined( USE_MoltenVK ) +#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 ) // SRS - Enable MoltenVK's performance tracking for display of Metal encoding timer on macOS layerSetting.pSettingName = "MVK_CONFIG_PERFORMANCE_TRACKING"; layerSetting.type = vk::LayerSettingTypeEXT::eBool32; layerSetting.pValues = &valueTrue; layerSettings.push_back( layerSetting ); +#endif +#endif layerSettingsCreateInfo.settingCount = uint32_t( layerSettings.size() ); layerSettingsCreateInfo.pSettings = layerSettings.data(); @@ -1242,16 +1252,17 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain() // SRS - when USE_MoltenVK defined, set MoltenVK runtime configuration parameters on macOS (deprecated version) #if defined(__APPLE__) && defined( USE_MoltenVK ) - // SRS - deprecated by VK_EXT_layer_settings, but retained for older versions of MoltenVK < 1.2.7 / SDK < 1.3.275.0 - const PFN_vkGetMoltenVKConfigurationMVK vkGetMoltenVKConfigurationMVK = // NOLINT(misc-misplaced-const) - (PFN_vkGetMoltenVKConfigurationMVK)vkGetInstanceProcAddr( m_VulkanInstance, "vkGetMoltenVKConfigurationMVK" ); - const PFN_vkSetMoltenVKConfigurationMVK vkSetMoltenVKConfigurationMVK = // NOLINT(misc-misplaced-const) - (PFN_vkSetMoltenVKConfigurationMVK)vkGetInstanceProcAddr( m_VulkanInstance, "vkSetMoltenVKConfigurationMVK" ); #if defined( VK_EXT_layer_settings ) // SRS - for backwards compatibility at runtime: execute only if we can't find the VK_EXT_layer_settings extension if( enabledExtensions.instance.find( VK_EXT_LAYER_SETTINGS_EXTENSION_NAME ) == enabledExtensions.instance.end() ) #endif { + // SRS - vkSetMoltenVKConfigurationMVK() now deprecated, but retained for MoltenVK < 1.2.7 / SDK < 1.3.275.0 + const PFN_vkGetMoltenVKConfigurationMVK vkGetMoltenVKConfigurationMVK = // NOLINT(misc-misplaced-const) + (PFN_vkGetMoltenVKConfigurationMVK)vkGetInstanceProcAddr( m_VulkanInstance, "vkGetMoltenVKConfigurationMVK" ); + const PFN_vkSetMoltenVKConfigurationMVK vkSetMoltenVKConfigurationMVK = // NOLINT(misc-misplaced-const) + (PFN_vkSetMoltenVKConfigurationMVK)vkGetInstanceProcAddr( m_VulkanInstance, "vkSetMoltenVKConfigurationMVK" ); + vk::PhysicalDeviceFeatures2 deviceFeatures2; vk::PhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures; deviceFeatures2.setPNext( &portabilityFeatures ); @@ -1276,11 +1287,14 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain() mvkConfig.fullImageViewSwizzle = VK_TRUE; } - // SRS - Turn MoltenVK's Metal argument buffer feature on for descriptor indexing only - if( mvkConfig.useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER ) + // SRS - Set MoltenVK's Metal argument buffer option for descriptor resource scaling + // - Also needed for Vulkan SDK 1.3.268.1 to work around SPIRV-Cross issue for Metal conversion. + // - See https://github.com/KhronosGroup/MoltenVK/issues/2016 and https://github.com/goki/vgpu/issues/9 + // - Issue solved in Vulkan SDK >= 1.3.275.0, but config uses VK_EXT_layer_settings instead of this code. + if( mvkConfig.useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER && r_mvkUseMetalArgumentBuffers.GetInteger() ) { - idLib::Printf( "Enabled MoltenVK's Metal argument buffers for descriptor indexing...\n" ); - mvkConfig.useMetalArgumentBuffers = MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING; + idLib::Printf( "Enabled MoltenVK's Metal argument buffers...\n" ); + mvkConfig.useMetalArgumentBuffers = MVKUseMetalArgumentBuffers( r_mvkUseMetalArgumentBuffers.GetInteger() ); } #if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 ) @@ -1432,7 +1446,7 @@ void DeviceManager_VK::BeginFrame() #if defined(__APPLE__) && defined( USE_MoltenVK ) #if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 ) - if( m_DeviceApiVersion >= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) ) + if( vkGetPerformanceStatisticsMVK && m_DeviceApiVersion >= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) ) { // SRS - get MoltenVK's Metal encoding time and GPU memory usage for display in statistics overlay HUD MVKPerformanceStatistics mvkPerfStats;