Merge pull request #1298 from billhollings/auto-gpu-capture-fixes

Fixes to auto GPU capture
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index ed74893..3043525 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -58,6 +58,15 @@
 #define VK_MVK_MOLTENVK_SPEC_VERSION            31
 #define VK_MVK_MOLTENVK_EXTENSION_NAME          "VK_MVK_moltenvk"
 
+/** Identifies the scope for Metal to run an automatic GPU capture for diagnostic debugging purposes. */
+typedef enum MVKConfigAutoGPUCaptureScopeBits {
+	MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_NONE     = 0,	/**< No automatic GPU capture. */
+	MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE   = 1,	/**< Automatically capture all GPU activity during the lifetime of a VkDevice. */
+	MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME    = 2,	/**< Automatically capture all GPU activity during the rendering and presentation of the first frame. */
+	MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_MAX_ENUM = 0x7FFFFFFF
+} MVKConfigAutoGPUCaptureScopeBits;
+typedef VkFlags MVKConfigAutoGPUCaptureScope;
+
 /** Identifies extensions to advertise as part of MoltenVK configuration. */
 typedef enum MVKConfigAdvertiseExtensionBits {
 	MVK_CONFIG_ADVERTISE_EXTENSIONS_ALL         = 0x00000001,	/**< All supported extensions. */
@@ -390,18 +399,21 @@
 	VkBool32 switchSystemGPU;
 
 	/**
-	 * If enabled, arbitrary VkImageView component swizzles are supported, as defined
-	 * in VkImageViewCreateInfo::components when creating a VkImageView.
+	 * Older versions of Metal do not natively support per-texture swizzling. When running on
+	 * such a system, and this parameter is enabled, arbitrary VkImageView component swizzles
+	 * are supported, as defined in VkImageViewCreateInfo::components when creating a VkImageView.
 	 *
-	 * If disabled, a very limited set of VkImageView component swizzles are supported
-	 * via format substitutions.
+	 * If disabled, and native Metal per-texture swizzling is not available on the platform,
+	 * a very limited set of VkImageView component swizzles are supported via format substitutions.
 	 *
-	 * Metal does not natively support per-texture swizzling. If this parameter is enabled
-	 * both when a VkImageView is created, and when any pipeline that uses that VkImageView
-	 * is compiled, VkImageView swizzling is automatically performed in the converted Metal
-	 * shader code during all texture sampling and reading operations, regardless of whether
-	 * a swizzle is required for the VkImageView associated with the Metal texture.
-	 * This may result in reduced performance.
+	 * If Metal supports native per-texture swizzling, this parameter is ignored.
+
+	 * When running on an older version of Metal that does not support native per-texture
+	 * swizzling, if this parameter is enabled, both when a VkImageView is created, and
+	 * when any pipeline that uses that VkImageView is compiled, VkImageView swizzling is
+	 * automatically performed in the converted Metal shader code during all texture sampling
+	 * and reading operations, regardless of whether a swizzle is required for the VkImageView
+	 * associated with the Metal texture. This may result in reduced performance.
 	 *
 	 * The value of this parameter may be changed at any time during application runtime,
 	 * and the changed value will immediately effect subsequent MoltenVK behaviour.
@@ -420,8 +432,9 @@
 	 * in a call to vkGetPhysicalDeviceImageFormatProperties2KHR() to query for an VkImageView
 	 * format that will require full swizzling to be enabled, and this feature is not enabled.
 	 *
-	 * If this parameter is disabled, the following limited set of VkImageView swizzles are
-	 * supported by MoltenVK, via automatic format substitution:
+	 * If this parameter is disabled, and native Metal per-texture swizzling is not available
+	 * on the platform, the following limited set of VkImageView swizzles are supported by
+	 * MoltenVK, via automatic format substitution:
 	 *
 	 * Texture format			       Swizzle
 	 * --------------                  -------
@@ -585,15 +598,14 @@
 	 * Controls whether Metal should run an automatic GPU capture without the user having to
 	 * trigger it manually via the Xcode user interface, and controls the scope under which
 	 * that GPU capture will occur. This is useful when trying to capture a one-shot GPU trace,
-	 * such as when running a Vulkan CTS test case. For the automatic GPU capture to occur,
-	 * the Xcode scheme under which the app is run must have the Metal GPU capture option
-	 * enabled. MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE should not be set to manually trigger a
-	 * GPU capture via the Xcode user interface.
+	 * such as when running a Vulkan CTS test case. For the automatic GPU capture to occur, the
+	 * Xcode scheme under which the app is run must have the Metal GPU capture option enabled.
+	 * This parameter should not be set to manually trigger a GPU capture via the Xcode user interface.
 	 *
-	 * To automatically trigger a GPU capture, set this value as follows:
-	 *   0: No automatic GPU capture.
-	 *   1: Capture all GPU commands issued during the lifetime of the VkDevice.
-	 *   2: Capture all GPU commands issued during the first rendered frame.
+	 * When the value of this parameter is MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME,
+	 * the queue for which the GPU activity is captured is identifed by the values of
+	 * the defaultGPUCaptureScopeQueueFamilyIndex and defaultGPUCaptureScopeQueueIndex
+	 * configuration parameters.
 	 *
 	 * The value of this parameter must be changed before creating a VkDevice,
 	 * for the change to take effect.
@@ -603,7 +615,7 @@
 	 * runtime environment variable or MoltenVK compile-time build setting.
 	 * If neither is set, no automatic GPU capture will occur.
 	 */
-	uint32_t autoGPUCaptureScope;
+	MVKConfigAutoGPUCaptureScope autoGPUCaptureScope;
 
 	/**
 	 * The path to a file where the automatic GPU capture should be saved, if autoGPUCaptureScope
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index 2a821d0..c65ffae 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -698,27 +698,17 @@
 	 * capture scope, and if so, starts capturing from the specified Metal capture object.
 	 * The capture will be made either to Xcode, or to a file if one has been configured.
 	 *
-	 * The autoGPUCaptureScope parameter must be one of:
-	 *   - MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_NONE
-	 *   - MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE
-	 *   - MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME
-	 *
 	 * The mtlCaptureObject must be one of:
 	 *   - MTLDevice for scope MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE
 	 *   - MTLCommandQueue for scope MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME.
 	 */
-	void startAutoGPUCapture(int32_t autoGPUCaptureScope, id mtlCaptureObject);
+	void startAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope, id mtlCaptureObject);
 
 	/**
 	 * Checks if automatic GPU capture is enabled for the specified
 	 * auto capture scope, and if so, stops capturing.
-	 *
-	 * The autoGPUCaptureScope parameter must be one of:
-	 *   - MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_NONE
-	 *   - MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE
-	 *   - MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME
 	 */
