diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index fb3eb2f8..c97b41c2 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -106,10 +106,10 @@ typedef enum MVKUseMetalArgumentBuffers { /** Identifies the Metal functionality used to support Vulkan semaphore functionality (VkSemaphore). */ typedef enum MVKVkSemaphoreSupportStyle { - MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK = 0, /**< Use CPU callbacks upon GPU submission completion. This is the slowest technique. */ - MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1, /**< Use Metal events (MTLEvent) when available on the platform, and where safe. This will revert to same as MVK_CONFIG_VK_SEMAPHORE_USE_SINGLE_QUEUE on some NVIDIA GPUs and Rosetta2, due to potential challenges with MTLEvents on those platforms. */ - MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS = 2, /**< Always use Metal events (MTLEvent) when available on the platform. */ - MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE = 3, /**< Limit Vulkan to a single queue, with no explicit semaphore synchronization, and use Metal's implicit guarantees that all operations submitted to a queue will give the same result as if they had been run in submission order. */ + MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE = 0, /**< Limit Vulkan to a single queue, with no explicit semaphore synchronization, and use Metal's implicit guarantees that all operations submitted to a queue will give the same result as if they had been run in submission order. */ + MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1, /**< Use Metal events (MTLEvent) when available on the platform, and where safe. This will revert to same as MVK_CONFIG_VK_SEMAPHORE_USE_SINGLE_QUEUE on some NVIDIA GPUs and Rosetta2, due to potential challenges with MTLEvents on those platforms, or in older environments where MTLEvents are not supported. */ + MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS = 2, /**< Always use Metal events (MTLEvent) when available on the platform. This will revert to same as MVK_CONFIG_VK_SEMAPHORE_USE_SINGLE_QUEUE in older environments where MTLEvents are not supported. */ + MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK = 3, /**< Use CPU callbacks upon GPU submission completion. This is the slowest technique, but allows multiple queues, compared to MVK_CONFIG_VK_SEMAPHORE_USE_SINGLE_QUEUE. */ MVK_CONFIG_VK_SEMAPHORE_MAX_ENUM = 0x7FFFFFFF } MVKVkSemaphoreSupportStyle; @@ -574,7 +574,7 @@ typedef struct { */ VkBool32 forceLowPowerGPU; - /** Deprecated. Use semaphoreSupportStyle instead. */ + /** Deprecated. Vulkan sempphores using MTLFence are no longer supported. Use semaphoreSupportStyle instead. */ VkBool32 semaphoreUseMTLFence; /** @@ -592,15 +592,17 @@ typedef struct { * runtime environment variable or MoltenVK compile-time build setting. * If neither is set, this setting is set to * MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE by default, - * and MoltenVK will use MTLEvent, except on NVIDIA GPU, and Rosetta2 environments, - * where it will use a single queue with implicit synchronization - * (as if this parameter was set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE). + * and MoltenVK will use MTLEvent, except on NVIDIA GPU and Rosetta2 environments, + * or where MTLEvents are not supported, where it will use a single queue with + * implicit synchronization (as if this parameter was set to + * MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE). * * This parameter interacts with the deprecated legacy parameters semaphoreUseMTLEvent - * and semaphoreUseMTLFence. If semaphoreUseMTLEvent is enabled, this parameter - * will be set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE. - * If semaphoreUseMTLEvent is disabled, and semaphoreUseMTLFence is enabled, - * this parameter will be set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE. + * and semaphoreUseMTLFence. If semaphoreUseMTLEvent is enabled, this parameter will be + * set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE. + * If semaphoreUseMTLEvent is disabled, this parameter will be set to + * MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE if semaphoreUseMTLFence is enabled, + * or MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK if semaphoreUseMTLFence is disabled. * Structurally, this parameter replaces, and is aliased by, semaphoreUseMTLEvent. */ MVKVkSemaphoreSupportStyle semaphoreSupportStyle; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index f67ac5c8..32319529 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3118,12 +3118,13 @@ void MVKPhysicalDevice::initCounterSets() { // Determine whether Vulkan semaphores should use a MTLEvent, CPU callbacks, or should limit // Vulkan to a single queue and use Metal's implicit guarantees that all operations submitted // to a queue will give the same result as if they had been run in submission order. -// MTLEvents for semaphores can sometimes prove troublesome on some platforms, -// and so may optionally be disabled on those platforms. +// MTLEvents for semaphores are preferred, but can sometimes prove troublesome on some platforms, +// and so may be disabled on those platforms, unless explicitly requested. If MTLEvents are +// unusable, void MVKPhysicalDevice::initVkSemaphoreStyle() { - // Default to CPU callback if other options unavailable. - _vkSemaphoreStyle = MVKSemaphoreStyleUseEmulation; + // Default to single queue if other options unavailable. + _vkSemaphoreStyle = MVKSemaphoreStyleSingleQueue; switch (mvkConfig().semaphoreSupportStyle) { case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE: { @@ -3135,10 +3136,10 @@ void MVKPhysicalDevice::initVkSemaphoreStyle() { case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS: if (_metalFeatures.events) { _vkSemaphoreStyle = MVKSemaphoreStyleUseMTLEvent; } break; - case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE: - _vkSemaphoreStyle = MVKSemaphoreStyleSingleQueue; - break; case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK: + _vkSemaphoreStyle = MVKSemaphoreStyleUseEmulation; + break; + case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE: default: break; } diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp index f28af093..c3a8805c 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.cpp @@ -66,12 +66,12 @@ static void mvkInitConfigFromEnvVars() { // Legacy MVK_ALLOW_METAL_EVENTS is covered by MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE, // but for backwards compatibility, if legacy MVK_ALLOW_METAL_EVENTS is explicitly // disabled, disable semaphoreUseMTLEvent (aliased as semaphoreSupportStyle value - // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK), and let mvkSetConfig() further - // process legacy behavior based on the value of legacy semaphoreUseMTLFence). + // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE), and let mvkSetConfig() + // further process legacy behavior of MVK_ALLOW_METAL_FENCES. bool sem4UseMTLEvent; MVK_SET_FROM_ENV_OR_BUILD_BOOL(sem4UseMTLEvent, MVK_ALLOW_METAL_EVENTS); if ( !sem4UseMTLEvent ) { - evCfg.semaphoreUseMTLEvent = (MVKVkSemaphoreSupportStyle)false; // Disabled. Also semaphoreSupportStyle MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK. + evCfg.semaphoreUseMTLEvent = (MVKVkSemaphoreSupportStyle)false; // Disabled. Also semaphoreSupportStyle MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE. } mvkSetConfig(evCfg); @@ -102,11 +102,12 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig) { VK_VERSION_MINOR(_mvkConfig.apiVersionToAdvertise), VK_HEADER_VERSION); - // Deprecated legacy support for specific case where semaphoreUseMTLFence is enabled and legacy - // semaphoreUseMTLEvent (now aliased to semaphoreSupportStyle) is disabled. In this case the user - // had been using the legacy MTLFence, so use MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE now. - if (_mvkConfig.semaphoreUseMTLFence && !_mvkConfig.semaphoreUseMTLEvent) { - _mvkConfig.semaphoreSupportStyle = MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE; + // Deprecated legacy support for specific case where both legacy semaphoreUseMTLEvent + // (now aliased to semaphoreSupportStyle) and legacy semaphoreUseMTLFence are explicitly + // disabled by the app. In this case the app had been using CPU emulation, so use + // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK. + if ( !_mvkConfig.semaphoreUseMTLEvent && !_mvkConfig.semaphoreUseMTLFence ) { + _mvkConfig.semaphoreSupportStyle = MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK; } // Set capture file path string diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h index dc9e4558..06abb170 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h @@ -241,7 +241,7 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig); # define MVK_ALLOW_METAL_EVENTS 1 #endif #ifndef MVK_ALLOW_METAL_FENCES // Deprecated -# define MVK_ALLOW_METAL_FENCES 0 +# define MVK_ALLOW_METAL_FENCES 1 #endif /** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */