Fix swizzle of depth and stencil values into RGBA (float4) variable in shaders.

MVKImageViewPlane track Vulkan component swizzle instead of just packed
swizzle, and modify swizzle when using depth or stencil sampling or reading.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index e7daeb8..6a1c749 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -19,6 +19,7 @@
 Released TBD
 
 - Fix incorrect translation of clear color values on Apple Silicon.
+- Fix swizzle of depth and stencil values into RGBA (`float4`) variable in shaders.
 
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index 9553499..a5ba5b8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -531,6 +531,9 @@
 
     void releaseMTLTexture();
 
+	/** Returns the packed component swizzle of this image view. */
+	uint32_t getPackedSwizzle() { return _useSwizzle ? mvkPackSwizzle(_componentSwizzle) : 0; }
+
     ~MVKImageViewPlane();
 
 protected:
@@ -541,10 +544,10 @@
 
     friend MVKImageView;
     MVKImageView* _imageView;
-    uint8_t _planeIndex;
+	id<MTLTexture> _mtlTexture;
+	VkComponentMapping _componentSwizzle;
     MTLPixelFormat _mtlPixFmt;
-    uint32_t _packedSwizzle;
-    id<MTLTexture> _mtlTexture;
+	uint8_t _planeIndex;
     bool _useMTLTextureView;
 	bool _useSwizzle;
 };
@@ -570,16 +573,16 @@
 	id<MTLTexture> getMTLTexture(uint8_t planeIndex) { return _planes[planeIndex]->getMTLTexture(); }
 
 	/** Returns the Metal pixel format of this image view. */
-	inline MTLPixelFormat getMTLPixelFormat(uint8_t planeIndex) { return _planes[planeIndex]->_mtlPixFmt; }
+	MTLPixelFormat getMTLPixelFormat(uint8_t planeIndex) { return _planes[planeIndex]->_mtlPixFmt; }
     
     /** Returns the packed component swizzle of this image view. */
-    inline uint32_t getPackedSwizzle() { return _planes[0]->_packedSwizzle; }
+    uint32_t getPackedSwizzle() { return _planes[0]->getPackedSwizzle(); }
     
     /** Returns the number of planes of this image view. */
-    inline uint8_t getPlaneCount() { return _planes.size(); }
+    uint8_t getPlaneCount() { return _planes.size(); }
 
 	/** Returns the Metal texture type of this image view. */
