Merge pull request #1738 from billhollings/fix-vulkan-sem4-fallback

Vulkan semaphore fallback to using single queue if `MTLEvents` unusable.
This commit is contained in:
Bill Hollings 2022-10-10 09:05:50 -05:00 committed by GitHub
commit 707da6e043
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 28 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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. */