mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 10:38:53 +00:00
macOS: Support VK_EXT_layer_settings for MoltenVK >= 1.2.7 / Vulkan SDK >= 1.3.272.0
(cherry picked from commit f3c65eef3e75ea2846cffd97aff1fd2f9bf92f7f)
This commit is contained in:
parent
ec2719b099
commit
e80b6a3e21
1 changed files with 154 additions and 70 deletions
|
@ -38,7 +38,12 @@
|
|||
#include <nvrhi/vulkan.h>
|
||||
// SRS - optionally needed for MoltenVK runtime config visibility
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
#include <MoltenVK/vk_mvk_moltenvk.h>
|
||||
#if 0
|
||||
#include <MoltenVK/mvk_vulkan.h>
|
||||
#include <MoltenVK/mvk_config.h> // SRS - will eventually move to these mvk include files for MoltenVK >= 1.2.7 / SDK >= 1.3.272.0
|
||||
#else
|
||||
#include <MoltenVK/vk_mvk_moltenvk.h> // SRS - now deprecated, but provides backwards compatibility for MoltenVK < 1.2.7 / SDK < 1.3.272.0
|
||||
#endif
|
||||
idCVar r_mvkSynchronousQueueSubmits( "r_mvkSynchronousQueueSubmits", "0", CVAR_BOOL | CVAR_INIT, "Use MoltenVK's synchronous queue submit option." );
|
||||
#endif
|
||||
#include <nvrhi/validation.h>
|
||||
|
@ -201,9 +206,15 @@ private:
|
|||
{
|
||||
// instance
|
||||
{
|
||||
#if defined(__APPLE__) && defined( VK_KHR_portability_enumeration )
|
||||
#if defined(__APPLE__)
|
||||
#if defined( VK_KHR_portability_enumeration )
|
||||
// SRS - This is optional since it only became manadatory with Vulkan SDK 1.3.216.0 or later
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
|
||||
#endif
|
||||
#if defined( VK_EXT_layer_settings )
|
||||
// SRS - This is optional since implemented only for MoltenVK 1.2.7 / SDK 1.3.272.0 or later
|
||||
VK_EXT_LAYER_SETTINGS_EXTENSION_NAME,
|
||||
#endif
|
||||
#endif
|
||||
VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME,
|
||||
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
|
||||
|
@ -223,10 +234,8 @@ private:
|
|||
#if defined( VK_KHR_format_feature_flags2 )
|
||||
VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME,
|
||||
#endif
|
||||
#if defined( VK_EXT_memory_budget )
|
||||
VK_EXT_MEMORY_BUDGET_EXTENSION_NAME,
|
||||
#endif
|
||||
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME
|
||||
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
|
||||
VK_EXT_MEMORY_BUDGET_EXTENSION_NAME
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -287,6 +296,9 @@ private:
|
|||
// SRS - flag indicating support for presentation timing via VK_GOOGLE_display_timing extension
|
||||
bool displayTimingEnabled = false;
|
||||
|
||||
// SRS - slot for Vulkan device API version at runtime (initialize to Vulkan build version)
|
||||
uint32_t m_DeviceApiVersion = VK_HEADER_VERSION_COMPLETE;
|
||||
|
||||
private:
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL vulkanDebugCallback(
|
||||
VkDebugReportFlagsEXT flags,
|
||||
|
@ -427,6 +439,7 @@ bool DeviceManager_VK::createInstance()
|
|||
|
||||
std::unordered_set<std::string> requiredLayers = enabledExtensions.layers;
|
||||
|
||||
auto instanceVersion = vk::enumerateInstanceVersion();
|
||||
for( const auto& layer : vk::enumerateInstanceLayerProperties() )
|
||||
{
|
||||
const std::string name = layer.layerName;
|
||||
|
@ -434,9 +447,9 @@ bool DeviceManager_VK::createInstance()
|
|||
{
|
||||
enabledExtensions.layers.insert( name );
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) && !defined( USE_MoltenVK )
|
||||
// SRS - Vulkan SDK < 1.3.268.1 does not have native VK_KHR_synchronization2 support on macOS, add Khronos layer to emulate
|
||||
else if( name == "VK_LAYER_KHRONOS_synchronization2" && VK_HEADER_VERSION_COMPLETE < VK_MAKE_API_VERSION( 0, 1, 3, 268 ) )
|
||||
else if( name == "VK_LAYER_KHRONOS_synchronization2" && instanceVersion < VK_MAKE_API_VERSION( 0, 1, 3, 268 ) )
|
||||
{
|
||||
enabledExtensions.layers.insert( name );
|
||||
}
|
||||
|
@ -478,11 +491,63 @@ bool DeviceManager_VK::createInstance()
|
|||
.setPpEnabledExtensionNames( instanceExtVec.data() )
|
||||
.setPApplicationInfo( &applicationInfo );
|
||||
|
||||
#if defined(__APPLE__) && defined( VK_KHR_portability_enumeration )
|
||||
#if defined(__APPLE__)
|
||||
#if defined( VK_KHR_portability_enumeration )
|
||||
if( enabledExtensions.instance.find( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME ) != enabledExtensions.instance.end() )
|
||||
{
|
||||
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
|
||||
std::vector<vk::LayerSettingEXT> 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;
|
||||
|
||||
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 };
|
||||
|
||||
// SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR()
|
||||
layerSetting.pSettingName = "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eBool32;
|
||||
layerSetting.pValues = r_mvkSynchronousQueueSubmits.GetBool() ? &valueTrue : &valueFalse;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Enable MoltenVK's image view swizzle feature in case we don't have native image view swizzle
|
||||
layerSetting.pSettingName = "MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eBool32;
|
||||
layerSetting.pValues = &valueTrue;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Turn MoltenVK's Metal argument buffer feature on for descriptor indexing only
|
||||
layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eInt32;
|
||||
layerSetting.pValues = &useMetalArgumentBuffers;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// SRS - Disable MoltenVK's timestampPeriod filter for HUD / Optick profiler timing calibration
|
||||
layerSetting.pSettingName = "MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA";
|
||||
layerSetting.type = vk::LayerSettingTypeEXT::eFloat32;
|
||||
layerSetting.pValues = ×tampPeriodLowPassAlpha;
|
||||
layerSettings.push_back( layerSetting );
|
||||
|
||||
// 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 );
|
||||
|
||||
layerSettingsCreateInfo.settingCount = uint32_t( layerSettings.size() );
|
||||
layerSettingsCreateInfo.pSettings = layerSettings.data();
|
||||
|
||||
info.setPNext( &layerSettingsCreateInfo );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const vk::Result res = vk::createInstance( &info, nullptr, &m_VulkanInstance );
|
||||
|
@ -939,9 +1004,10 @@ bool DeviceManager_VK::createDevice()
|
|||
enablePModeImmediate = find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eImmediate ) != surfacePModes.end();
|
||||
enablePModeFifoRelaxed = find( surfacePModes.begin(), surfacePModes.end(), vk::PresentModeKHR::eFifoRelaxed ) != surfacePModes.end();
|
||||
|
||||
// stash the renderer string
|
||||
// stash the device renderer string and api version
|
||||
auto prop = m_VulkanPhysicalDevice.getProperties();
|
||||
m_RendererString = std::string( prop.deviceName.data() );
|
||||
m_DeviceApiVersion = prop.apiVersion;
|
||||
|
||||
// SRS - Determine maxPushConstantSize for Vulkan device
|
||||
if( r_useVulkanPushConstants.GetBool() )
|
||||
|
@ -1123,7 +1189,6 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
{
|
||||
enabledExtensions.instance.insert( VK_EXT_DEBUG_REPORT_EXTENSION_NAME );
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
enabledExtensions.layers.insert( "MoltenVK" );
|
||||
}
|
||||
|
||||
// SRS - when USE_MoltenVK defined, load libMoltenVK vs. the default libvulkan
|
||||
|
@ -1171,49 +1236,57 @@ bool DeviceManager_VK::CreateDeviceAndSwapChain()
|
|||
CHECK( pickPhysicalDevice() );
|
||||
CHECK( findQueueFamilies( m_VulkanPhysicalDevice, m_WindowSurface ) );
|
||||
|
||||
// SRS - when USE_MoltenVK defined, set MoltenVK runtime configuration parameters on macOS
|
||||
// SRS - when USE_MoltenVK defined, set MoltenVK runtime configuration parameters on macOS (deprecated version)
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
vk::PhysicalDeviceFeatures2 deviceFeatures2;
|
||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures;
|
||||
deviceFeatures2.setPNext( &portabilityFeatures );
|
||||
m_VulkanPhysicalDevice.getFeatures2( &deviceFeatures2 );
|
||||
|
||||
MVKConfiguration mvkConfig;
|
||||
size_t mvkConfigSize = sizeof( mvkConfig );
|
||||
|
||||
vkGetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
|
||||
// SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR()
|
||||
if( mvkConfig.synchronousQueueSubmits == VK_TRUE && !r_mvkSynchronousQueueSubmits.GetBool() )
|
||||
{
|
||||
idLib::Printf( "Disabled MoltenVK's synchronous queue submits...\n" );
|
||||
mvkConfig.synchronousQueueSubmits = VK_FALSE;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
}
|
||||
|
||||
// SRS - If we don't have native image view swizzle, enable MoltenVK's image view swizzle feature
|
||||
if( portabilityFeatures.imageViewFormatSwizzle == VK_FALSE )
|
||||
{
|
||||
idLib::Printf( "Enabled MoltenVK's image view swizzle...\n" );
|
||||
mvkConfig.fullImageViewSwizzle = VK_TRUE;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
}
|
||||
|
||||
// SRS - Turn MoltenVK's Metal argument buffer feature on for descriptor indexing only
|
||||
if( mvkConfig.useMetalArgumentBuffers == MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_NEVER )
|
||||
{
|
||||
idLib::Printf( "Enabled MoltenVK's Metal argument buffers for descriptor indexing...\n" );
|
||||
mvkConfig.useMetalArgumentBuffers = MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
}
|
||||
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
// SRS - Disable MoltenVK's timestampPeriod filter for HUD / Optick profiler timing calibration
|
||||
mvkConfig.timestampPeriodLowPassAlpha = 1.0;
|
||||
// SRS - Enable MoltenVK's performance tracking for display of Metal encoding timer on macOS
|
||||
mvkConfig.performanceTracking = VK_TRUE;
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
// SRS - deprecated by VK_EXT_layer_settings, but retained for older versions of MoltenVK < 1.2.7 / SDK < 1.3.272.0
|
||||
#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
|
||||
{
|
||||
vk::PhysicalDeviceFeatures2 deviceFeatures2;
|
||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR portabilityFeatures;
|
||||
deviceFeatures2.setPNext( &portabilityFeatures );
|
||||
m_VulkanPhysicalDevice.getFeatures2( &deviceFeatures2 );
|
||||
|
||||
MVKConfiguration mvkConfig;
|
||||
size_t mvkConfigSize = sizeof( mvkConfig );
|
||||
|
||||
vkGetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
|
||||
// SRS - Set MoltenVK's synchronous queue submit option for vkQueueSubmit() & vkQueuePresentKHR()
|
||||
if( mvkConfig.synchronousQueueSubmits == VK_TRUE && !r_mvkSynchronousQueueSubmits.GetBool() )
|
||||
{
|
||||
idLib::Printf( "Disabled MoltenVK's synchronous queue submits...\n" );
|
||||
mvkConfig.synchronousQueueSubmits = VK_FALSE;
|
||||
}
|
||||
|
||||
// SRS - If we don't have native image view swizzle, enable MoltenVK's image view swizzle feature
|
||||
if( portabilityFeatures.imageViewFormatSwizzle == VK_FALSE )
|
||||
{
|
||||
idLib::Printf( "Enabled MoltenVK's image view swizzle...\n" );
|
||||
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 )
|
||||
{
|
||||
idLib::Printf( "Enabled MoltenVK's Metal argument buffers for descriptor indexing...\n" );
|
||||
mvkConfig.useMetalArgumentBuffers = MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_DESCRIPTOR_INDEXING;
|
||||
}
|
||||
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
if( mvkConfig.apiVersionToAdvertise >= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) )
|
||||
{
|
||||
// SRS - Disable MoltenVK's timestampPeriod filter for HUD / Optick profiler timing calibration
|
||||
mvkConfig.timestampPeriodLowPassAlpha = 1.0;
|
||||
// SRS - Enable MoltenVK's performance tracking for display of Metal encoding timer on macOS
|
||||
mvkConfig.performanceTracking = VK_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
vkSetMoltenVKConfigurationMVK( m_VulkanInstance, &mvkConfig, &mvkConfigSize );
|
||||
}
|
||||
#endif
|
||||
|
||||
CHECK( createDevice() );
|
||||
|
@ -1342,27 +1415,38 @@ void DeviceManager_VK::BeginFrame()
|
|||
|
||||
#if defined(__APPLE__) && defined( USE_MoltenVK )
|
||||
#if MVK_VERSION >= MVK_MAKE_VERSION( 1, 2, 6 )
|
||||
// SRS - get MoltenVK's Metal encoding time and GPU memory usage for display in statistics overlay HUD
|
||||
MVKPerformanceStatistics mvkPerfStats;
|
||||
size_t mvkPerfStatsSize = sizeof( mvkPerfStats );
|
||||
vkGetPerformanceStatisticsMVK( m_VulkanDevice, &mvkPerfStats, &mvkPerfStatsSize );
|
||||
commonLocal.SetRendererMvkEncodeMicroseconds( uint64( Max( 0.0, mvkPerfStats.queue.submitCommandBuffers.latest - mvkPerfStats.queue.retrieveCAMetalDrawable.latest ) * 1000.0 ) );
|
||||
commonLocal.SetRendererGpuMemoryMB( int( mvkPerfStats.device.gpuMemoryAllocated.latest / 1024.0 ) );
|
||||
#endif
|
||||
#elif defined( VK_EXT_memory_budget )
|
||||
// SRS - get Vulkan GPU memory usage for display in statistics overlay HUD
|
||||
vk::PhysicalDeviceMemoryProperties2 memoryProperties2;
|
||||
vk::PhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
|
||||
memoryProperties2.pNext = &memoryBudget;
|
||||
m_VulkanPhysicalDevice.getMemoryProperties2( &memoryProperties2 );
|
||||
|
||||
VkDeviceSize gpuMemoryAllocated = 0;
|
||||
for( uint32_t i = 0; i < memoryProperties2.memoryProperties.memoryHeapCount; i++ )
|
||||
if( m_DeviceApiVersion >= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) )
|
||||
{
|
||||
gpuMemoryAllocated += memoryBudget.heapUsage[i];
|
||||
// SRS - get MoltenVK's Metal encoding time and GPU memory usage for display in statistics overlay HUD
|
||||
MVKPerformanceStatistics mvkPerfStats;
|
||||
size_t mvkPerfStatsSize = sizeof( mvkPerfStats );
|
||||
vkGetPerformanceStatisticsMVK( m_VulkanDevice, &mvkPerfStats, &mvkPerfStatsSize );
|
||||
commonLocal.SetRendererMvkEncodeMicroseconds( uint64( Max( 0.0, mvkPerfStats.queue.submitCommandBuffers.latest - mvkPerfStats.queue.retrieveCAMetalDrawable.latest ) * 1000.0 ) );
|
||||
commonLocal.SetRendererGpuMemoryMB( int( mvkPerfStats.device.gpuMemoryAllocated.latest / 1024.0 ) );
|
||||
}
|
||||
commonLocal.SetRendererGpuMemoryMB( int( gpuMemoryAllocated / 1024 / 1024 ) );
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
// SRS - get Vulkan GPU memory usage for display in statistics overlay HUD
|
||||
vk::PhysicalDeviceMemoryProperties2 memoryProperties2;
|
||||
vk::PhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget;
|
||||
memoryProperties2.pNext = &memoryBudget;
|
||||
m_VulkanPhysicalDevice.getMemoryProperties2( &memoryProperties2 );
|
||||
|
||||
VkDeviceSize gpuMemoryAllocated = 0;
|
||||
for( uint32_t i = 0; i < memoryProperties2.memoryProperties.memoryHeapCount; i++ )
|
||||
{
|
||||
gpuMemoryAllocated += memoryBudget.heapUsage[i];
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// SRS - macOS Vulkan API <= 1.2.268 has heap reporting defect, use heapUsage[0] only
|
||||
if( m_DeviceApiVersion <= VK_MAKE_API_VERSION( 0, 1, 2, 268 ) )
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
commonLocal.SetRendererGpuMemoryMB( int( gpuMemoryAllocated / 1024 / 1024 ) );
|
||||
}
|
||||
|
||||
const vk::Result res = m_VulkanDevice.acquireNextImageKHR( m_SwapChain,
|
||||
std::numeric_limits<uint64_t>::max(), // timeout
|
||||
|
|
Loading…
Reference in a new issue