-	void stopAutoGPUCapture(int32_t autoGPUCaptureScope);
+	void stopAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope);
 
 	/** Returns whether this instance is currently automatically capturing a GPU trace. */
 	inline bool isCurrentlyAutoGPUCapturing() { return _isCurrentlyAutoGPUCapturing; }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index a023c20..9b9c923 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -3680,7 +3680,7 @@
 			  _enabledInlineUniformBlockFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind));
 }
 
-void MVKDevice::startAutoGPUCapture(int32_t autoGPUCaptureScope, id mtlCaptureObject) {
+void MVKDevice::startAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope, id mtlCaptureObject) {
 
 	if (_isCurrentlyAutoGPUCapturing || (mvkGetMVKConfiguration()->autoGPUCaptureScope != autoGPUCaptureScope)) { return; }
 
@@ -3729,7 +3729,7 @@
 	}
 }
 
-void MVKDevice::stopAutoGPUCapture(int32_t autoGPUCaptureScope) {
+void MVKDevice::stopAutoGPUCapture(MVKConfigAutoGPUCaptureScope autoGPUCaptureScope) {
 	if (_isCurrentlyAutoGPUCapturing && mvkGetMVKConfiguration()->autoGPUCaptureScope == autoGPUCaptureScope) {
 		[[MTLCaptureManager sharedCaptureManager] stopCapture];
 		_isCurrentlyAutoGPUCapturing = false;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
index c502387..7e549b3 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
@@ -214,13 +214,15 @@
 void MVKQueue::initGPUCaptureScopes() {
 	_submissionCaptureScope = new MVKGPUCaptureScope(this);
 
-	if (_queueFamily->getIndex() == mvkGetMVKConfiguration()->defaultGPUCaptureScopeQueueFamilyIndex &&
-		_index == mvkGetMVKConfiguration()->defaultGPUCaptureScopeQueueIndex) {
+	const MVKConfiguration* pMVKConfig = mvkGetMVKConfiguration();
+	if (_queueFamily->getIndex() == pMVKConfig->defaultGPUCaptureScopeQueueFamilyIndex &&
+		_index == pMVKConfig->defaultGPUCaptureScopeQueueIndex) {
+
+		getDevice()->startAutoGPUCapture(MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME, _mtlQueue);
 		_submissionCaptureScope->makeDefault();
+
 	}
 	_submissionCaptureScope->beginScope();	// Allow Xcode to capture the first frame if desired.
-
-	getDevice()->startAutoGPUCapture(MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME, _mtlQueue);
 }
 
 MVKQueue::~MVKQueue() {
diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
index 7aa09f2..e93ad4a 100644
--- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
+++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
@@ -222,9 +222,6 @@
  * developer having to trigger it manually via the Xcode UI. This is useful when trying
  * to capture a one-shot trace, such as when running a Vulkan CTS test case.
  */
-#define MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_NONE		0
-#define MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE	1
-#define MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_FRAME		2
 #ifndef MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE
 #   define MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE    	MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_NONE
 #endif