-	inline MTLTextureType getMTLTextureType() { return _mtlTextureType; }
+	MTLTextureType getMTLTextureType() { return _mtlTextureType; }
 
 	/**
 	 * Populates the texture of the specified render pass descriptor
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 18a74e2..b0e4e03 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -1448,12 +1448,12 @@
         sliceRange = NSMakeRange(0, 1);
     }
     id<MTLTexture> mtlTex = _imageView->_image->getMTLTexture(_planeIndex);
-    if (_device->_pMetalFeatures->nativeTextureSwizzle && _packedSwizzle) {
+    if (_device->_pMetalFeatures->nativeTextureSwizzle && _useSwizzle) {
         return [mtlTex newTextureViewWithPixelFormat: _mtlPixFmt
                                          textureType: mtlTextureType
                                               levels: NSMakeRange(_imageView->_subresourceRange.baseMipLevel, _imageView->_subresourceRange.levelCount)
                                               slices: sliceRange
-                                             swizzle: mvkMTLTextureSwizzleChannelsFromVkComponentMapping(mvkUnpackSwizzle(_packedSwizzle))];    // retained
+                                             swizzle: mvkMTLTextureSwizzleChannelsFromVkComponentMapping(_componentSwizzle)];    // retained
     } else {
         return [mtlTex newTextureViewWithPixelFormat: _mtlPixFmt
                                          textureType: mtlTextureType
@@ -1475,7 +1475,6 @@
     _mtlTexture = nil;
 
 	getVulkanAPIObject()->setConfigurationResult(initSwizzledMTLPixelFormat(pCreateInfo));
-    _packedSwizzle = _useSwizzle ? mvkPackSwizzle(pCreateInfo->components) : 0;
 
     // Determine whether this image view should use a Metal texture view,
     // and set the _useMTLTextureView variable appropriately.
@@ -1488,7 +1487,7 @@
              ((_imageView->_mtlTextureType == MTLTextureType2D || _imageView->_mtlTextureType == MTLTextureType2DArray) && is3D)) &&
             _imageView->_subresourceRange.levelCount == _imageView->_image->_mipLevels &&
             (is3D || _imageView->_subresourceRange.layerCount == _imageView->_image->_arrayLayers) &&
-            (!_device->_pMetalFeatures->nativeTextureSwizzle || !_packedSwizzle)) {
+            (!_device->_pMetalFeatures->nativeTextureSwizzle || !_useSwizzle)) {
             _useMTLTextureView = false;
         }
     } else {
@@ -1499,24 +1498,39 @@
 VkResult MVKImageViewPlane::initSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo) {
 
 	_useSwizzle = false;
-	VkComponentMapping components = pCreateInfo->components;
+	_componentSwizzle = pCreateInfo->components;
 
-#define SWIZZLE_MATCHES(R, G, B, A)    mvkVkComponentMappingsMatch(components, {VK_COMPONENT_SWIZZLE_ ##R, VK_COMPONENT_SWIZZLE_ ##G, VK_COMPONENT_SWIZZLE_ ##B, VK_COMPONENT_SWIZZLE_ ##A} )
+	VkImageAspectFlags aspectMask = pCreateInfo->subresourceRange.aspectMask;
+	bool supportsSwizzling = _device->_pMetalFeatures->nativeTextureSwizzle || mvkConfig().fullImageViewSwizzle;
+
+#define SWIZZLE_MATCHES(R, G, B, A)    mvkVkComponentMappingsMatch(_componentSwizzle, {VK_COMPONENT_SWIZZLE_ ##R, VK_COMPONENT_SWIZZLE_ ##G, VK_COMPONENT_SWIZZLE_ ##B, VK_COMPONENT_SWIZZLE_ ##A} )
 #define VK_COMPONENT_SWIZZLE_ANY       VK_COMPONENT_SWIZZLE_MAX_ENUM
 
 	// If we have an identity swizzle, we're all good.
 	if (SWIZZLE_MATCHES(R, G, B, A)) {
-		// Change to stencil-only format if only stencil aspect is requested
-		if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
-			mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
-			if (_mtlPixFmt == MTLPixelFormatDepth32Float_Stencil8) {
-				_mtlPixFmt = MTLPixelFormatX32_Stencil8;
-			}
+
+		// Identity swizzles of depth/stencil formats can require special handling.
+		if (mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
+
+			// If only stencil aspect is requested, possibly change to stencil-only format.
+			if (aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
+				if (_mtlPixFmt == MTLPixelFormatDepth32Float_Stencil8) {
+					_mtlPixFmt = MTLPixelFormatX32_Stencil8;
+				}
 #if MVK_MACOS
-			else if (_mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8) {
-				_mtlPixFmt = MTLPixelFormatX24_Stencil8;
-			}
+				else if (_mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8) {
+					_mtlPixFmt = MTLPixelFormatX24_Stencil8;
+				}
 #endif
+			}
+
+			// When reading or sampling into a vec4 color, Vulkan expects the depth or stencil value in only the red component.
+			// Metal can be inconsistent, but on most platforms populates all components with the depth or stencil value.
+			// If swizzling is available, we can compensate for this by forcing the appropriate swizzle.
+			if (supportsSwizzling && mvkIsAnyFlagEnabled(aspectMask, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
+					_componentSwizzle = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE };
+					_useSwizzle = true;
+			}
 		}
 
 		return VK_SUCCESS;
@@ -1625,7 +1639,7 @@
 
 		case MTLPixelFormatDepth32Float_Stencil8:
 			// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
-			if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
+			if (aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
 				mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
 				_mtlPixFmt = MTLPixelFormatX32_Stencil8;
 				if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
@@ -1637,7 +1651,7 @@
 #if MVK_MACOS
 		case MTLPixelFormatDepth24Unorm_Stencil8:
 			// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
-			if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
+			if (aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
 				mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
 				_mtlPixFmt = MTLPixelFormatX24_Stencil8;
 				if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
@@ -1652,14 +1666,14 @@
 	}
 
 	// No format transformation swizzles were found, so we'll need to use either native or shader swizzling, if it is supported.
-	if ( !(_device->_pMetalFeatures->nativeTextureSwizzle || mvkConfig().fullImageViewSwizzle) ) {
+	if ( !supportsSwizzling ) {
 		return getVulkanAPIObject()->reportError(VK_ERROR_FEATURE_NOT_PRESENT,
 												 "The value of %s::components) (%s, %s, %s, %s), when applied to a VkImageView, requires full component swizzling to be enabled both at the"
 												 " time when the VkImageView is created and at the time any pipeline that uses that VkImageView is compiled. Full component swizzling can"
 												 " be enabled via the MVKConfiguration::fullImageViewSwizzle config parameter or MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE environment variable.",
 												 pCreateInfo->image ? "vkCreateImageView(VkImageViewCreateInfo" : "vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDeviceImageViewSupportEXTX",
-												 mvkVkComponentSwizzleName(components.r), mvkVkComponentSwizzleName(components.g),
-												 mvkVkComponentSwizzleName(components.b), mvkVkComponentSwizzleName(components.a));
+												 mvkVkComponentSwizzleName(_componentSwizzle.r), mvkVkComponentSwizzleName(_componentSwizzle.g),
+												 mvkVkComponentSwizzleName(_componentSwizzle.b), mvkVkComponentSwizzleName(_componentSwizzle.a));
 	}
 
 	_useSwizzle = true;