Merge pull request #1397 from billhollings/depth-stencil-swizzle-fixes
Fix swizzle of depth and stencil values into RGBA (float4) variable in shaders.
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 ff719db..cffcd46 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -531,20 +531,26 @@
void releaseMTLTexture();
+ /** Returns the packed component swizzle of this image view. */
+ uint32_t getPackedSwizzle() { return _useSwizzle ? mvkPackSwizzle(_componentSwizzle) : 0; }
+
~MVKImageViewPlane();
protected:
void propagateDebugName();
id<MTLTexture> newMTLTexture();
+ id<MTLTexture> getUnswizzledMTLTexture();
+ VkResult initSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo);
MVKImageViewPlane(MVKImageView* imageView, uint8_t planeIndex, MTLPixelFormat mtlPixFmt, const VkImageViewCreateInfo* pCreateInfo);
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;
};
@@ -568,16 +574,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
@@ -591,30 +597,6 @@
*/
void populateMTLRenderPassAttachmentDescriptorResolve(MTLRenderPassAttachmentDescriptor* mtlAttDesc);
- /**
- * Returns, in mtlPixFmt, a MTLPixelFormat, based on the MTLPixelFormat converted from
- * the VkFormat, but possibly modified by the swizzles defined in the VkComponentMapping
- * of the VkImageViewCreateInfo.
- *
- * Metal prior to version 3.0 does not support native per-texture swizzles, so if the swizzle
- * is not an identity swizzle, this function attempts to find an alternate MTLPixelFormat that
- * coincidentally matches the swizzled format.
- *
- * If a replacement MTLFormat was found, it is returned and useSwizzle is set to false.
- * If a replacement MTLFormat could not be found, the original MTLPixelFormat is returned,
- * and the useSwizzle is set to true, indicating that either native or shader swizzling
- * should be used for this image view.
- *
- * This is a static function that can be used to validate image view formats prior to creating one.
- */
- static VkResult validateSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo,
- VkImageUsageFlags usage,
- MVKVulkanAPIObject* apiObject,
- bool hasNativeSwizzleSupport,
- bool hasShaderSwizzleSupport,
- MTLPixelFormat& mtlPixFmt,
- bool& useSwizzle);
-
#pragma mark Construction
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 2dedcec..2a67b65 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
@@ -1462,6 +1462,13 @@
}
}
+// If a swizzle is being applied, returns the unswizzled parent texture.
+// This is relevant for depth/stencil attachments that are also sampled and might have forced swizzles.
+id<MTLTexture> MVKImageViewPlane::getUnswizzledMTLTexture() {
+ id<MTLTexture> mtlTex = getMTLTexture();
+ return _useSwizzle && mtlTex.parentTexture ? mtlTex.parentTexture : mtlTex;
+}
+
#pragma mark Construction
@@ -1474,15 +1481,7 @@
_mtlPixFmt = mtlPixFmt;
_mtlTexture = nil;
- bool useSwizzle;
- _imageView->setConfigurationResult(_imageView->validateSwizzledMTLPixelFormat(pCreateInfo,
- _imageView->_usage,
- _imageView,
- _device->_pMetalFeatures->nativeTextureSwizzle,
- mvkConfig().fullImageViewSwizzle,
- _mtlPixFmt,
- useSwizzle));
- _packedSwizzle = (useSwizzle) ? mvkPackSwizzle(pCreateInfo->components) : 0;
+ getVulkanAPIObject()->setConfigurationResult(initSwizzledMTLPixelFormat(pCreateInfo));
// Determine whether this image view should use a Metal texture view,
// and set the _useMTLTextureView variable appropriately.
@@ -1495,7 +1494,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)) {
+ !_useSwizzle) {
_useMTLTextureView = false;
}
} else {
@@ -1503,6 +1502,192 @@
}
}
+VkResult MVKImageViewPlane::initSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo) {
+
+ _useSwizzle = false;
+ _componentSwizzle = pCreateInfo->components;
+
+ 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)) {
+
+ // 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;
+ }
+#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;
+ }
+
+ if (mvkIsAnyFlagEnabled(_imageView->_usage, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) {
+ // Vulkan forbids using image views with non-identity swizzles as storage images or attachments.
+ // Let's catch some cases which are essentially identity, but would still result in Metal restricting
+ // the resulting texture's usage.
+
+ switch (_mtlPixFmt) {
+ case MTLPixelFormatR8Unorm:
+#if MVK_APPLE_SILICON
+ case MTLPixelFormatR8Unorm_sRGB:
+#endif
+ case MTLPixelFormatR8Snorm:
+ case MTLPixelFormatR8Uint:
+ case MTLPixelFormatR8Sint:
+ case MTLPixelFormatR16Unorm:
+ case MTLPixelFormatR16Snorm:
+ case MTLPixelFormatR16Uint:
+ case MTLPixelFormatR16Sint:
+ case MTLPixelFormatR16Float:
+ case MTLPixelFormatR32Uint:
+ case MTLPixelFormatR32Sint:
+ case MTLPixelFormatR32Float:
+ if (SWIZZLE_MATCHES(R, ZERO, ZERO, ONE)) {
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatRG8Unorm:
+#if MVK_APPLE_SILICON
+ case MTLPixelFormatRG8Unorm_sRGB:
+#endif
+ case MTLPixelFormatRG8Snorm:
+ case MTLPixelFormatRG8Uint:
+ case MTLPixelFormatRG8Sint:
+ case MTLPixelFormatRG16Unorm:
+ case MTLPixelFormatRG16Snorm:
+ case MTLPixelFormatRG16Uint:
+ case MTLPixelFormatRG16Sint:
+ case MTLPixelFormatRG16Float:
+ case MTLPixelFormatRG32Uint:
+ case MTLPixelFormatRG32Sint:
+ case MTLPixelFormatRG32Float:
+ if (SWIZZLE_MATCHES(R, G, ZERO, ONE)) {
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatRG11B10Float:
+ case MTLPixelFormatRGB9E5Float:
+ if (SWIZZLE_MATCHES(R, G, B, ONE)) {
+ return VK_SUCCESS;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (_mtlPixFmt) {
+ case MTLPixelFormatR8Unorm:
+ if (SWIZZLE_MATCHES(ZERO, ANY, ANY, R)) {
+ _mtlPixFmt = MTLPixelFormatA8Unorm;
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatA8Unorm:
+ if (SWIZZLE_MATCHES(A, ANY, ANY, ZERO)) {
+ _mtlPixFmt = MTLPixelFormatR8Unorm;
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatRGBA8Unorm:
+ if (SWIZZLE_MATCHES(B, G, R, A)) {
+ _mtlPixFmt = MTLPixelFormatBGRA8Unorm;
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatRGBA8Unorm_sRGB:
+ if (SWIZZLE_MATCHES(B, G, R, A)) {
+ _mtlPixFmt = MTLPixelFormatBGRA8Unorm_sRGB;
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatBGRA8Unorm:
+ if (SWIZZLE_MATCHES(B, G, R, A)) {
+ _mtlPixFmt = MTLPixelFormatRGBA8Unorm;
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatBGRA8Unorm_sRGB:
+ if (SWIZZLE_MATCHES(B, G, R, A)) {
+ _mtlPixFmt = MTLPixelFormatRGBA8Unorm_sRGB;
+ return VK_SUCCESS;
+ }
+ break;
+
+ case MTLPixelFormatDepth32Float_Stencil8:
+ // If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
+ 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)) {
+ return VK_SUCCESS;
+ }
+ }
+ break;
+
+#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 (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)) {
+ return VK_SUCCESS;
+ }
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ // No format transformation swizzles were found, so we'll need to use either native or shader swizzling, if it is supported.
+ 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(_componentSwizzle.r), mvkVkComponentSwizzleName(_componentSwizzle.g),
+ mvkVkComponentSwizzleName(_componentSwizzle.b), mvkVkComponentSwizzleName(_componentSwizzle.a));
+ }
+
+ _useSwizzle = true;
+
+ return VK_SUCCESS;
+}
+
MVKImageViewPlane::~MVKImageViewPlane() {
[_mtlTexture release];
}
@@ -1519,7 +1704,7 @@
void MVKImageView::populateMTLRenderPassAttachmentDescriptor(MTLRenderPassAttachmentDescriptor* mtlAttDesc) {
MVKImageViewPlane* plane = _planes[0];
- mtlAttDesc.texture = plane->getMTLTexture(); // Use image view, necessary if image view format differs from image format
+ mtlAttDesc.texture = plane->getUnswizzledMTLTexture();
mtlAttDesc.level = plane->_useMTLTextureView ? 0 : _subresourceRange.baseMipLevel;
if (mtlAttDesc.texture.textureType == MTLTextureType3D) {
mtlAttDesc.slice = 0;
@@ -1532,7 +1717,7 @@
void MVKImageView::populateMTLRenderPassAttachmentDescriptorResolve(MTLRenderPassAttachmentDescriptor* mtlAttDesc) {
MVKImageViewPlane* plane = _planes[0];
- mtlAttDesc.resolveTexture = plane->getMTLTexture(); // Use image view, necessary if image view format differs from image format
+ mtlAttDesc.resolveTexture = plane->getUnswizzledMTLTexture();
mtlAttDesc.resolveLevel = plane->_useMTLTextureView ? 0 : _subresourceRange.baseMipLevel;
if (mtlAttDesc.resolveTexture.textureType == MTLTextureType3D) {
mtlAttDesc.resolveSlice = 0;
@@ -1635,180 +1820,6 @@
}
}
-VkResult MVKImageView::validateSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo,
- VkImageUsageFlags usage,
- MVKVulkanAPIObject* apiObject,
- bool hasNativeSwizzleSupport,
- bool hasShaderSwizzleSupport,
- MTLPixelFormat& mtlPixFmt,
- bool& useSwizzle) {
- useSwizzle = false;
- VkComponentMapping components = 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} )
- #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(usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
- if (mtlPixFmt == MTLPixelFormatDepth32Float_Stencil8)
- mtlPixFmt = MTLPixelFormatX32_Stencil8;
-#if MVK_MACOS
- else if (mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8)
- mtlPixFmt = MTLPixelFormatX24_Stencil8;
-#endif
- }
-
- return VK_SUCCESS;
- }
-
- if (mvkIsAnyFlagEnabled(usage, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) {
- // Vulkan forbids using image views with non-identity swizzles as storage images or attachments.
- // Let's catch some cases which are essentially identity, but would still result in Metal restricting
- // the resulting texture's usage.
-
- switch (mtlPixFmt) {
- case MTLPixelFormatR8Unorm:
-#if MVK_APPLE_SILICON
- case MTLPixelFormatR8Unorm_sRGB:
-#endif
- case MTLPixelFormatR8Snorm:
- case MTLPixelFormatR8Uint:
- case MTLPixelFormatR8Sint:
- case MTLPixelFormatR16Unorm:
- case MTLPixelFormatR16Snorm:
- case MTLPixelFormatR16Uint:
- case MTLPixelFormatR16Sint:
- case MTLPixelFormatR16Float:
- case MTLPixelFormatR32Uint:
- case MTLPixelFormatR32Sint:
- case MTLPixelFormatR32Float:
- if (SWIZZLE_MATCHES(R, ZERO, ZERO, ONE)) {
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatRG8Unorm:
-#if MVK_APPLE_SILICON
- case MTLPixelFormatRG8Unorm_sRGB:
-#endif
- case MTLPixelFormatRG8Snorm:
- case MTLPixelFormatRG8Uint:
- case MTLPixelFormatRG8Sint:
- case MTLPixelFormatRG16Unorm:
- case MTLPixelFormatRG16Snorm:
- case MTLPixelFormatRG16Uint:
- case MTLPixelFormatRG16Sint:
- case MTLPixelFormatRG16Float:
- case MTLPixelFormatRG32Uint:
- case MTLPixelFormatRG32Sint:
- case MTLPixelFormatRG32Float:
- if (SWIZZLE_MATCHES(R, G, ZERO, ONE)) {
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatRG11B10Float:
- case MTLPixelFormatRGB9E5Float:
- if (SWIZZLE_MATCHES(R, G, B, ONE)) {
- return VK_SUCCESS;
- }
- break;
-
- default:
- break;
- }
- }
-
- switch (mtlPixFmt) {
- case MTLPixelFormatR8Unorm:
- if (SWIZZLE_MATCHES(ZERO, ANY, ANY, R)) {
- mtlPixFmt = MTLPixelFormatA8Unorm;
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatA8Unorm:
- if (SWIZZLE_MATCHES(A, ANY, ANY, ZERO)) {
- mtlPixFmt = MTLPixelFormatR8Unorm;
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatRGBA8Unorm:
- if (SWIZZLE_MATCHES(B, G, R, A)) {
- mtlPixFmt = MTLPixelFormatBGRA8Unorm;
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatRGBA8Unorm_sRGB:
- if (SWIZZLE_MATCHES(B, G, R, A)) {
- mtlPixFmt = MTLPixelFormatBGRA8Unorm_sRGB;
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatBGRA8Unorm:
- if (SWIZZLE_MATCHES(B, G, R, A)) {
- mtlPixFmt = MTLPixelFormatRGBA8Unorm;
- return VK_SUCCESS;
- }
- break;
-
- case MTLPixelFormatBGRA8Unorm_sRGB:
- if (SWIZZLE_MATCHES(B, G, R, A)) {
- mtlPixFmt = MTLPixelFormatRGBA8Unorm_sRGB;
- return VK_SUCCESS;
- }
- break;
-
- 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 &&
- mvkIsAnyFlagEnabled(usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
- mtlPixFmt = MTLPixelFormatX32_Stencil8;
- if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
- return VK_SUCCESS;
- }
- }
- break;
-
-#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 &&
- mvkIsAnyFlagEnabled(usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
- mtlPixFmt = MTLPixelFormatX24_Stencil8;
- if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
- return VK_SUCCESS;
- }
- }
- break;
-#endif
-
- default:
- break;
- }
-
- // No format transformation swizzles were found, so we'll need to use either native or shader swizzling.
- useSwizzle = true;
- if (hasNativeSwizzleSupport || hasShaderSwizzleSupport ) {
- return VK_SUCCESS;
- }
-
- // Oh, oh. Neither native or shader swizzling is supported.
- return apiObject->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));
-}
-
MVKImageView::~MVKImageView() {
mvkDestroyContainerContents(_planes);
}