Skip to content

Commit

Permalink
Don't enable PixelFormatView just in case we need it to copy
Browse files Browse the repository at this point in the history
Not worth the performance hit to everything else
  • Loading branch information
etang-cw committed Dec 5, 2023
1 parent 8820c53 commit c84ebdd
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 25 deletions.
18 changes: 12 additions & 6 deletions MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,17 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

MTLPixelFormat srcMTLPixFmt = _srcImage->getMTLPixelFormat(srcPlaneIndex);
bool isSrcCompressed = _srcImage->getIsCompressed();
bool canReinterpretSrc = _srcImage->hasPixelFormatView();

MTLPixelFormat dstMTLPixFmt = _dstImage->getMTLPixelFormat(dstPlaneIndex);
bool isDstCompressed = _dstImage->getIsCompressed();
bool canReinterpretDst = _dstImage->hasPixelFormatView();

bool isEitherCompressed = isSrcCompressed || isDstCompressed;
bool canReinterpret = canReinterpretSrc || canReinterpretDst;

// 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 useTempBuffer = (srcMTLPixFmt != dstMTLPixFmt) && (isEitherCompressed || !canReinterpret);

if (useTempBuffer) {
// Add copy from source image to temp buffer.
Expand Down Expand Up @@ -177,12 +182,13 @@ static inline MTLSize mvkClampMTLSize(MTLSize size, MTLOrigin origin, MTLSize ma

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);
Expand Down
6 changes: 5 additions & 1 deletion MoltenVK/MoltenVK/GPUObjects/MVKImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,10 @@ class MVKImage : public MVKVulkanAPIDeviceObject {
* 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() const { return mvkIsAnyFlagEnabled(_mtlUsage, MTLTextureUsagePixelFormatView); }

/** Returns the Metal resource options for this image. */
MTLStorageMode getMTLStorageMode();

Expand Down Expand Up @@ -354,6 +357,7 @@ class MVKImage : public MVKVulkanAPIDeviceObject {
VkImageUsageFlags _stencilUsage;
VkFormat _vkFormat;
MTLTextureType _mtlTextureType;
MTLTextureUsage _mtlUsage;
std::mutex _lock;
IOSurfaceRef _ioSurface;
VkDeviceSize _rowByteAlignment;
Expand Down
11 changes: 10 additions & 1 deletion MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
mtlTexDesc.mipmapLevelCount = _image->_mipLevels;
mtlTexDesc.sampleCount = mvkSampleCountFromVkSampleCountFlagBits(_image->_samples);
mtlTexDesc.arrayLength = _image->_arrayLayers;
mtlTexDesc.usageMVK = _image->getMTLTextureUsage(mtlPixFmt);
mtlTexDesc.usageMVK = _image->_mtlUsage;
mtlTexDesc.storageModeMVK = _image->getMTLStorageMode();
mtlTexDesc.cpuCacheMode = _image->getMTLCPUCacheMode();

Expand Down Expand Up @@ -982,6 +982,8 @@
}
}
_hasExpectedTexelSize = _hasChromaSubsampling || (pixFmts->getBytesPerBlock(_planes[0]->_mtlPixFmt) == pixFmts->getBytesPerBlock(_vkFormat));
MTLPixelFormat actualFmt = MVK_MACOS && _is3DCompressed ? MTLPixelFormatBGRA8Unorm : pixFmts->getMTLPixelFormat(pCreateInfo->format);
_mtlUsage = getMTLTextureUsage(actualFmt);

if (pExtMemInfo) { initExternalMemory(pExtMemInfo->handleTypes); }

Expand Down Expand Up @@ -1763,6 +1765,13 @@ static void signalAndUnmarkAsTracked(const MVKSwapchainSignaler& signaler) {
}
}

if (!_imageView->_image->hasPixelFormatView()) {
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)) {
Expand Down
34 changes: 17 additions & 17 deletions MoltenVK/MoltenVK/GPUObjects/MVKPixelFormats.mm
Original file line number Diff line number Diff line change
Expand Up @@ -737,23 +737,23 @@
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) {

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) {

bool pfv = false;

// 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);
}

Expand Down

0 comments on commit c84ebdd

Please sign in to comment.