Merge pull request #1418 from billhollings/vulkan-semaphores-via-mtlevents
Prefer MTLEvent for VkSemaphore, except on NVIDIA, prefer emulation.
This commit is contained in:
commit
77c31cd0da
@ -18,6 +18,9 @@ MoltenVK 1.1.5
|
||||
|
||||
Released TBD
|
||||
|
||||
- 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.
|
||||
|
@ -557,14 +557,15 @@ typedef struct {
|
||||
/**
|
||||
* Use MTLFence, if it is available on the device, for VkSemaphore synchronization behaviour.
|
||||
*
|
||||
* This parameter interacts with semaphoreUseMTLEvent. If both are enabled, semaphoreUseMTLFence
|
||||
* takes priority and MTLFence will be used if it is available, otherwise MTLEvent will be used
|
||||
* if it is available. If neither semaphoreUseMTLFence or semaphoreUseMTLEvent are enabled, or
|
||||
* if neither MTLFence or MTLEvent are available, CPU-based synchoronization will be used.
|
||||
* 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, 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
|
||||
* MVK_ALLOW_METAL_FENCES or MVK_ALLOW_METAL_EVENTS.
|
||||
* semaphoreUseMTLEvent or semaphoreUseMTLFence.
|
||||
*
|
||||
* The value of this parameter must be changed before creating a VkDevice,
|
||||
* for the change to take effect.
|
||||
@ -572,22 +573,22 @@ 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.
|
||||
* If neither is set, this setting is disabled by default, and VkSemaphore will not use MTLFence.
|
||||
*/
|
||||
VkBool32 semaphoreUseMTLFence;
|
||||
|
||||
/**
|
||||
* Use MTLEvent, if it is available on the device, for VkSemaphore synchronization behaviour.
|
||||
*
|
||||
* This parameter interacts with semaphoreUseMTLFence. If both are enabled, semaphoreUseMTLFence
|
||||
* takes priority and MTLFence will be used if it is available, otherwise MTLEvent will be used
|
||||
* if it is available. If neither semaphoreUseMTLFence or semaphoreUseMTLEvent are enabled, or
|
||||
* if neither MTLFence or MTLEvent are available, CPU-based synchoronization will be used.
|
||||
* 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, 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
|
||||
* MVK_ALLOW_METAL_FENCES or MVK_ALLOW_METAL_EVENTS.
|
||||
* semaphoreUseMTLEvent or semaphoreUseMTLFence.
|
||||
*
|
||||
* The value of this parameter must be changed before creating a VkDevice,
|
||||
* for the change to take effect.
|
||||
@ -596,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, unless if MTLFence is available and semaphoreUseMTLFence is enabled.
|
||||
* if it is available, except on NVIDIA GPUs.
|
||||
*/
|
||||
VkBool32 semaphoreUseMTLEvent;
|
||||
|
||||
|
@ -832,11 +832,17 @@ protected:
|
||||
id<MTLBuffer> _dummyBlitMTLBuffer;
|
||||
uint32_t _globalVisibilityQueryCount;
|
||||
std::mutex _vizLock;
|
||||
bool _useMTLFenceForSemaphores;
|
||||
bool _useMTLEventForSemaphores;
|
||||
bool _logActivityPerformanceInline;
|
||||
bool _isPerformanceTracking;
|
||||
bool _isCurrentlyAutoGPUCapturing;
|
||||
|
||||
typedef enum {
|
||||
VkSemaphoreStyleUseMTLEvent,
|
||||
VkSemaphoreStyleUseMTLFence,
|
||||
VkSemaphoreStyleUseEmulation
|
||||
} VkSemaphoreStyle;
|
||||
VkSemaphoreStyle _vkSemaphoreStyle;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -3263,12 +3263,10 @@ MVKSemaphore* MVKDevice::createSemaphore(const VkSemaphoreCreateInfo* pCreateInf
|
||||
return new MVKTimelineSemaphoreEmulated(this, pCreateInfo, pTypeCreateInfo);
|
||||
}
|
||||
} else {
|
||||
if (_useMTLFenceForSemaphores) {
|
||||
return new MVKSemaphoreMTLFence(this, pCreateInfo);
|
||||
} else if (_useMTLEventForSemaphores) {
|
||||
return new MVKSemaphoreMTLEvent(this, pCreateInfo);
|
||||
} else {
|
||||
return new MVKSemaphoreEmulated(this, pCreateInfo);
|
||||
switch (_vkSemaphoreStyle) {
|
||||
case VkSemaphoreStyleUseMTLEvent: return new MVKSemaphoreMTLEvent(this, pCreateInfo);
|
||||
case VkSemaphoreStyleUseMTLFence: return new MVKSemaphoreMTLFence(this, pCreateInfo);
|
||||
case VkSemaphoreStyleUseEmulation: return new MVKSemaphoreEmulated(this, pCreateInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3953,11 +3951,24 @@ void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice, const VkDe
|
||||
_pProperties = &_physicalDevice->_properties;
|
||||
_pMemoryProperties = &_physicalDevice->_memoryProperties;
|
||||
|
||||
// Indicate whether semaphores should use a MTLFence or MTLEvent if they are available.
|
||||
_useMTLFenceForSemaphores = _pMetalFeatures->fences && mvkConfig().semaphoreUseMTLFence;
|
||||
_useMTLEventForSemaphores = _pMetalFeatures->events && mvkConfig().semaphoreUseMTLEvent;
|
||||
|
||||
MVKLogInfo("Using %s for Vulkan semaphores.", _useMTLFenceForSemaphores ? "MTLFence" : (_useMTLEventForSemaphores ? "MTLEvent" : "emulation"));
|
||||
// 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;
|
||||
_vkSemaphoreStyle = canUseMTLEventForSem4 ? VkSemaphoreStyleUseMTLEvent : (canUseMTLFenceForSem4 ? VkSemaphoreStyleUseMTLFence : VkSemaphoreStyleUseEmulation);
|
||||
switch (_vkSemaphoreStyle) {
|
||||
case VkSemaphoreStyleUseMTLEvent:
|
||||
MVKLogInfo("Using MTLEvent for Vulkan semaphores.");
|
||||
break;
|
||||
case VkSemaphoreStyleUseMTLFence:
|
||||
MVKLogInfo("Using MTLFence for Vulkan semaphores.");
|
||||
break;
|
||||
case VkSemaphoreStyleUseEmulation:
|
||||
MVKLogInfo("Using emulation for Vulkan semaphores.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user