From d0e00ad3be4be3c52630f9f3c013bea1679927f1 Mon Sep 17 00:00:00 2001 From: Evan Tang Date: Thu, 14 Sep 2023 11:46:07 -0500 Subject: [PATCH] Don't enable PixelFormatView just in case we need it to copy Not worth the performance hit to everything else --- MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm | 20 ++++++++----- MoltenVK/MoltenVK/GPUObjects/MVKImage.h | 5 +++- MoltenVK/MoltenVK/GPUObjects/MVKImage.mm | 7 +++++ .../MoltenVK/GPUObjects/MVKPixelFormats.mm | 30 +++++++++---------- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm index 52dcb78f..06d67822 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm @@ -133,12 +133,17 @@ void MVKCmdCopyImage::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::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 srcMTLTex = _srcImage->getMTLTexture(srcPlaneIndex, _dstImage->getMTLPixelFormat(dstPlaneIndex)); - id 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 srcMTLTex = _srcImage->getMTLTexture(srcPlaneIndex, fmt); + id dstMTLTex = _dstImage->getMTLTexture(dstPlaneIndex, fmt); if ( !srcMTLTex || !dstMTLTex ) { return; } id mtlBlitEnc = cmdEncoder->getMTLBlitEncoder(commandUse); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index 900b10ff..7103bddd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -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(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index f73c64a8..d7ff2933 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -1763,6 +1763,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)) { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm index fa76befa..0427e52c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm @@ -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); }