MVKImage: Handle VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT.
Only set `MTLTextureUsagePixelFormatView` if this bit is set. This
should reduce the usage of this bit, which disables lossless compression
on Apple GPUs, in many cases.
We continue to set it anyway for `VK_IMAGE_USAGE_TRANSFER_SRC_BIT`; this
is because we create those texture views on the application's behalf, to
implement `vkCopyImage()` where the source and destination formats do
not agree. We also continue to set it for depth/stencil formats; Metal
requires it in order to use only the stencil aspect in a view.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index b88450f..5882132 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -367,6 +367,7 @@
bool _is3DCompressed;
bool _isAliasable;
bool _hasExtendedUsage;
+ bool _hasMutableFormat;
};
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 210c1ff..40a9414 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -123,7 +123,7 @@
mtlTexDesc.mipmapLevelCount = _image->_mipLevels;
mtlTexDesc.sampleCount = mvkSampleCountFromVkSampleCountFlagBits(_image->_samples);
mtlTexDesc.arrayLength = _image->_arrayLayers;
- mtlTexDesc.usageMVK = _image->getPixelFormats()->getMTLTextureUsage(_image->_usage, mtlPixFmt, minUsage, _image->_isLinear, _image->_hasExtendedUsage);
+ mtlTexDesc.usageMVK = _image->getPixelFormats()->getMTLTextureUsage(_image->_usage, mtlPixFmt, minUsage, _image->_isLinear, _image->_hasMutableFormat, _image->_hasExtendedUsage);
mtlTexDesc.storageModeMVK = _image->getMTLStorageMode();
mtlTexDesc.cpuCacheMode = _image->getMTLCPUCacheMode();
@@ -804,6 +804,7 @@
MVKPixelFormats* pixFmts = getPixelFormats();
_vkFormat = pCreateInfo->format;
_usage = pCreateInfo->usage;
+ _hasMutableFormat = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
_hasExtendedUsage = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT);
_is3DCompressed = (getImageType() == VK_IMAGE_TYPE_3D) && (pixFmts->getFormatType(pCreateInfo->format) == kMVKFormatCompressed) && !_device->_pMetalFeatures->native3DCompressedTextures;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
index e87063e..5b73547 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.h
@@ -350,6 +350,7 @@
MTLPixelFormat mtlFormat,
MTLTextureUsage minUsage = MTLTextureUsageUnknown,
bool isLinear = false,
+ bool isMutableFormat = true,
bool isExtended = false);
/** Enumerates all formats that support the given features, calling a specified function for each one. */
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
index d27b4b2..a265dcd 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
@@ -465,6 +465,7 @@
MTLPixelFormat mtlFormat,
MTLTextureUsage minUsage,
bool isLinear,
+ bool isMutableFormat,
bool isExtended) {
bool isDepthFmt = isDepthFormat(mtlFormat);
bool isStencilFmt = isStencilFormat(mtlFormat);
@@ -514,13 +515,22 @@
}
// Create view on, but only on color formats, or combined depth-stencil formats if supported by the GPU...
- if (mvkIsAnyFlagEnabled(vkImageUsageFlags, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // May use temp view if transfer involves format change
- VK_IMAGE_USAGE_SAMPLED_BIT |
+ if ((mvkIsAnyFlagEnabled(vkImageUsageFlags, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) || // May use temp view if transfer involves format change
+ (isMutableFormat &&
+ mvkIsAnyFlagEnabled(vkImageUsageFlags, (VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_STORAGE_BIT |
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)))) &&
+ isColorFormat) {
+
+ mvkEnableFlags(mtlUsage, MTLTextureUsagePixelFormatView);
+ }
+ if (mvkIsAnyFlagEnabled(vkImageUsageFlags, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // May use temp view if transfer involves format change
+ VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
- (isColorFormat || (isCombinedDepthStencilFmt && supportsStencilViews))) {
+ isCombinedDepthStencilFmt && supportsStencilViews) {
mvkEnableFlags(mtlUsage, MTLTextureUsagePixelFormatView);
}