diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index b16a39b7..904ff96c 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -18,7 +18,9 @@ MoltenVK 1.1.5 Released TBD -- Revert to prefer `MTLEvent` over `MTLFence` for `VkSemaphore`, except on NVIDIA. +- Changes to how `VkSemaphore` is supported: + - Revert to prefer `MTLEvent` for `VkSemaphore`, except on NVIDIA, where emulation on CPU is preferred. + - Set default value of the `MVK_ALLOW_METAL_FENCES` environment variable to `0 (false)`, - Vulkan timestamp query pools use Metal GPU counters when available. - Support resolving attachments with formats that Metal does not natively resolve. - Fix issue where swapchain images were acquired out of order under heavy load. diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index 99138dfe..d3c8a743 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -559,9 +559,9 @@ typedef struct { * * This parameter interacts with semaphoreUseMTLEvent. If both are enabled, on GPUs other than * NVIDIA, semaphoreUseMTLEvent takes priority and MTLEvent will be used if it is available, - * otherwise MTLFence will be used if it is available. On NVIDIA GPUs, the opposite priority - * applies. If neither semaphoreUseMTLFence nor semaphoreUseMTLEvent are enabled, or if neither - * MTLEvent nor MTLFence are available, CPU-based synchoronization will be used. + * otherwise MTLFence will be used if it is available. On NVIDIA GPUs, MTLEvent is disabled + * for VkSemaphores, so CPU-based synchronization will be used unless semaphoreUseMTLFence + * is enabled and MTLFence is available. * * In the special case of VK_SEMAPHORE_TYPE_TIMELINE semaphores, MoltenVK will always * use MTLSharedEvent if it is available on the platform, regardless of the values of @@ -573,8 +573,7 @@ typedef struct { * The initial value or this parameter is set by the * MVK_ALLOW_METAL_FENCES * runtime environment variable or MoltenVK compile-time build setting. - * If neither is set, this setting is enabled by default, and VkSemaphore will use MTLFence, - * if it is available, unless MTLEvent is available and semaphoreUseMTLEvent is enabled. + * If neither is set, this setting is disabled by default, and VkSemaphore will not use MTLFence. */ VkBool32 semaphoreUseMTLFence; @@ -583,9 +582,9 @@ typedef struct { * * This parameter interacts with semaphoreUseMTLFence. If both are enabled, on GPUs other than * NVIDIA, semaphoreUseMTLEvent takes priority and MTLEvent will be used if it is available, - * otherwise MTLFence will be used if it is available. On NVIDIA GPUs, the opposite priority - * applies. If neither semaphoreUseMTLFence nor semaphoreUseMTLEvent are enabled, or if neither - * MTLEvent nor MTLFence are available, CPU-based synchoronization will be used. + * otherwise MTLFence will be used if it is available. On NVIDIA GPUs, MTLEvent is disabled + * for VkSemaphores, so CPU-based synchronization will be used unless semaphoreUseMTLFence + * is enabled and MTLFence is available. * * In the special case of VK_SEMAPHORE_TYPE_TIMELINE semaphores, MoltenVK will always * use MTLSharedEvent if it is available on the platform, regardless of the values of @@ -598,7 +597,7 @@ typedef struct { * MVK_ALLOW_METAL_EVENTS * runtime environment variable or MoltenVK compile-time build setting. * If neither is set, this setting is enabled by default, and VkSemaphore will use MTLEvent, - * if it is available. + * if it is available, except on NVIDIA GPUs. */ VkBool32 semaphoreUseMTLEvent; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index b41da9fa..6fd35daa 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3951,22 +3951,13 @@ void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice, const VkDe _pProperties = &_physicalDevice->_properties; _pMemoryProperties = &_physicalDevice->_memoryProperties; - // Decide whether semaphores should use a MTLFence or MTLEvent if they are available. - // Prefer MTLEvent over MTLFence, because MTLEvent handles sync across MTLCommandBuffers and MTLCommandQueues, - // except on NVIDIA GPUs, which have demonstrated trouble with MTLEvents, prefer MTLFence. - bool canUseMTLEventForSem4 = _pMetalFeatures->events && mvkConfig().semaphoreUseMTLEvent; + // Decide whether Vulkan semaphores should use a MTLEvent or MTLFence if they are available. + // Prefer MTLEvent, because MTLEvent handles sync across MTLCommandBuffers and MTLCommandQueues. + // However, do not allow use of MTLEvents on NVIDIA GPUs, which have demonstrated trouble with MTLEvents. + // Since MTLFence config is disabled by default, emulation will be used on NVIDIA unless MTLFence is enabled. + bool canUseMTLEventForSem4 = _pMetalFeatures->events && mvkConfig().semaphoreUseMTLEvent && (_pProperties->vendorID != kNVVendorId); bool canUseMTLFenceForSem4 = _pMetalFeatures->fences && mvkConfig().semaphoreUseMTLFence; - switch (_pProperties->vendorID) { - case kNVVendorId: - _vkSemaphoreStyle = canUseMTLFenceForSem4 ? VkSemaphoreStyleUseMTLFence : (canUseMTLEventForSem4 ? VkSemaphoreStyleUseMTLEvent : VkSemaphoreStyleUseEmulation); - break; - case kAppleVendorId: - case kIntelVendorId: - case kAMDVendorId: - default: - _vkSemaphoreStyle = canUseMTLEventForSem4 ? VkSemaphoreStyleUseMTLEvent : (canUseMTLFenceForSem4 ? VkSemaphoreStyleUseMTLFence : VkSemaphoreStyleUseEmulation); - break; - } + _vkSemaphoreStyle = canUseMTLEventForSem4 ? VkSemaphoreStyleUseMTLEvent : (canUseMTLFenceForSem4 ? VkSemaphoreStyleUseMTLFence : VkSemaphoreStyleUseEmulation); switch (_vkSemaphoreStyle) { case VkSemaphoreStyleUseMTLEvent: MVKLogInfo("Using MTLEvent for Vulkan semaphores."); diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h index 4cb724a1..e7d65446 100644 --- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h +++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h @@ -233,15 +233,15 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig); /** * Allow the use of MTLFence or MTLEvent for VkSemaphore synchronization behaviour. * By default: - * - MVK_ALLOW_METAL_FENCES is enabled * - MVK_ALLOW_METAL_EVENTS is enabled + * - MVK_ALLOW_METAL_FENCES is disabled * */ -#ifndef MVK_ALLOW_METAL_FENCES -# define MVK_ALLOW_METAL_FENCES 1 -#endif #ifndef MVK_ALLOW_METAL_EVENTS # define MVK_ALLOW_METAL_EVENTS 1 #endif +#ifndef MVK_ALLOW_METAL_FENCES +# define MVK_ALLOW_METAL_FENCES 0 +#endif /** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */ #ifndef MVK_CONFIG_TEXTURE_1D_AS_2D