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). */ /** Identifies the Metal functionality used to support Vulkan semaphore functionality (VkSemaphore). */
typedef enum MVKVkSemaphoreSupportStyle { 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_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. */ 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. */ 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_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_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 MVK_CONFIG_VK_SEMAPHORE_MAX_ENUM = 0x7FFFFFFF
} MVKVkSemaphoreSupportStyle; } MVKVkSemaphoreSupportStyle;
@ -574,7 +574,7 @@ typedef struct {
*/ */
VkBool32 forceLowPowerGPU; VkBool32 forceLowPowerGPU;
/** Deprecated. Use semaphoreSupportStyle instead. */ /** Deprecated. Vulkan sempphores using MTLFence are no longer supported. Use semaphoreSupportStyle instead. */
VkBool32 semaphoreUseMTLFence; VkBool32 semaphoreUseMTLFence;
/** /**
@ -592,15 +592,17 @@ typedef struct {
* runtime environment variable or MoltenVK compile-time build setting. * runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, this setting is set to * If neither is set, this setting is set to
* MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE by default, * MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE by default,
* and MoltenVK will use MTLEvent, except on NVIDIA GPU, and Rosetta2 environments, * and MoltenVK will use MTLEvent, except on NVIDIA GPU and Rosetta2 environments,
* where it will use a single queue with implicit synchronization * or where MTLEvents are not supported, where it will use a single queue with
* (as if this parameter was set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE). * 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 * This parameter interacts with the deprecated legacy parameters semaphoreUseMTLEvent
* and semaphoreUseMTLFence. If semaphoreUseMTLEvent is enabled, this parameter * and semaphoreUseMTLFence. If semaphoreUseMTLEvent is enabled, this parameter will be
* will be set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE. * set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE.
* If semaphoreUseMTLEvent is disabled, and semaphoreUseMTLFence is enabled, * If semaphoreUseMTLEvent is disabled, this parameter will be set to
* this parameter will be set to MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE. * 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. * Structurally, this parameter replaces, and is aliased by, semaphoreUseMTLEvent.
*/ */
MVKVkSemaphoreSupportStyle semaphoreSupportStyle; MVKVkSemaphoreSupportStyle semaphoreSupportStyle;

View File

@ -3118,12 +3118,13 @@ void MVKPhysicalDevice::initCounterSets() {
// Determine whether Vulkan semaphores should use a MTLEvent, CPU callbacks, or should limit // 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 // 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. // 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, // MTLEvents for semaphores are preferred, but can sometimes prove troublesome on some platforms,
// and so may optionally be disabled on those platforms. // and so may be disabled on those platforms, unless explicitly requested. If MTLEvents are
// unusable,
void MVKPhysicalDevice::initVkSemaphoreStyle() { void MVKPhysicalDevice::initVkSemaphoreStyle() {
// Default to CPU callback if other options unavailable. // Default to single queue if other options unavailable.
_vkSemaphoreStyle = MVKSemaphoreStyleUseEmulation; _vkSemaphoreStyle = MVKSemaphoreStyleSingleQueue;
switch (mvkConfig().semaphoreSupportStyle) { switch (mvkConfig().semaphoreSupportStyle) {
case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE: { 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: case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS:
if (_metalFeatures.events) { _vkSemaphoreStyle = MVKSemaphoreStyleUseMTLEvent; } if (_metalFeatures.events) { _vkSemaphoreStyle = MVKSemaphoreStyleUseMTLEvent; }
break; break;
case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE:
_vkSemaphoreStyle = MVKSemaphoreStyleSingleQueue;
break;
case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK: case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK:
_vkSemaphoreStyle = MVKSemaphoreStyleUseEmulation;
break;
case MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE:
default: default:
break; break;
} }

View File

@ -66,12 +66,12 @@ static void mvkInitConfigFromEnvVars() {
// Legacy MVK_ALLOW_METAL_EVENTS is covered by MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE, // 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 // but for backwards compatibility, if legacy MVK_ALLOW_METAL_EVENTS is explicitly
// disabled, disable semaphoreUseMTLEvent (aliased as semaphoreSupportStyle value // disabled, disable semaphoreUseMTLEvent (aliased as semaphoreSupportStyle value
// MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK), and let mvkSetConfig() further // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE), and let mvkSetConfig()
// process legacy behavior based on the value of legacy semaphoreUseMTLFence). // further process legacy behavior of MVK_ALLOW_METAL_FENCES.
bool sem4UseMTLEvent; bool sem4UseMTLEvent;
MVK_SET_FROM_ENV_OR_BUILD_BOOL(sem4UseMTLEvent, MVK_ALLOW_METAL_EVENTS); MVK_SET_FROM_ENV_OR_BUILD_BOOL(sem4UseMTLEvent, MVK_ALLOW_METAL_EVENTS);
if ( !sem4UseMTLEvent ) { 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); mvkSetConfig(evCfg);
@ -102,11 +102,12 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig) {
VK_VERSION_MINOR(_mvkConfig.apiVersionToAdvertise), VK_VERSION_MINOR(_mvkConfig.apiVersionToAdvertise),
VK_HEADER_VERSION); VK_HEADER_VERSION);
// Deprecated legacy support for specific case where semaphoreUseMTLFence is enabled and legacy // Deprecated legacy support for specific case where both legacy semaphoreUseMTLEvent
// semaphoreUseMTLEvent (now aliased to semaphoreSupportStyle) is disabled. In this case the user // (now aliased to semaphoreSupportStyle) and legacy semaphoreUseMTLFence are explicitly
// had been using the legacy MTLFence, so use MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE now. // disabled by the app. In this case the app had been using CPU emulation, so use
if (_mvkConfig.semaphoreUseMTLFence && !_mvkConfig.semaphoreUseMTLEvent) { // MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK.
_mvkConfig.semaphoreSupportStyle = MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE; if ( !_mvkConfig.semaphoreUseMTLEvent && !_mvkConfig.semaphoreUseMTLFence ) {
_mvkConfig.semaphoreSupportStyle = MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK;
} }
// Set capture file path string // Set capture file path string

View File

@ -241,7 +241,7 @@ void mvkSetConfig(const MVKConfiguration& mvkConfig);
# define MVK_ALLOW_METAL_EVENTS 1 # define MVK_ALLOW_METAL_EVENTS 1
#endif #endif
#ifndef MVK_ALLOW_METAL_FENCES // Deprecated #ifndef MVK_ALLOW_METAL_FENCES // Deprecated
# define MVK_ALLOW_METAL_FENCES 0 # define MVK_ALLOW_METAL_FENCES 1
#endif #endif
/** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */ /** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */