Merge pull request #2088 from etang-cw/PixelFormatView

Don't enable PixelFormatView just in case we need it to copy
This commit is contained in:
Bill Hollings 2023-12-12 12:55:38 -05:00 committed by GitHub
commit 2cccfd516e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 23 deletions

View File

@ -133,12 +133,17 @@ void MVKCmdCopyImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com
MTLPixelFormat srcMTLPixFmt = _srcImage->getMTLPixelFormat(srcPlaneIndex);
bool isSrcCompressed = _srcImage->getIsCompressed();
bool canReinterpretSrc = _srcImage->hasPixelFormatView(srcPlaneIndex);
MTLPixelFormat dstMTLPixFmt = _dstImage->getMTLPixelFormat(dstPlaneIndex);
bool isDstCompressed = _dstImage->getIsCompressed();
bool canReinterpretDst = _dstImage->hasPixelFormatView(dstPlaneIndex);
// If source and destination have different formats and at least one is compressed, use a temporary intermediary buffer
bool useTempBuffer = (srcMTLPixFmt != dstMTLPixFmt) && (isSrcCompressed || isDstCompressed);
bool isEitherCompressed = isSrcCompressed || isDstCompressed;
bool canReinterpret = canReinterpretSrc || canReinterpretDst;
// If source and destination can't be reinterpreted to matching formats use a temporary intermediary buffer
bool useTempBuffer = (srcMTLPixFmt != dstMTLPixFmt) && (isEitherCompressed || !canReinterpret);
if (useTempBuffer) {
// Add copy from source image to temp buffer.
@ -177,12 +182,13 @@ void MVKCmdCopyImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com
size_t bytesPerRow = pixFmts->getBytesPerRow(srcMTLPixFmt, vkIC.extent.width);
size_t bytesPerRegion = pixFmts->getBytesPerLayer(srcMTLPixFmt, bytesPerRow, vkIC.extent.height);
tmpBuffSize += bytesPerRegion;
tmpBuffSize += bytesPerRegion * vkIC.extent.depth;
} else {
// Map the source pixel format to the dest pixel format through a texture view on the source texture.
// If the source and dest pixel formats are the same, this will simply degenerate to the source texture itself.
id<MTLTexture> srcMTLTex = _srcImage->getMTLTexture(srcPlaneIndex, _dstImage->getMTLPixelFormat(dstPlaneIndex));
id<MTLTexture> dstMTLTex = _dstImage->getMTLTexture(dstPlaneIndex);
// Map the source pixel format to the dest pixel format through a texture view on the reinterpretable texture.
// If the source and dest pixel formats are the same, this will simply degenerate to the texture itself.
MTLPixelFormat fmt = (canReinterpretSrc ? _dstImage : _srcImage)->getMTLPixelFormat(canReinterpretSrc ? dstPlaneIndex : srcPlaneIndex);
id<MTLTexture> srcMTLTex = _srcImage->getMTLTexture(srcPlaneIndex, fmt);
id<MTLTexture> dstMTLTex = _dstImage->getMTLTexture(dstPlaneIndex, fmt);
if ( !srcMTLTex || !dstMTLTex ) { return; }
id<MTLBlitCommandEncoder> mtlBlitEnc = cmdEncoder->getMTLBlitEncoder(commandUse);

View File

@ -310,7 +310,10 @@ public:
* attempting to copy a depth image with a substituted format to and from a buffer.
*/
inline bool hasExpectedTexelSize() { return _hasExpectedTexelSize; }
/** Returns whether the texture has the PixelFormatView usage flag, allowing it to be reinterpreted. */
inline bool hasPixelFormatView(uint32_t planeIndex) { return mvkIsAnyFlagEnabled(getMTLTexture(planeIndex).usage, MTLTextureUsagePixelFormatView); }
/** Returns the Metal resource options for this image. */
MTLStorageMode getMTLStorageMode();

View File

@ -1777,6 +1777,13 @@ VkResult MVKImageViewPlane::initSwizzledMTLPixelFormat(const VkImageViewCreateIn
}
}
if (!_imageView->_image->hasPixelFormatView(_planeIndex)) {
if (!enableSwizzling()) {
MVKAssert(0, "Image without PixelFormatView usage couldn't enable swizzling!");
}
return VK_SUCCESS;
}
switch (_mtlPixFmt) {
case MTLPixelFormatR8Unorm:
if (SWIZZLE_MATCHES(ZERO, ANY, ANY, R)) {

View File

@ -737,23 +737,23 @@ MTLTextureUsage MVKPixelFormats::getMTLTextureUsage(VkImageUsageFlags vkImageUsa
mvkEnableFlags(mtlUsage, samples == VK_SAMPLE_COUNT_1_BIT ? MTLTextureUsageShaderWrite : MTLTextureUsageShaderRead);
}
// 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
(needsReinterpretation &&
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) {
bool pfv = false;
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)) &&
isCombinedDepthStencilFmt && supportsStencilViews) {
// Swizzle emulation may need to reinterpret
needsReinterpretation |= !_physicalDevice->getMetalFeatures()->nativeTextureSwizzle;
pfv |= isColorFormat && needsReinterpretation &&
mvkIsAnyFlagEnabled(vkImageUsageFlags, (VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
pfv |= isCombinedDepthStencilFmt && supportsStencilViews &&
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));
if (pfv) {
mvkEnableFlags(mtlUsage, MTLTextureUsagePixelFormatView);
}