/*
 * MVKImage.mm
 *
 * Copyright (c) 2015-2020 The Brenwill Workshop Ltd. (http://www.brenwill.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "MVKImage.h"
#include "MVKQueue.h"
#include "MVKSwapchain.h"
#include "MVKCommandBuffer.h"
#include "MVKCmdDebug.h"
#include "MVKEnvironment.h"
#include "MVKFoundation.h"
#include "MVKOSExtensions.h"
#include "MVKLogging.h"
#include "MVKCodec.h"
#import "MTLTextureDescriptor+MoltenVK.h"
#import "MTLSamplerDescriptor+MoltenVK.h"

using namespace std;
using namespace SPIRV_CROSS_NAMESPACE;

#pragma mark -
#pragma mark MVKImagePlane

MVKVulkanAPIObject* MVKImagePlane::getVulkanAPIObject() { return _image; }

id<MTLTexture> MVKImagePlane::getMTLTexture() {
    if ( !_mtlTexture && _image->_vkFormat ) {
        // Lock and check again in case another thread has created the texture.
        lock_guard<mutex> lock(_image->_lock);
        if (_mtlTexture) { return _mtlTexture; }

        MTLTextureDescriptor* mtlTexDesc = newMTLTextureDescriptor();    // temp retain
        MVKImageMemoryBinding* memoryBinding = getMemoryBinding();

        if (_image->_ioSurface) {
            _mtlTexture = [_image->getMTLDevice()
                           newTextureWithDescriptor: mtlTexDesc
                           iosurface: _image->_ioSurface
                           plane: _planeIndex];
        } else if (memoryBinding->_usesTexelBuffer) {
            _mtlTexture = [memoryBinding->_deviceMemory->getMTLBuffer()
                           newTextureWithDescriptor: mtlTexDesc
                           offset: memoryBinding->getDeviceMemoryOffset()
                           bytesPerRow: _subresources[0].layout.rowPitch];
        } else if (memoryBinding->_deviceMemory->getMTLHeap() && !_image->getIsDepthStencil()) {
            // Metal support for depth/stencil from heaps is flaky
            _mtlTexture = [memoryBinding->_deviceMemory->getMTLHeap()
                           newTextureWithDescriptor: mtlTexDesc
                           offset: memoryBinding->getDeviceMemoryOffset()];
            if (_image->_isAliasable) { [_mtlTexture makeAliasable]; }
        } else {
            _mtlTexture = [_image->getMTLDevice() newTextureWithDescriptor: mtlTexDesc];
        }

        [mtlTexDesc release];                                            // temp release

        propagateDebugName();
    }
    return _mtlTexture;
}

id<MTLTexture> MVKImagePlane::getMTLTexture(MTLPixelFormat mtlPixFmt) {
    // Note: Retrieve the base texture outside of lock to avoid deadlock if it too needs to be lazily created.
    // Delegate to _image in case the method is overriden. (e.g. if it's a swapchain image)
    if (mtlPixFmt == _mtlPixFmt) { return _image->getMTLTexture(_planeIndex); }
    id<MTLTexture> mtlTex = _mtlTextureViews[mtlPixFmt];
    if ( !mtlTex ) {
        // Lock and check again in case another thread has created the view texture.
        id<MTLTexture> baseTexture = _image->getMTLTexture(_planeIndex);
        lock_guard<mutex> lock(_image->_lock);
        mtlTex = _mtlTextureViews[mtlPixFmt];
        if ( !mtlTex ) {
            mtlTex = [baseTexture newTextureViewWithPixelFormat: mtlPixFmt];    // retained
            _mtlTextureViews[mtlPixFmt] = mtlTex;
        }
    }
    return mtlTex;
}

void MVKImagePlane::releaseMTLTexture() {
    [_mtlTexture release];
    for (auto elem : _mtlTextureViews) {
        [elem.second release];
    }
    _mtlTextureViews.clear();
}

// Returns a Metal texture descriptor constructed from the properties of this image.
// It is the caller's responsibility to release the returned descriptor object.
MTLTextureDescriptor* MVKImagePlane::newMTLTextureDescriptor() {
    MTLPixelFormat mtlPixFmt = _mtlPixFmt;
    MTLTextureUsage minUsage = MTLTextureUsageUnknown;
#if MVK_MACOS
    if (_image->_is3DCompressed) {
        // Metal before 3.0 doesn't support 3D compressed textures, so we'll decompress
        // the texture ourselves. This, then, is the *uncompressed* format.
        mtlPixFmt = MTLPixelFormatBGRA8Unorm;
        minUsage = MTLTextureUsageShaderWrite;
    }
#endif

    VkExtent3D extent = _image->getExtent3D(_planeIndex, 0);
    MTLTextureDescriptor* mtlTexDesc = [MTLTextureDescriptor new];    // retained
    mtlTexDesc.pixelFormat = mtlPixFmt;
    mtlTexDesc.textureType = _image->_mtlTextureType;
    mtlTexDesc.width = extent.width;
    mtlTexDesc.height = extent.height;
    mtlTexDesc.depth = extent.depth;
    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.storageModeMVK = _image->getMTLStorageMode();
    mtlTexDesc.cpuCacheMode = _image->getMTLCPUCacheMode();

    return mtlTexDesc;
}

// Initializes the subresource definitions.
void MVKImagePlane::initSubresources(const VkImageCreateInfo* pCreateInfo) {
    _subresources.reserve(_image->_mipLevels * _image->_arrayLayers);

    MVKImageSubresource subRez;
    subRez.subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT << _planeIndex;
    subRez.layoutState = pCreateInfo->initialLayout;

    VkDeviceSize offset = 0;
    if (_planeIndex > 0 && _image->_memoryBindings.size() == 1) {
        auto subresources = &_image->_planes[_planeIndex-1]->_subresources;
        VkSubresourceLayout& lastLayout = (*subresources)[subresources->size()-1].layout;
        offset = lastLayout.offset+lastLayout.size;
    }

    for (uint32_t mipLvl = 0; mipLvl < _image->_mipLevels; mipLvl++) {
        subRez.subresource.mipLevel = mipLvl;
        VkDeviceSize rowPitch = _image->getBytesPerRow(_planeIndex, mipLvl);
        VkDeviceSize depthPitch = _image->getBytesPerLayer(_planeIndex, mipLvl);

        VkExtent3D mipExtent = _image->getExtent3D(_planeIndex, mipLvl);
        
        for (uint32_t layer = 0; layer < _image->_arrayLayers; layer++) {
            subRez.subresource.arrayLayer = layer;

            VkSubresourceLayout& layout = subRez.layout;
            layout.offset = offset;
            layout.size = depthPitch * mipExtent.depth;
            
            layout.rowPitch = rowPitch;
            layout.depthPitch = depthPitch;

            _subresources.push_back(subRez);
            offset += layout.size;
        }
    }
}

// Returns a pointer to the internal subresource for the specified MIP level layer.
MVKImageSubresource* MVKImagePlane::getSubresource(uint32_t mipLevel, uint32_t arrayLayer) {
    uint32_t srIdx = (mipLevel * _image->_arrayLayers) + arrayLayer;
    return (srIdx < _subresources.size()) ? &_subresources[srIdx] : NULL;
}

// Updates the contents of the underlying MTLTexture, corresponding to the
// specified subresource definition, from the underlying memory buffer.
void MVKImagePlane::updateMTLTextureContent(MVKImageSubresource& subresource,
                                            VkDeviceSize offset, VkDeviceSize size) {

    VkImageSubresource& imgSubRez = subresource.subresource;
    VkSubresourceLayout& imgLayout = subresource.layout;
    size = getMemoryBinding()->getDeviceMemory()->adjustMemorySize(size, offset);
    // Check if subresource overlaps the memory range.
	if ( !overlaps(imgLayout, offset, size) ) { return; }

    // Don't update if host memory has not been mapped yet.
    void* pHostMem = getMemoryBinding()->getHostMemoryAddress();
    if ( !pHostMem ) { return; }

    VkExtent3D mipExtent = _image->getExtent3D(_planeIndex, imgSubRez.mipLevel);
    void* pImgBytes = (void*)((uintptr_t)pHostMem + imgLayout.offset);

    MTLRegion mtlRegion;
    mtlRegion.origin = MTLOriginMake(0, 0, 0);
    mtlRegion.size = mvkMTLSizeFromVkExtent3D(mipExtent);

#if MVK_MACOS
    std::unique_ptr<char[]> decompBuffer;
    if (_image->_is3DCompressed) {
        // We cannot upload the texture data directly in this case. But we
        // can upload the decompressed image data.
        std::unique_ptr<MVKCodec> codec = mvkCreateCodec(_image->getVkFormat());
        if (!codec) {
            _image->reportError(VK_ERROR_FORMAT_NOT_SUPPORTED, "A 3D texture used a compressed format that MoltenVK does not yet support.");
            return;
        }
        VkSubresourceLayout destLayout;
        destLayout.rowPitch = 4 * mipExtent.width;
        destLayout.depthPitch = destLayout.rowPitch * mipExtent.height;
        destLayout.size = destLayout.depthPitch * mipExtent.depth;
        decompBuffer = std::unique_ptr<char[]>(new char[destLayout.size]);
        codec->decompress(decompBuffer.get(), pImgBytes, destLayout, imgLayout, mipExtent);
        pImgBytes = decompBuffer.get();
        imgLayout = destLayout;
    }
#endif

    VkImageType imgType = _image->getImageType();
    VkDeviceSize bytesPerRow = (imgType != VK_IMAGE_TYPE_1D) ? imgLayout.rowPitch : 0;
    VkDeviceSize bytesPerImage = (imgType == VK_IMAGE_TYPE_3D) ? imgLayout.depthPitch : 0;

    id<MTLTexture> mtlTex = getMTLTexture();
    if (_image->getPixelFormats()->isPVRTCFormat(mtlTex.pixelFormat)) {
        bytesPerRow = 0;
        bytesPerImage = 0;
    }

    [mtlTex replaceRegion: mtlRegion
              mipmapLevel: imgSubRez.mipLevel
                    slice: imgSubRez.arrayLayer
                withBytes: pImgBytes
              bytesPerRow: bytesPerRow
            bytesPerImage: bytesPerImage];
}

// Updates the contents of the underlying memory buffer from the contents of
// the underlying MTLTexture, corresponding to the specified subresource definition.
void MVKImagePlane::getMTLTextureContent(MVKImageSubresource& subresource,
                                         VkDeviceSize offset, VkDeviceSize size) {

    VkImageSubresource& imgSubRez = subresource.subresource;
    VkSubresourceLayout& imgLayout = subresource.layout;

    // Check if subresource overlaps the memory range.
    if ( !overlaps(imgLayout, offset, size) ) { return; }

    // Don't update if host memory has not been mapped yet.
    void* pHostMem = getMemoryBinding()->getHostMemoryAddress();
    if ( !pHostMem ) { return; }

    VkExtent3D mipExtent = _image->getExtent3D(_planeIndex, imgSubRez.mipLevel);
    void* pImgBytes = (void*)((uintptr_t)pHostMem + imgLayout.offset);

    MTLRegion mtlRegion;
    mtlRegion.origin = MTLOriginMake(0, 0, 0);
    mtlRegion.size = mvkMTLSizeFromVkExtent3D(mipExtent);

    VkImageType imgType = _image->getImageType();
    VkDeviceSize bytesPerRow = (imgType != VK_IMAGE_TYPE_1D) ? imgLayout.rowPitch : 0;
    VkDeviceSize bytesPerImage = (imgType == VK_IMAGE_TYPE_3D) ? imgLayout.depthPitch : 0;

    [_mtlTexture getBytes: pImgBytes
              bytesPerRow: bytesPerRow
            bytesPerImage: bytesPerImage
               fromRegion: mtlRegion
              mipmapLevel: imgSubRez.mipLevel
                    slice: imgSubRez.arrayLayer];
}

// Returns whether subresource layout overlaps the memory range.
bool MVKImagePlane::overlaps(VkSubresourceLayout& imgLayout, VkDeviceSize offset, VkDeviceSize size) {
	VkDeviceSize memStart = offset;
	VkDeviceSize memEnd = offset + size;
	VkDeviceSize imgStart = getMemoryBinding()->_deviceMemoryOffset + imgLayout.offset;
	VkDeviceSize imgEnd = imgStart + imgLayout.size;
	return imgStart < memEnd && imgEnd > memStart;
}

void MVKImagePlane::propagateDebugName() {
    setLabelIfNotNil(_image->_planes[_planeIndex]->_mtlTexture, _image->_debugName);
}

MVKImageMemoryBinding* MVKImagePlane::getMemoryBinding() const {
    return (_image->_memoryBindings.size() > 1) ? _image->_memoryBindings[_planeIndex] : _image->_memoryBindings[0];
}

void MVKImagePlane::applyImageMemoryBarrier(VkPipelineStageFlags srcStageMask,
											VkPipelineStageFlags dstStageMask,
											MVKPipelineBarrier& barrier,
											MVKCommandEncoder* cmdEncoder,
											MVKCommandUse cmdUse) {

	// Extract the mipmap levels that are to be updated
	uint32_t mipLvlStart = barrier.baseMipLevel;
	uint32_t mipLvlEnd = (barrier.levelCount == (uint8_t)VK_REMAINING_MIP_LEVELS
						  ? _image->getMipLevelCount()
						  : (mipLvlStart + barrier.levelCount));

	// Extract the cube or array layers (slices) that are to be updated
	uint32_t layerStart = barrier.baseArrayLayer;
	uint32_t layerEnd = (barrier.layerCount == (uint16_t)VK_REMAINING_ARRAY_LAYERS
						 ? _image->getLayerCount()
						 : (layerStart + barrier.layerCount));

	MVKImageMemoryBinding* memBind = getMemoryBinding();
	bool needsSync = memBind->needsHostReadSync(srcStageMask, dstStageMask, barrier);
	bool needsPull = (!memBind->_usesTexelBuffer &&
					  memBind->isMemoryHostCoherent() &&
					  barrier.newLayout == VK_IMAGE_LAYOUT_GENERAL &&
					  mvkIsAnyFlagEnabled(barrier.dstAccessMask, (VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_READ_BIT)));
	MVKDeviceMemory* dvcMem = memBind->getDeviceMemory();
	const MVKMappedMemoryRange& mappedRange = dvcMem ? dvcMem->getMappedRange() : MVKMappedMemoryRange();

	// Iterate across mipmap levels and layers, and update the image layout state for each
	for (uint32_t mipLvl = mipLvlStart; mipLvl < mipLvlEnd; mipLvl++) {
		for (uint32_t layer = layerStart; layer < layerEnd; layer++) {
			MVKImageSubresource* pImgRez = getSubresource(mipLvl, layer);
			if (pImgRez) { pImgRez->layoutState = barrier.newLayout; }
			if (needsSync) {
#if MVK_MACOS
				[cmdEncoder->getMTLBlitEncoder(cmdUse) synchronizeTexture: _mtlTexture slice: layer level: mipLvl];
#endif
			}
			// Check if image content should be pulled into host-mapped device memory after
			// the GPU is done with it. This only applies if the image is intended to be
			// host-coherent, is not using a texel buffer, is transitioning to host-readable,
			// AND the device memory has an already-open memory mapping. If a memory mapping is
			// created later, it will pull the image contents in at that time, so it is not needed now.
			// The mapped range will be {0,0} if device memory is not currently mapped.
			if (needsPull && pImgRez && overlaps(pImgRez->layout, mappedRange.offset, mappedRange.size)) {
				pullFromDeviceOnCompletion(cmdEncoder, *pImgRez, mappedRange);
			}
		}
	}
}

// Once the command buffer completes, pull the content of the subresource into host memory.
// This is only necessary when the image memory is intended to be host-coherent, and the
// device memory is currently mapped to host memory
void MVKImagePlane::pullFromDeviceOnCompletion(MVKCommandEncoder* cmdEncoder,
											   MVKImageSubresource& subresource,
											   const MVKMappedMemoryRange& mappedRange) {

	[cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id<MTLCommandBuffer> mcb) {
		getMTLTextureContent(subresource, mappedRange.offset, mappedRange.size);
	}];
}

MVKImagePlane::MVKImagePlane(MVKImage* image, uint8_t planeIndex) {
    _image = image;
    _planeIndex = planeIndex;
    _mtlTexture = nil;
}

MVKImagePlane::~MVKImagePlane() {
    releaseMTLTexture();
}


#pragma mark -
#pragma mark MVKImageMemoryBinding

VkResult MVKImageMemoryBinding::getMemoryRequirements(VkMemoryRequirements* pMemoryRequirements) {
    pMemoryRequirements->size = _byteCount;
    pMemoryRequirements->alignment = _byteAlignment;
    return VK_SUCCESS;
}

VkResult MVKImageMemoryBinding::getMemoryRequirements(const void*, VkMemoryRequirements2* pMemoryRequirements) {
    pMemoryRequirements->sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
    for (auto* next = (VkBaseOutStructure*)pMemoryRequirements->pNext; next; next = next->pNext) {
        switch (next->sType) {
        case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
            auto* dedicatedReqs = (VkMemoryDedicatedRequirements*)next;
            bool writable = mvkIsAnyFlagEnabled(_image->_usage, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
            dedicatedReqs->requiresDedicatedAllocation = _requiresDedicatedMemoryAllocation;
            dedicatedReqs->prefersDedicatedAllocation = (dedicatedReqs->requiresDedicatedAllocation ||
                                                        (!_usesTexelBuffer && (writable || !_device->_pMetalFeatures->placementHeaps)));
            break;
        }
        default:
            break;
        }
    }
    return VK_SUCCESS;
}

// Memory may have been mapped before image was bound, and needs to be loaded into the MTLTexture.
VkResult MVKImageMemoryBinding::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) {
    if (_deviceMemory) { _deviceMemory->removeImageMemoryBinding(this); }
    MVKResource::bindDeviceMemory(mvkMem, memOffset);

    _usesTexelBuffer = _device->_pMetalFeatures->texelBuffers && _deviceMemory && _deviceMemory->_mtlBuffer; // Texel buffers available
    _usesTexelBuffer = _usesTexelBuffer && (isMemoryHostAccessible() || _device->_pMetalFeatures->placementHeaps) && _image->_isLinear && !_image->getIsCompressed(); // Applicable memory layout

    // macOS before 10.15.5 cannot use shared memory for texel buffers.
    _usesTexelBuffer = _usesTexelBuffer && (_device->_pMetalFeatures->sharedLinearTextures || !isMemoryHostCoherent());

    flushToDevice(getDeviceMemoryOffset(), getByteCount());
    return _deviceMemory ? _deviceMemory->addImageMemoryBinding(this) : VK_SUCCESS;
}

void MVKImageMemoryBinding::applyMemoryBarrier(VkPipelineStageFlags srcStageMask,
                                               VkPipelineStageFlags dstStageMask,
                                               MVKPipelineBarrier& barrier,
                                               MVKCommandEncoder* cmdEncoder,
                                               MVKCommandUse cmdUse) {
#if MVK_MACOS
    if ( needsHostReadSync(srcStageMask, dstStageMask, barrier) ) {
        for(uint8_t planeIndex = beginPlaneIndex(); planeIndex < endPlaneIndex(); planeIndex++) {
            [cmdEncoder->getMTLBlitEncoder(cmdUse) synchronizeResource: _image->_planes[planeIndex]->_mtlTexture];
        }
    }
#endif
}

void MVKImageMemoryBinding::propagateDebugName() {
    for(uint8_t planeIndex = beginPlaneIndex(); planeIndex < endPlaneIndex(); planeIndex++) {
        _image->_planes[planeIndex]->propagateDebugName();
    }
}

// Returns whether the specified image memory barrier requires a sync between this
// texture and host memory for the purpose of the host reading texture memory.
bool MVKImageMemoryBinding::needsHostReadSync(VkPipelineStageFlags srcStageMask,
                                              VkPipelineStageFlags dstStageMask,
                                              MVKPipelineBarrier& barrier) {
#if MVK_MACOS
    return ((barrier.newLayout == VK_IMAGE_LAYOUT_GENERAL) &&
            mvkIsAnyFlagEnabled(barrier.dstAccessMask, (VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_READ_BIT)) &&
            isMemoryHostAccessible() && (!_device->_pMetalFeatures->sharedLinearTextures || !isMemoryHostCoherent()));
#endif
#if MVK_IOS_OR_TVOS
    return false;
#endif
}

bool MVKImageMemoryBinding::shouldFlushHostMemory() { return isMemoryHostAccessible() && !_usesTexelBuffer; }

// Flushes the device memory at the specified memory range into the MTLTexture. Updates
// all subresources that overlap the specified range and are in an updatable layout state.
VkResult MVKImageMemoryBinding::flushToDevice(VkDeviceSize offset, VkDeviceSize size) {
    if (shouldFlushHostMemory()) {
        for(uint8_t planeIndex = beginPlaneIndex(); planeIndex < endPlaneIndex(); planeIndex++) {
            for (auto& subRez : _image->_planes[planeIndex]->_subresources) {
                switch (subRez.layoutState) {
                    case VK_IMAGE_LAYOUT_UNDEFINED:
                    case VK_IMAGE_LAYOUT_PREINITIALIZED:
                    case VK_IMAGE_LAYOUT_GENERAL: {
                        _image->_planes[planeIndex]->updateMTLTextureContent(subRez, offset, size);
                        break;
                    }
                    default:
                        break;
                }
            }
        }
    }
    return VK_SUCCESS;
}

// Pulls content from the MTLTexture into the device memory at the specified memory range.
// Pulls from all subresources that overlap the specified range and are in an updatable layout state.
VkResult MVKImageMemoryBinding::pullFromDevice(VkDeviceSize offset, VkDeviceSize size) {
    if (shouldFlushHostMemory()) {
        for(uint8_t planeIndex = beginPlaneIndex(); planeIndex < endPlaneIndex(); planeIndex++) {
            for (auto& subRez : _image->_planes[planeIndex]->_subresources) {
                switch (subRez.layoutState) {
                    case VK_IMAGE_LAYOUT_GENERAL: {
                        _image->_planes[planeIndex]->getMTLTextureContent(subRez, offset, size);
                        break;
                    }
                    default:
                        break;
                }
            }
        }
    }
    return VK_SUCCESS;
}

uint8_t MVKImageMemoryBinding::beginPlaneIndex() const {
    return (_image->_memoryBindings.size() > 1) ? _planeIndex : 0;
}

uint8_t MVKImageMemoryBinding::endPlaneIndex() const {
    return (_image->_memoryBindings.size() > 1) ? _planeIndex : (uint8_t)_image->_memoryBindings.size();
}

MVKImageMemoryBinding::MVKImageMemoryBinding(MVKDevice* device, MVKImage* image, uint8_t planeIndex) : MVKResource(device) {
    _image = image;
    _planeIndex = planeIndex;
    _usesTexelBuffer = false;
}

MVKImageMemoryBinding::~MVKImageMemoryBinding() {
    if (_deviceMemory) { _deviceMemory->removeImageMemoryBinding(this); }
}


#pragma mark MVKImage

uint8_t MVKImage::getPlaneFromVkImageAspectFlags(VkImageAspectFlags aspectMask) {
    return (aspectMask & VK_IMAGE_ASPECT_PLANE_2_BIT) ? 2 :
           (aspectMask & VK_IMAGE_ASPECT_PLANE_1_BIT) ? 1 :
           0;
}

void MVKImage::propagateDebugName() {
    for (uint8_t planeIndex = 0; planeIndex < _planes.size(); planeIndex++) {
        _planes[planeIndex]->propagateDebugName();
    }
}

void MVKImage::flushToDevice(VkDeviceSize offset, VkDeviceSize size) {
    for (int bindingIndex = 0; bindingIndex < _memoryBindings.size(); bindingIndex++) {
        MVKImageMemoryBinding *binding = _memoryBindings[bindingIndex];
        binding->flushToDevice(offset, size);
    }
}

VkImageType MVKImage::getImageType() { return mvkVkImageTypeFromMTLTextureType(_mtlTextureType); }

bool MVKImage::getIsDepthStencil() { return getPixelFormats()->getFormatType(_vkFormat) == kMVKFormatDepthStencil; }

bool MVKImage::getIsCompressed() { return getPixelFormats()->getFormatType(_vkFormat) == kMVKFormatCompressed; }

VkExtent3D MVKImage::getExtent3D(uint8_t planeIndex, uint32_t mipLevel) {
    VkExtent3D extent = _extent;
    if (_hasChromaSubsampling) {
        extent.width /= _planes[planeIndex]->_blockTexelSize.width;
        extent.height /= _planes[planeIndex]->_blockTexelSize.height;
    }
	return mvkMipmapLevelSizeFromBaseSize3D(extent, mipLevel);
}

VkDeviceSize MVKImage::getBytesPerRow(uint8_t planeIndex, uint32_t mipLevel) {
    size_t bytesPerRow = getPixelFormats()->getBytesPerRow(_vkFormat, getExtent3D(planeIndex, mipLevel).width);
    return mvkAlignByteCount(bytesPerRow, _rowByteAlignment);
}

VkDeviceSize MVKImage::getBytesPerLayer(uint8_t planeIndex, uint32_t mipLevel) {
    VkExtent3D extent = getExtent3D(planeIndex, mipLevel);
    size_t bytesPerRow = getBytesPerRow(planeIndex, mipLevel);
    return getPixelFormats()->getBytesPerLayer(_vkFormat, bytesPerRow, extent.height);
}

VkResult MVKImage::getSubresourceLayout(const VkImageSubresource* pSubresource,
										VkSubresourceLayout* pLayout) {
    uint8_t planeIndex = MVKImage::getPlaneFromVkImageAspectFlags(pSubresource->aspectMask);
    MVKImageSubresource* pImgRez = _planes[planeIndex]->getSubresource(pSubresource->mipLevel, pSubresource->arrayLayer);
    if ( !pImgRez ) { return VK_INCOMPLETE; }

    *pLayout = pImgRez->layout;
    return VK_SUCCESS;
}

void MVKImage::getTransferDescriptorData(MVKImageDescriptorData& imgData) {
    imgData.imageType = getImageType();
    imgData.format = getVkFormat();
    imgData.extent = _extent;
    imgData.mipLevels = _mipLevels;
    imgData.arrayLayers = _arrayLayers;
    imgData.samples = _samples;
    imgData.usage = _usage;
}


#pragma mark Resource memory

void MVKImage::applyImageMemoryBarrier(VkPipelineStageFlags srcStageMask,
									   VkPipelineStageFlags dstStageMask,
									   MVKPipelineBarrier& barrier,
									   MVKCommandEncoder* cmdEncoder,
									   MVKCommandUse cmdUse) {

	for (uint8_t planeIndex = 0; planeIndex < _planes.size(); planeIndex++) {
		if ( !_hasChromaSubsampling || mvkIsAnyFlagEnabled(barrier.aspectMask, (VK_IMAGE_ASPECT_PLANE_0_BIT << planeIndex)) ) {
			_planes[planeIndex]->applyImageMemoryBarrier(srcStageMask, dstStageMask, barrier, cmdEncoder, cmdUse);
		}
    }
}

VkResult MVKImage::getMemoryRequirements(VkMemoryRequirements* pMemoryRequirements, uint8_t planeIndex) {
    pMemoryRequirements->memoryTypeBits = (_isDepthStencilAttachment)
                                          ? _device->getPhysicalDevice()->getPrivateMemoryTypes()
                                          : _device->getPhysicalDevice()->getAllMemoryTypes();
#if MVK_MACOS
    // Metal on macOS does not provide native support for host-coherent memory, but Vulkan requires it for Linear images
    if ( !_isLinear ) {
        mvkDisableFlags(pMemoryRequirements->memoryTypeBits, _device->getPhysicalDevice()->getHostCoherentMemoryTypes());
    }
#endif
#if MVK_IOS_OR_TVOS
    // Only transient attachments may use memoryless storage
    if (!mvkAreAllFlagsEnabled(_usage, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) ) {
        mvkDisableFlags(pMemoryRequirements->memoryTypeBits, _device->getPhysicalDevice()->getLazilyAllocatedMemoryTypes());
    }
#endif
    return _memoryBindings[planeIndex]->getMemoryRequirements(pMemoryRequirements);
}

VkResult MVKImage::getMemoryRequirements(const void* pInfo, VkMemoryRequirements2* pMemoryRequirements) {
    uint8_t planeIndex = 0;
	const auto* pImageInfo = (const VkImageMemoryRequirementsInfo2*)pInfo;
	for (const auto* next = (const VkBaseInStructure*)pImageInfo->pNext; next; next = next->pNext) {
		switch (next->sType) {
		case VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO: {
			const auto* planeReqs = (const VkImagePlaneMemoryRequirementsInfo*)next;
            planeIndex = MVKImage::getPlaneFromVkImageAspectFlags(planeReqs->planeAspect);
			break;
		}
		default:
			break;
		}
	}
    VkResult rslt = getMemoryRequirements(&pMemoryRequirements->memoryRequirements, planeIndex);
    if (rslt != VK_SUCCESS) { return rslt; }
    return _memoryBindings[planeIndex]->getMemoryRequirements(pInfo, pMemoryRequirements);
}

VkResult MVKImage::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset, uint8_t planeIndex) {
    return _memoryBindings[planeIndex]->bindDeviceMemory(mvkMem, memOffset);
}

VkResult MVKImage::bindDeviceMemory2(const VkBindImageMemoryInfo* pBindInfo) {
    uint8_t planeIndex = 0;
    for (const auto* next = (const VkBaseInStructure*)pBindInfo->pNext; next; next = next->pNext) {
        switch (next->sType) {
            case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO: {
                const VkBindImagePlaneMemoryInfo* imagePlaneMemoryInfo = (const VkBindImagePlaneMemoryInfo*)next;
                planeIndex = MVKImage::getPlaneFromVkImageAspectFlags(imagePlaneMemoryInfo->planeAspect);
                break;
            }
            default:
                break;
        }
    }
    return bindDeviceMemory((MVKDeviceMemory*)pBindInfo->memory, pBindInfo->memoryOffset, planeIndex);
}


#pragma mark Metal

id<MTLTexture> MVKImage::getMTLTexture(uint8_t planeIndex) {
	return _planes[planeIndex]->getMTLTexture();
}

id<MTLTexture> MVKImage::getMTLTexture(uint8_t planeIndex, MTLPixelFormat mtlPixFmt) {
    return _planes[planeIndex]->getMTLTexture(mtlPixFmt);
}

VkResult MVKImage::setMTLTexture(uint8_t planeIndex, id<MTLTexture> mtlTexture) {
	lock_guard<mutex> lock(_lock);

	releaseIOSurface();
    _planes[planeIndex]->releaseMTLTexture();
	_planes[planeIndex]->_mtlTexture = [mtlTexture retain];		// retained

    _vkFormat = getPixelFormats()->getVkFormat(mtlTexture.pixelFormat);
	_mtlTextureType = mtlTexture.textureType;
	_extent.width = uint32_t(mtlTexture.width);
	_extent.height = uint32_t(mtlTexture.height);
	_extent.depth = uint32_t(mtlTexture.depth);
	_mipLevels = uint32_t(mtlTexture.mipmapLevelCount);
	_samples = mvkVkSampleCountFlagBitsFromSampleCount(mtlTexture.sampleCount);
	_arrayLayers = uint32_t(mtlTexture.arrayLength);
	_usage = getPixelFormats()->getVkImageUsageFlags(mtlTexture.usage, mtlTexture.pixelFormat);

	if (_device->_pMetalFeatures->ioSurfaces) {
		_ioSurface = mtlTexture.iosurface;
		CFRetain(_ioSurface);
	}

	return VK_SUCCESS;
}

void MVKImage::releaseIOSurface() {
    if (_ioSurface) {
        CFRelease(_ioSurface);
        _ioSurface = nil;
    }
}

IOSurfaceRef MVKImage::getIOSurface() { return _ioSurface; }

VkResult MVKImage::useIOSurface(IOSurfaceRef ioSurface) {
	lock_guard<mutex> lock(_lock);

    if (!_device->_pMetalFeatures->ioSurfaces) { return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkUseIOSurfaceMVK() : IOSurfaces are not supported on this platform."); }

#if MVK_SUPPORT_IOSURFACE_BOOL

    for (uint8_t planeIndex = 0; planeIndex < _planes.size(); planeIndex++) {
        _planes[planeIndex]->releaseMTLTexture();
    }
    releaseIOSurface();

    MVKPixelFormats* pixFmts = getPixelFormats();

	if (ioSurface) {
		if (IOSurfaceGetWidth(ioSurface) != _extent.width) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface width %zu does not match VkImage width %d.", IOSurfaceGetWidth(ioSurface), _extent.width); }
		if (IOSurfaceGetHeight(ioSurface) != _extent.height) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface height %zu does not match VkImage height %d.", IOSurfaceGetHeight(ioSurface), _extent.height); }
		if (IOSurfaceGetBytesPerElement(ioSurface) != pixFmts->getBytesPerBlock(_vkFormat)) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface bytes per element %zu does not match VkImage bytes per element %d.", IOSurfaceGetBytesPerElement(ioSurface), pixFmts->getBytesPerBlock(_vkFormat)); }
		if (IOSurfaceGetElementWidth(ioSurface) != pixFmts->getBlockTexelSize(_vkFormat).width) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface element width %zu does not match VkImage element width %d.", IOSurfaceGetElementWidth(ioSurface), pixFmts->getBlockTexelSize(_vkFormat).width); }
		if (IOSurfaceGetElementHeight(ioSurface) != pixFmts->getBlockTexelSize(_vkFormat).height) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface element height %zu does not match VkImage element height %d.", IOSurfaceGetElementHeight(ioSurface), pixFmts->getBlockTexelSize(_vkFormat).height); }
        if (IOSurfaceGetPlaneCount(ioSurface) != _planes.size()) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface plane count %zu does not match VkImage plane count %lu.", IOSurfaceGetPlaneCount(ioSurface), _planes.size()); }
        if (_hasChromaSubsampling) {
            for (uint8_t planeIndex = 0; planeIndex < _planes.size(); ++planeIndex) {
                if (IOSurfaceGetWidthOfPlane(ioSurface, planeIndex) != getExtent3D(planeIndex, 0).width) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface width %zu of plane %d does not match VkImage width %d.", IOSurfaceGetWidthOfPlane(ioSurface, planeIndex), planeIndex, getExtent3D(planeIndex, 0).width); }
                if (IOSurfaceGetHeightOfPlane(ioSurface, planeIndex) != getExtent3D(planeIndex, 0).height) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface height %zu of plane %d does not match VkImage height %d.", IOSurfaceGetHeightOfPlane(ioSurface, planeIndex), planeIndex, getExtent3D(planeIndex, 0).height); }
                if (IOSurfaceGetBytesPerElementOfPlane(ioSurface, planeIndex) != _planes[planeIndex]->_bytesPerBlock) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface bytes per element %zu of plane %d does not match VkImage bytes per element %d.", IOSurfaceGetBytesPerElementOfPlane(ioSurface, planeIndex), planeIndex, _planes[planeIndex]->_bytesPerBlock); }
                if (IOSurfaceGetElementWidthOfPlane(ioSurface, planeIndex) != _planes[planeIndex]->_blockTexelSize.width) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface element width %zu of plane %d does not match VkImage element width %d.", IOSurfaceGetElementWidthOfPlane(ioSurface, planeIndex), planeIndex, _planes[planeIndex]->_blockTexelSize.width); }
                if (IOSurfaceGetElementHeightOfPlane(ioSurface, planeIndex) != _planes[planeIndex]->_blockTexelSize.height) { return reportError(VK_ERROR_INITIALIZATION_FAILED, "vkUseIOSurfaceMVK() : IOSurface element height %zu of plane %d does not match VkImage element height %d.", IOSurfaceGetElementHeightOfPlane(ioSurface, planeIndex), planeIndex, _planes[planeIndex]->_blockTexelSize.height); }
            }
        }

        _ioSurface = ioSurface;
        CFRetain(_ioSurface);
    } else {
        @autoreleasepool {
            CFMutableDictionaryRef properties = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)@{
			    (id)kIOSurfaceWidth: @(_extent.width),
			    (id)kIOSurfaceHeight: @(_extent.height),
			    (id)kIOSurfaceBytesPerElement: @(pixFmts->getBytesPerBlock(_vkFormat)),
			    (id)kIOSurfaceElementWidth: @(pixFmts->getBlockTexelSize(_vkFormat).width),
			    (id)kIOSurfaceElementHeight: @(pixFmts->getBlockTexelSize(_vkFormat).height),
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
			    (id)kIOSurfaceIsGlobal: @(true), // Deprecated but needed for interprocess transfers
#pragma clang diagnostic pop
            });
            if(_hasChromaSubsampling) {
                CFMutableArrayRef planeProperties = CFArrayCreateMutable(NULL, _planes.size(), NULL);
                for (uint8_t planeIndex = 0; planeIndex < _planes.size(); ++planeIndex) {
                    CFArrayAppendValue(planeProperties, (CFDictionaryRef)@{
                        (id)kIOSurfacePlaneWidth: @(getExtent3D(planeIndex, 0).width),
                        (id)kIOSurfacePlaneHeight: @(getExtent3D(planeIndex, 0).height),
                        (id)kIOSurfacePlaneBytesPerElement: @(_planes[planeIndex]->_bytesPerBlock),
                        (id)kIOSurfacePlaneElementWidth: @(_planes[planeIndex]->_blockTexelSize.width),
                        (id)kIOSurfacePlaneElementHeight: @(_planes[planeIndex]->_blockTexelSize.height),
                    });
                }
                CFDictionaryAddValue(properties, (id)kIOSurfacePlaneInfo, planeProperties);
            }
            _ioSurface = IOSurfaceCreate(properties);
        }
    }

#endif

    return VK_SUCCESS;
}

MTLStorageMode MVKImage::getMTLStorageMode() {
    if ( !_memoryBindings[0]->_deviceMemory ) return MTLStorageModePrivate;

    MTLStorageMode stgMode = _memoryBindings[0]->_deviceMemory->getMTLStorageMode();

    if (_ioSurface && stgMode == MTLStorageModePrivate) { stgMode = MTLStorageModeShared; }

	// For macOS prior to 10.15.5, textures cannot use Shared storage mode, so change to Managed storage mode.
    if (stgMode == MTLStorageModeShared && !_device->_pMetalFeatures->sharedLinearTextures) {
        stgMode = MTLStorageModeManaged;
    }
    return stgMode;
}

MTLCPUCacheMode MVKImage::getMTLCPUCacheMode() {
	return _memoryBindings[0]->_deviceMemory ? _memoryBindings[0]->_deviceMemory->getMTLCPUCacheMode() : MTLCPUCacheModeDefaultCache;
}


#pragma mark Construction

MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
	_ioSurface = nil;

    // Adjust the info components to be compatible with Metal, then use the modified versions to set other
	// config info. Vulkan allows unused extent dimensions to be zero, but Metal requires minimum of one.
    uint32_t minDim = 1;
    _extent.width = max(pCreateInfo->extent.width, minDim);
	_extent.height = max(pCreateInfo->extent.height, minDim);
	_extent.depth = max(pCreateInfo->extent.depth, minDim);
    _arrayLayers = max(pCreateInfo->arrayLayers, minDim);

	// Perform validation and adjustments before configuring other settings
	bool isAttachment = mvkIsAnyFlagEnabled(pCreateInfo->usage, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
																 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
																 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
																 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT));
	// Texture type depends on validated samples. Other validation depends on possibly modified texture type.
	_samples = validateSamples(pCreateInfo, isAttachment);
	_mtlTextureType = mvkMTLTextureTypeFromVkImageType(pCreateInfo->imageType, _arrayLayers, _samples > VK_SAMPLE_COUNT_1_BIT);

	validateConfig(pCreateInfo, isAttachment);
	_mipLevels = validateMipLevels(pCreateInfo, isAttachment);
	_isLinear = validateLinear(pCreateInfo, isAttachment);

	MVKPixelFormats* pixFmts = getPixelFormats();
    _vkFormat = pCreateInfo->format;
	_usage = pCreateInfo->usage;
	_hasExtendedUsage = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT);

	_is3DCompressed = (getImageType() == VK_IMAGE_TYPE_3D) && (pixFmts->getFormatType(pCreateInfo->format) == kMVKFormatCompressed) && !_device->_pMetalFeatures->native3DCompressedTextures;
	_isDepthStencilAttachment = (mvkAreAllFlagsEnabled(pCreateInfo->usage, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ||
								 mvkAreAllFlagsEnabled(pixFmts->getVkFormatProperties(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT));
	_canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews;
	_rowByteAlignment = _isLinear ? _device->getVkFormatTexelBufferAlignment(pCreateInfo->format, this) : mvkEnsurePowerOfTwo(pixFmts->getBytesPerBlock(pCreateInfo->format));

    VkExtent2D blockTexelSizeOfPlane[3];
    uint32_t bytesPerBlockOfPlane[3];
    MTLPixelFormat mtlPixFmtOfPlane[3];
	uint8_t subsamplingPlaneCount = pixFmts->getChromaSubsamplingPlanes(_vkFormat, blockTexelSizeOfPlane, bytesPerBlockOfPlane, mtlPixFmtOfPlane);
	uint8_t planeCount = std::max(subsamplingPlaneCount, (uint8_t)1);
    uint8_t memoryBindingCount = (pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT) ? planeCount : 1;
    _hasChromaSubsampling = (subsamplingPlaneCount > 0);

    for (uint8_t planeIndex = 0; planeIndex < memoryBindingCount; ++planeIndex) {
        _memoryBindings.push_back(new MVKImageMemoryBinding(device, this, planeIndex));
    }

    for (uint8_t planeIndex = 0; planeIndex < planeCount; ++planeIndex) {
        _planes.push_back(new MVKImagePlane(this, planeIndex));
        if (_hasChromaSubsampling) {
            _planes[planeIndex]->_blockTexelSize = blockTexelSizeOfPlane[planeIndex];
            _planes[planeIndex]->_bytesPerBlock = bytesPerBlockOfPlane[planeIndex];
            _planes[planeIndex]->_mtlPixFmt = mtlPixFmtOfPlane[planeIndex];
        } else {
            _planes[planeIndex]->_mtlPixFmt = getPixelFormats()->getMTLPixelFormat(_vkFormat);
        }
        _planes[planeIndex]->initSubresources(pCreateInfo);
        MVKImageMemoryBinding* memoryBinding = _planes[planeIndex]->getMemoryBinding();
        if (!_isLinear && _device->_pMetalFeatures->placementHeaps) {
            MTLTextureDescriptor* mtlTexDesc = _planes[planeIndex]->newMTLTextureDescriptor();    // temp retain
            MTLSizeAndAlign sizeAndAlign = [_device->getMTLDevice() heapTextureSizeAndAlignWithDescriptor: mtlTexDesc];
            [mtlTexDesc release];
            memoryBinding->_byteCount += sizeAndAlign.size;
            memoryBinding->_byteAlignment = std::max(memoryBinding->_byteAlignment, (VkDeviceSize)sizeAndAlign.align);
            _isAliasable = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_ALIAS_BIT);
        } else {
            for (uint32_t mipLvl = 0; mipLvl < _mipLevels; mipLvl++) {
                VkExtent3D mipExtent = getExtent3D(planeIndex, mipLvl);
                memoryBinding->_byteCount += getBytesPerLayer(planeIndex, mipLvl) * mipExtent.depth * _arrayLayers;
            }
            memoryBinding->_byteAlignment = std::max(memoryBinding->_byteAlignment, _rowByteAlignment);
        }
    }
    _hasExpectedTexelSize = _hasChromaSubsampling || (pixFmts->getBytesPerBlock(_planes[0]->_mtlPixFmt) == pixFmts->getBytesPerBlock(_vkFormat));

	for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
		switch (next->sType) {
			case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO: {
				auto* pExtMemInfo = (const VkExternalMemoryImageCreateInfo*)next;
				initExternalMemory(pExtMemInfo->handleTypes);
				break;
			}
			default:
				break;
		}
	}
}

VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {

	VkSampleCountFlagBits validSamples = pCreateInfo->samples;

	if (validSamples == VK_SAMPLE_COUNT_1_BIT) { return validSamples; }

	// Don't use getImageType() because it hasn't been set yet.
	if ( !((pCreateInfo->imageType == VK_IMAGE_TYPE_2D) || ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && mvkTreatTexture1DAs2D())) ) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, multisampling can only be used with a 2D image type. Setting sample count to 1."));
		validSamples = VK_SAMPLE_COUNT_1_BIT;
	}

	if (getPixelFormats()->getFormatType(pCreateInfo->format) == kMVKFormatCompressed) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, multisampling cannot be used with compressed images. Setting sample count to 1."));
		validSamples = VK_SAMPLE_COUNT_1_BIT;
	}

	if (pCreateInfo->arrayLayers > 1) {
		if ( !_device->_pMetalFeatures->multisampleArrayTextures ) {
			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support multisampled array textures. Setting sample count to 1."));
			validSamples = VK_SAMPLE_COUNT_1_BIT;
		}
		if (isAttachment && !_device->_pMetalFeatures->multisampleLayeredRendering) {
			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to multisampled array (layered) attachments. Setting sample count to 1."));
			validSamples = VK_SAMPLE_COUNT_1_BIT;
		}
	}

	return validSamples;
}

void MVKImage::validateConfig(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
	MVKPixelFormats* pixFmts = getPixelFormats();

	bool is2D = (getImageType() == VK_IMAGE_TYPE_2D);
	bool isCompressed = pixFmts->getFormatType(pCreateInfo->format) == kMVKFormatCompressed;

#if MVK_IOS_OR_TVOS
	if (isCompressed && !is2D) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, compressed formats may only be used with 2D images."));
	}
#endif
#if MVK_MACOS
	if (isCompressed && !is2D) {
		if (getImageType() != VK_IMAGE_TYPE_3D) {
			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, compressed formats may only be used with 2D or 3D images."));
		} else if (!_device->_pMetalFeatures->native3DCompressedTextures && !mvkCanDecodeFormat(pCreateInfo->format)) {
			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, the %s compressed format may only be used with 2D images.", getPixelFormats()->getName(pCreateInfo->format)));
		}
	}
#endif

	if ((pixFmts->getFormatType(pCreateInfo->format) == kMVKFormatDepthStencil) && !is2D ) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, depth/stencil formats may only be used with 2D images."));
	}
	if (isAttachment && (pCreateInfo->arrayLayers > 1) && !_device->_pMetalFeatures->layeredRendering) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to array (layered) attachments."));
	}
	if (isAttachment && (getImageType() == VK_IMAGE_TYPE_1D)) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not support rendering to native 1D attachments. Consider enabling MVK_CONFIG_TEXTURE_1D_AS_2D."));
	}
	if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not allow uncompressed views of compressed images."));
	}
	if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT)) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not support split-instance memory binding."));
	}
}

uint32_t MVKImage::validateMipLevels(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
	uint32_t minDim = 1;
	uint32_t validMipLevels = max(pCreateInfo->mipLevels, minDim);

	if (validMipLevels == 1) { return validMipLevels; }

	if (getImageType() == VK_IMAGE_TYPE_1D) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, native 1D images cannot use mipmaps. Setting mip levels to 1. Consider enabling MVK_CONFIG_TEXTURE_1D_AS_2D."));
		validMipLevels = 1;
	}

	return validMipLevels;
}

bool MVKImage::validateLinear(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {

	if (pCreateInfo->tiling != VK_IMAGE_TILING_LINEAR ) { return false; }

	bool isLin = true;

	if (getImageType() != VK_IMAGE_TYPE_2D) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, imageType must be VK_IMAGE_TYPE_2D."));
		isLin = false;
	}

	if (getPixelFormats()->getFormatType(pCreateInfo->format) == kMVKFormatDepthStencil) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, format must not be a depth/stencil format."));
		isLin = false;
	}
	if (getPixelFormats()->getFormatType(pCreateInfo->format) == kMVKFormatCompressed) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, format must not be a compressed format."));
		isLin = false;
	}

	if (pCreateInfo->mipLevels > 1) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, mipLevels must be 1."));
		isLin = false;
	}

	if (pCreateInfo->arrayLayers > 1) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, arrayLayers must be 1."));
		isLin = false;
	}

	if (pCreateInfo->samples > VK_SAMPLE_COUNT_1_BIT) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, samples must be VK_SAMPLE_COUNT_1_BIT."));
		isLin = false;
	}

#if MVK_MACOS
	if (isAttachment) {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to linear (VK_IMAGE_TILING_LINEAR) images."));
		isLin = false;
	}
#endif

	return isLin;
}

void MVKImage::initExternalMemory(VkExternalMemoryHandleTypeFlags handleTypes) {
	if (mvkIsOnlyAnyFlagEnabled(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR)) {
        auto& xmProps = _device->getPhysicalDevice()->getExternalImageProperties(VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR);
        for(auto& memoryBinding : _memoryBindings) {
            memoryBinding->_externalMemoryHandleTypes = handleTypes;
            memoryBinding->_requiresDedicatedMemoryAllocation = memoryBinding->_requiresDedicatedMemoryAllocation || mvkIsAnyFlagEnabled(xmProps.externalMemoryFeatures, VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT);
        }
	} else {
		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage(): Only external memory handle type VK_EXTERNAL_MEMORY_HANDLE_TYPE_MTLTEXTURE_BIT_KHR is supported."));
	}
}

MVKImage::~MVKImage() {
	mvkDestroyContainerContents(_memoryBindings);
	mvkDestroyContainerContents(_planes);
    releaseIOSurface();
}


#pragma mark -
#pragma mark MVKSwapchainImage

VkResult MVKSwapchainImage::bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset, uint8_t planeIndex) {
	return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}


#pragma mark Metal

// Overridden to always retrieve the MTLTexture directly from the CAMetalDrawable.
id<MTLTexture> MVKSwapchainImage::getMTLTexture(uint8_t planeIndex) { return [getCAMetalDrawable() texture]; }


#pragma mark Construction

MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
									 const VkImageCreateInfo* pCreateInfo,
									 MVKSwapchain* swapchain,
									 uint32_t swapchainIndex) : MVKImage(device, pCreateInfo) {
	_swapchain = swapchain;
	_swapchainIndex = swapchainIndex;
}


#pragma mark -
#pragma mark MVKPresentableSwapchainImage

bool MVKSwapchainImageAvailability::operator< (const MVKSwapchainImageAvailability& rhs) const {
	if (  isAvailable && !rhs.isAvailable) { return true; }
	if ( !isAvailable &&  rhs.isAvailable) { return false; }
	return acquisitionID < rhs.acquisitionID;
}

MVKSwapchainImageAvailability MVKPresentableSwapchainImage::getAvailability() {
	lock_guard<mutex> lock(_availabilityLock);

	return _availability;
}

// Makes an image available for acquisition by the app.
// If any semaphores are waiting to be signaled when this image becomes available, the
// earliest semaphore is signaled, and this image remains unavailable for other uses.
void MVKPresentableSwapchainImage::makeAvailable() {
	lock_guard<mutex> lock(_availabilityLock);

	// Mark when this event happened, relative to that of other images
	_availability.acquisitionID = _swapchain->getNextAcquisitionID();

	// Mark this image as available if no semaphores or fences are waiting to be signaled.
	_availability.isAvailable = _availabilitySignalers.empty();

	MVKSwapchainSignaler signaler;
	if (_availability.isAvailable) {
		// If this image is available, signal the semaphore and fence that were associated
		// with the last time this image was acquired while available. This is a workaround for
		// when an app uses a single semaphore or fence for more than one swapchain image.
		// Because the semaphore or fence will be signaled by more than one image, it will
		// get out of sync, and the final use of the image would not be signaled as a result.
		signaler = _preSignaler;
	} else {
		// If this image is not yet available, extract and signal the first semaphore and fence.
		auto sigIter = _availabilitySignalers.begin();
		signaler = *sigIter;
		_availabilitySignalers.erase(sigIter);
	}

	// Signal the semaphore and fence, and let them know they are no longer being tracked.
	signal(signaler, nil);
	unmarkAsTracked(signaler);

//	MVKLogDebug("Signaling%s swapchain image %p semaphore %p from present, with %lu remaining semaphores.", (_availability.isAvailable ? " pre-signaled" : ""), this, signaler.first, _availabilitySignalers.size());
}

void MVKPresentableSwapchainImage::acquireAndSignalWhenAvailable(MVKSemaphore* semaphore, MVKFence* fence) {
	lock_guard<mutex> lock(_availabilityLock);

	// Now that this image is being acquired, release the existing drawable and its texture.
	// This is not done earlier so the texture is retained for any post-processing such as screen captures, etc.
	releaseMetalDrawable();

	auto signaler = make_pair(semaphore, fence);
	if (_availability.isAvailable) {
		_availability.isAvailable = false;

		// If signalling through a MTLEvent, use an ephemeral MTLCommandBuffer.
		// Another option would be to use MTLSharedEvent in MVKSemaphore, but that might
		// impose unacceptable performance costs to handle this particular case.
		@autoreleasepool {
			MVKSemaphore* mvkSem = signaler.first;
			id<MTLCommandBuffer> mtlCmdBuff = (mvkSem && mvkSem->isUsingCommandEncoding()
											   ? [_device->getAnyQueue()->getMTLCommandQueue() commandBufferWithUnretainedReferences]
											   : nil);
			signal(signaler, mtlCmdBuff);
			[mtlCmdBuff commit];
		}

		_preSignaler = signaler;
	} else {
		_availabilitySignalers.push_back(signaler);
	}
	markAsTracked(signaler);

//	MVKLogDebug("%s swapchain image %p semaphore %p in acquire with %lu other semaphores.", (_availability.isAvailable ? "Signaling" : "Tracking"), this, semaphore, _availabilitySignalers.size());
}

// If present, signal the semaphore for the first waiter for the given image.
void MVKPresentableSwapchainImage::signalPresentationSemaphore(id<MTLCommandBuffer> mtlCmdBuff) {
	lock_guard<mutex> lock(_availabilityLock);

	if ( !_availabilitySignalers.empty() ) {
		MVKSemaphore* mvkSem = _availabilitySignalers.front().first;
		if (mvkSem) { mvkSem->encodeSignal(mtlCmdBuff); }
	}
}

// Signal either or both of the semaphore and fence in the specified tracker pair.
void MVKPresentableSwapchainImage::signal(MVKSwapchainSignaler& signaler, id<MTLCommandBuffer> mtlCmdBuff) {
	if (signaler.first) { signaler.first->encodeSignal(mtlCmdBuff); }
	if (signaler.second) { signaler.second->signal(); }
}

// Tell the semaphore and fence that they are being tracked for future signaling.
void MVKPresentableSwapchainImage::markAsTracked(MVKSwapchainSignaler& signaler) {
	if (signaler.first) { signaler.first->retain(); }
	if (signaler.second) { signaler.second->retain(); }
}

// Tell the semaphore and fence that they are no longer being tracked for future signaling.
void MVKPresentableSwapchainImage::unmarkAsTracked(MVKSwapchainSignaler& signaler) {
	if (signaler.first) { signaler.first->release(); }
	if (signaler.second) { signaler.second->release(); }
}


#pragma mark Metal

id<CAMetalDrawable> MVKPresentableSwapchainImage::getCAMetalDrawable() {
	while ( !_mtlDrawable ) {
		@autoreleasepool {      // Reclaim auto-released drawable object before end of loop
			uint64_t startTime = _device->getPerformanceTimestamp();

			_mtlDrawable = [_swapchain->_mtlLayer.nextDrawable retain];
			if ( !_mtlDrawable ) { MVKLogError("CAMetalDrawable could not be acquired."); }

			_device->addActivityPerformance(_device->_performanceStatistics.queue.nextCAMetalDrawable, startTime);
		}
	}
	return _mtlDrawable;
}

// Present the drawable and make myself available only once the command buffer has completed.
void MVKPresentableSwapchainImage::presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff, bool hasPresentTime, uint32_t presentID, uint64_t desiredPresentTime) {
	_swapchain->willPresentSurface(getMTLTexture(0), mtlCmdBuff);

	NSString* scName = _swapchain->getDebugName();
	if (scName) { mvkPushDebugGroup(mtlCmdBuff, scName); }
	if (!hasPresentTime) {
		[mtlCmdBuff presentDrawable: getCAMetalDrawable()];
	}
	else {
		// Convert from nsecs to seconds
		CFTimeInterval presentTimeSeconds = ( double ) desiredPresentTime * 1.0e-9;
		[mtlCmdBuff presentDrawable: getCAMetalDrawable() atTime:(CFTimeInterval)presentTimeSeconds];
	}
	if (scName) { mvkPopDebugGroup(mtlCmdBuff); }

	signalPresentationSemaphore(mtlCmdBuff);

	retain();	// Ensure this image is not destroyed while awaiting MTLCommandBuffer completion
	[mtlCmdBuff addCompletedHandler: ^(id<MTLCommandBuffer> mcb) {
		makeAvailable();
		release();
	}];
	
	if (hasPresentTime) {
		if ([_mtlDrawable respondsToSelector: @selector(addPresentedHandler:)]) {
			[_mtlDrawable addPresentedHandler: ^(id<MTLDrawable> drawable) {
				// Record the presentation time
				CFTimeInterval presentedTimeSeconds = drawable.presentedTime;
				uint64_t presentedTimeNanoseconds = (uint64_t)(presentedTimeSeconds * 1.0e9);
				_swapchain->recordPresentTime(presentID, desiredPresentTime, presentedTimeNanoseconds);
			}];
		} else {
			// If MTLDrawable.presentedTime/addPresentedHandler isn't supported, just treat it as if the
			// present happened when requested
			_swapchain->recordPresentTime(presentID, desiredPresentTime, desiredPresentTime);
		}
	}
}

// Resets the MTLTexture and CAMetalDrawable underlying this image.
void MVKPresentableSwapchainImage::releaseMetalDrawable() {
    for (uint8_t planeIndex = 0; planeIndex < _planes.size(); ++planeIndex) {
        _planes[planeIndex]->releaseMTLTexture();
    }
    [_mtlDrawable release];
	_mtlDrawable = nil;
}


#pragma mark Construction

MVKPresentableSwapchainImage::MVKPresentableSwapchainImage(MVKDevice* device,
														   const VkImageCreateInfo* pCreateInfo,
														   MVKSwapchain* swapchain,
														   uint32_t swapchainIndex) :
	MVKSwapchainImage(device, pCreateInfo, swapchain, swapchainIndex) {

	_mtlDrawable = nil;

	_availability.acquisitionID = _swapchain->getNextAcquisitionID();
	_availability.isAvailable = true;
	_preSignaler = make_pair(nullptr, nullptr);
}

MVKPresentableSwapchainImage::~MVKPresentableSwapchainImage() {
	releaseMetalDrawable();
}


#pragma mark -
#pragma mark MVKPeerSwapchainImage

VkResult MVKPeerSwapchainImage::bindDeviceMemory2(const VkBindImageMemoryInfo* pBindInfo) {
	const VkBindImageMemorySwapchainInfoKHR* swapchainInfo = nullptr;
	for (const auto* next = (const VkBaseInStructure*)pBindInfo->pNext; next; next = next->pNext) {
		switch (next->sType) {
			case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
				swapchainInfo = (const VkBindImageMemorySwapchainInfoKHR*)next;
				break;
			default:
				break;
		}
	}
	if (!swapchainInfo) { return VK_ERROR_OUT_OF_DEVICE_MEMORY; }

	_swapchainIndex = swapchainInfo->imageIndex;
	return VK_SUCCESS;
}


#pragma mark Metal

id<CAMetalDrawable> MVKPeerSwapchainImage::getCAMetalDrawable() {
	return ((MVKSwapchainImage*)_swapchain->getPresentableImage(_swapchainIndex))->getCAMetalDrawable();
}


#pragma mark Construction

MVKPeerSwapchainImage::MVKPeerSwapchainImage(MVKDevice* device,
											 const VkImageCreateInfo* pCreateInfo,
											 MVKSwapchain* swapchain,
											 uint32_t swapchainIndex) :
	MVKSwapchainImage(device, pCreateInfo, swapchain, swapchainIndex) {}



#pragma mark -
#pragma mark MVKImageViewPlane

MVKVulkanAPIObject* MVKImageViewPlane::getVulkanAPIObject() { return _imageView; }

void MVKImageViewPlane::propagateDebugName() { setLabelIfNotNil(_mtlTexture, _imageView->_debugName); }


#pragma mark Metal

id<MTLTexture> MVKImageViewPlane::getMTLTexture() {
    // If we can use a Metal texture view, lazily create it, otherwise use the image texture directly.
    if (_useMTLTextureView) {
        if ( !_mtlTexture && _mtlPixFmt ) {

            // Lock and check again in case another thread created the texture view
            lock_guard<mutex> lock(_imageView->_lock);
            if (_mtlTexture) { return _mtlTexture; }

            _mtlTexture = newMTLTexture(); // retained

            propagateDebugName();
        }
        return _mtlTexture;
    } else {
        return _imageView->_image->getMTLTexture(_planeIndex);
    }
}

// Creates and returns a retained Metal texture as an
// overlay on the Metal texture of the underlying image.
id<MTLTexture> MVKImageViewPlane::newMTLTexture() {
    MTLTextureType mtlTextureType = _imageView->_mtlTextureType;
    NSRange sliceRange = NSMakeRange(_imageView->_subresourceRange.baseArrayLayer, _imageView->_subresourceRange.layerCount);
    // Fake support for 2D views of 3D textures.
    if (_imageView->_image->getImageType() == VK_IMAGE_TYPE_3D &&
        (mtlTextureType == MTLTextureType2D || mtlTextureType == MTLTextureType2DArray)) {
        mtlTextureType = MTLTextureType3D;
        sliceRange = NSMakeRange(0, 1);
    }
    id<MTLTexture> mtlTex = _imageView->_image->getMTLTexture(MVKImage::getPlaneFromVkImageAspectFlags(_imageView->_subresourceRange.aspectMask));
    if (_device->_pMetalFeatures->nativeTextureSwizzle && _packedSwizzle) {
        return [mtlTex newTextureViewWithPixelFormat: _mtlPixFmt
                                         textureType: mtlTextureType
                                              levels: NSMakeRange(_imageView->_subresourceRange.baseMipLevel, _imageView->_subresourceRange.levelCount)
                                              slices: sliceRange
                                             swizzle: mvkMTLTextureSwizzleChannelsFromVkComponentMapping(mvkUnpackSwizzle(_packedSwizzle))];    // retained
    } else {
        return [mtlTex newTextureViewWithPixelFormat: _mtlPixFmt
                                         textureType: mtlTextureType
                                              levels: NSMakeRange(_imageView->_subresourceRange.baseMipLevel, _imageView->_subresourceRange.levelCount)
                                              slices: sliceRange];    // retained
    }
}


#pragma mark Construction

MVKImageViewPlane::MVKImageViewPlane(MVKImageView* imageView,
									 uint8_t planeIndex,
									 MTLPixelFormat mtlPixFmt,
									 const VkImageViewCreateInfo* pCreateInfo) : MVKBaseDeviceObject(imageView->_device) {
    _imageView = imageView;
    _planeIndex = planeIndex;
    _mtlPixFmt = mtlPixFmt;
    _mtlTexture = nil;

    bool useSwizzle;
	_imageView->setConfigurationResult(_imageView->validateSwizzledMTLPixelFormat(pCreateInfo,
																				  _imageView,
																				  _device->_pMetalFeatures->nativeTextureSwizzle,
																				  _device->_pMVKConfig->fullImageViewSwizzle,
																				  _mtlPixFmt,
																				  useSwizzle));
    _packedSwizzle = (useSwizzle) ? mvkPackSwizzle(pCreateInfo->components) : 0;

    // Determine whether this image view should use a Metal texture view,
    // and set the _useMTLTextureView variable appropriately.
    if ( _imageView->_image ) {
        _useMTLTextureView = _imageView->_image->_canSupportMTLTextureView;
        bool is3D = _imageView->_image->_mtlTextureType == MTLTextureType3D;
        // If the view is identical to underlying image, don't bother using a Metal view
        if (_mtlPixFmt == _imageView->_image->getMTLPixelFormat(planeIndex) &&
            (_imageView->_mtlTextureType == _imageView->_image->_mtlTextureType ||
             ((_imageView->_mtlTextureType == MTLTextureType2D || _imageView->_mtlTextureType == MTLTextureType2DArray) && is3D)) &&
            _imageView->_subresourceRange.levelCount == _imageView->_image->_mipLevels &&
            (is3D || _imageView->_subresourceRange.layerCount == _imageView->_image->_arrayLayers) &&
            (!_device->_pMetalFeatures->nativeTextureSwizzle || !_packedSwizzle)) {
            _useMTLTextureView = false;
        }
    } else {
        _useMTLTextureView = false;
    }
}

MVKImageViewPlane::~MVKImageViewPlane() {
    [_mtlTexture release];
}


#pragma mark -
#pragma mark MVKImageView

void MVKImageView::propagateDebugName() {
    for (uint8_t planeIndex = 0; planeIndex < _planes.size(); planeIndex++) {
        _planes[planeIndex]->propagateDebugName();
    }
}

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.level = plane->_useMTLTextureView ? 0 : _subresourceRange.baseMipLevel;
    if (mtlAttDesc.texture.textureType == MTLTextureType3D) {
        mtlAttDesc.slice = 0;
        mtlAttDesc.depthPlane = plane->_useMTLTextureView ? 0 : _subresourceRange.baseArrayLayer;
    } else {
        mtlAttDesc.slice = plane->_useMTLTextureView ? 0 : _subresourceRange.baseArrayLayer;
        mtlAttDesc.depthPlane = 0;
    }
}

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.resolveLevel = plane->_useMTLTextureView ? 0 : _subresourceRange.baseMipLevel;
    if (mtlAttDesc.resolveTexture.textureType == MTLTextureType3D) {
        mtlAttDesc.resolveSlice = 0;
        mtlAttDesc.resolveDepthPlane = plane->_useMTLTextureView ? 0 : _subresourceRange.baseArrayLayer;
    } else {
        mtlAttDesc.resolveSlice = plane->_useMTLTextureView ? 0 : _subresourceRange.baseArrayLayer;
        mtlAttDesc.resolveDepthPlane = 0;
    }
}


#pragma mark Construction

MVKImageView::MVKImageView(MVKDevice* device,
						   const VkImageViewCreateInfo* pCreateInfo,
						   const MVKConfiguration* pAltMVKConfig) : MVKVulkanAPIDeviceObject(device) {
	_image = (MVKImage*)pCreateInfo->image;
	_usage = _image->_usage;
    _mtlTextureType = mvkMTLTextureTypeFromVkImageViewType(pCreateInfo->viewType,
														   _image->getSampleCount() != VK_SAMPLE_COUNT_1_BIT);

	for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
		switch (next->sType) {
			case VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO: {
				auto* pViewUsageInfo = (VkImageViewUsageCreateInfo*)next;
				if (!(pViewUsageInfo->usage & ~_usage)) { _usage = pViewUsageInfo->usage; }
				break;
			}
            /* case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR: {
                const VkSamplerYcbcrConversionInfoKHR* sampConvInfo = (const VkSamplerYcbcrConversionInfoKHR*)next;
                break;
            } */
			default:
				break;
		}
	}

    // Validate whether the image view configuration can be supported
    if ( _image ) {
        VkImageType imgType = _image->getImageType();
        VkImageViewType viewType = pCreateInfo->viewType;

        // VK_KHR_maintenance1 supports taking 2D image views of 3D slices for sampling.
		// No dice in Metal. But we are able to fake out a 3D render attachment by making the Metal view
		// itself a 3D texture (when we create it), and setting the rendering depthPlane appropriately.
        if ((viewType == VK_IMAGE_VIEW_TYPE_2D || viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) && (imgType == VK_IMAGE_TYPE_3D)) {
            if (!mvkIsOnlyAnyFlagEnabled(_usage, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
                setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImageView(): 2D views on 3D images can only be used as color attachments."));
            }
        }
    }

	// Remember the subresource range, and determine the actual number of mip levels and texture slices
    _subresourceRange = pCreateInfo->subresourceRange;
	if (_subresourceRange.levelCount == VK_REMAINING_MIP_LEVELS) {
		_subresourceRange.levelCount = _image->getMipLevelCount() - _subresourceRange.baseMipLevel;
	}
	if (_subresourceRange.layerCount == VK_REMAINING_ARRAY_LAYERS) {
		_subresourceRange.layerCount = _image->getLayerCount() - _subresourceRange.baseArrayLayer;
	}

    VkExtent2D blockTexelSizeOfPlane[3];
    uint32_t bytesPerBlockOfPlane[3];
    MTLPixelFormat mtlPixFmtOfPlane[3];
    uint8_t subsamplingPlaneCount = getPixelFormats()->getChromaSubsamplingPlanes(pCreateInfo->format, blockTexelSizeOfPlane, bytesPerBlockOfPlane, mtlPixFmtOfPlane),
            beginPlaneIndex = 0,
            endPlaneIndex = subsamplingPlaneCount;
    if (subsamplingPlaneCount == 0) {
        endPlaneIndex = 1;
        mtlPixFmtOfPlane[0] = getPixelFormats()->getMTLPixelFormat(pCreateInfo->format);
    } else {
        if (!mvkVkComponentMappingsMatch(pCreateInfo->components, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A})) {
            setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "Image view swizzling for multi planar formats is not supported."));
        }
        if (_subresourceRange.aspectMask & (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)) {
            beginPlaneIndex = endPlaneIndex = MVKImage::getPlaneFromVkImageAspectFlags(_subresourceRange.aspectMask);
        }
    }
    for (uint8_t planeIndex = beginPlaneIndex; planeIndex < endPlaneIndex; planeIndex++) {
        _planes.push_back(new MVKImageViewPlane(this, planeIndex, mtlPixFmtOfPlane[planeIndex], pCreateInfo));
    }
}

VkResult MVKImageView::validateSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo,
													  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) {
			if (mtlPixFmt == MTLPixelFormatDepth32Float_Stencil8)
				mtlPixFmt = MTLPixelFormatX32_Stencil8;
#if MVK_MACOS
			else if (mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8)
				mtlPixFmt = MTLPixelFormatX24_Stencil8;
#endif
		}

		return VK_SUCCESS;
	}

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


#pragma mark -
#pragma mark MVKSamplerYcbcrConversion

void MVKSamplerYcbcrConversion::updateConstExprSampler(MSLConstexprSampler& constExprSampler) const {
	constExprSampler.planes = _planes;
	constExprSampler.resolution = _resolution;
	constExprSampler.chroma_filter = _chroma_filter;
	constExprSampler.x_chroma_offset = _x_chroma_offset;
	constExprSampler.y_chroma_offset = _y_chroma_offset;
    for (uint32_t i = 0; i < 4; ++i) {
		constExprSampler.swizzle[i] = _swizzle[i];
    }
	constExprSampler.ycbcr_model = _ycbcr_model;
	constExprSampler.ycbcr_range = _ycbcr_range;
    constExprSampler.bpc = _bpc;
	constExprSampler.ycbcr_conversion_enable = true;
}

static MSLSamplerFilter getSpvMinMagFilterFromVkFilter(VkFilter vkFilter) {
    switch (vkFilter) {
        case VK_FILTER_LINEAR:    return MSL_SAMPLER_FILTER_LINEAR;

        case VK_FILTER_NEAREST:
        default:
            return MSL_SAMPLER_FILTER_NEAREST;
    }
}

static MSLChromaLocation getSpvChromaLocationFromVkChromaLocation(VkChromaLocation vkChromaLocation) {
	switch (vkChromaLocation) {
		default:
		case VK_CHROMA_LOCATION_COSITED_EVEN:   return MSL_CHROMA_LOCATION_COSITED_EVEN;
		case VK_CHROMA_LOCATION_MIDPOINT:       return MSL_CHROMA_LOCATION_MIDPOINT;
	}
}

static MSLComponentSwizzle getSpvComponentSwizzleFromVkComponentMapping(VkComponentSwizzle vkComponentSwizzle) {
	switch (vkComponentSwizzle) {
		default:
		case VK_COMPONENT_SWIZZLE_IDENTITY:     return MSL_COMPONENT_SWIZZLE_IDENTITY;
		case VK_COMPONENT_SWIZZLE_ZERO:         return MSL_COMPONENT_SWIZZLE_ZERO;
		case VK_COMPONENT_SWIZZLE_ONE:          return MSL_COMPONENT_SWIZZLE_ONE;
		case VK_COMPONENT_SWIZZLE_R:            return MSL_COMPONENT_SWIZZLE_R;
		case VK_COMPONENT_SWIZZLE_G:            return MSL_COMPONENT_SWIZZLE_G;
		case VK_COMPONENT_SWIZZLE_B:            return MSL_COMPONENT_SWIZZLE_B;
		case VK_COMPONENT_SWIZZLE_A:            return MSL_COMPONENT_SWIZZLE_A;
	}
}

static MSLSamplerYCbCrModelConversion getSpvSamplerYCbCrModelConversionFromVkSamplerYcbcrModelConversion(VkSamplerYcbcrModelConversion vkSamplerYcbcrModelConversion) {
	switch (vkSamplerYcbcrModelConversion) {
		default:
		case VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY:   return MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
		case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY: return MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY;
		case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709:      return MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_709;
		case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601:      return MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_601;
		case VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020:     return MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_2020;
	}
}

static MSLSamplerYCbCrRange getSpvSamplerYcbcrRangeFromVkSamplerYcbcrRange(VkSamplerYcbcrRange vkSamplerYcbcrRange) {
	switch (vkSamplerYcbcrRange) {
		default:
		case VK_SAMPLER_YCBCR_RANGE_ITU_FULL:   return MSL_SAMPLER_YCBCR_RANGE_ITU_FULL;
		case VK_SAMPLER_YCBCR_RANGE_ITU_NARROW: return MSL_SAMPLER_YCBCR_RANGE_ITU_NARROW;
	}
}

MVKSamplerYcbcrConversion::MVKSamplerYcbcrConversion(MVKDevice* device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
	MVKPixelFormats* pixFmts = getPixelFormats();
	_planes = pixFmts->getChromaSubsamplingPlaneCount(pCreateInfo->format);
	_bpc = pixFmts->getChromaSubsamplingComponentBits(pCreateInfo->format);
	_resolution = pixFmts->getChromaSubsamplingResolution(pCreateInfo->format);
	_chroma_filter = getSpvMinMagFilterFromVkFilter(pCreateInfo->chromaFilter);
	_x_chroma_offset = getSpvChromaLocationFromVkChromaLocation(pCreateInfo->xChromaOffset);
	_y_chroma_offset = getSpvChromaLocationFromVkChromaLocation(pCreateInfo->yChromaOffset);
	_swizzle[0] = getSpvComponentSwizzleFromVkComponentMapping(pCreateInfo->components.r);
	_swizzle[1] = getSpvComponentSwizzleFromVkComponentMapping(pCreateInfo->components.g);
	_swizzle[2] = getSpvComponentSwizzleFromVkComponentMapping(pCreateInfo->components.b);
	_swizzle[3] = getSpvComponentSwizzleFromVkComponentMapping(pCreateInfo->components.a);
	_ycbcr_model = getSpvSamplerYCbCrModelConversionFromVkSamplerYcbcrModelConversion(pCreateInfo->ycbcrModel);
	_ycbcr_range = getSpvSamplerYcbcrRangeFromVkSamplerYcbcrRange(pCreateInfo->ycbcrRange);
	_forceExplicitReconstruction = pCreateInfo->forceExplicitReconstruction;
}


#pragma mark -
#pragma mark MVKSampler

bool MVKSampler::getConstexprSampler(mvk::MSLResourceBinding& resourceBinding) {
	resourceBinding.requiresConstExprSampler = _requiresConstExprSampler;
	if (_requiresConstExprSampler) {
		resourceBinding.constExprSampler = _constExprSampler;
	}
	return _requiresConstExprSampler;
}

// Returns an Metal sampler descriptor constructed from the properties of this image.
// It is the caller's responsibility to release the returned descriptor object.
MTLSamplerDescriptor* MVKSampler::newMTLSamplerDescriptor(const VkSamplerCreateInfo* pCreateInfo) {

	MTLSamplerDescriptor* mtlSampDesc = [MTLSamplerDescriptor new];		// retained
	mtlSampDesc.sAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeU);
	mtlSampDesc.tAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeV);
    if (!pCreateInfo->unnormalizedCoordinates) {
        mtlSampDesc.rAddressMode = mvkMTLSamplerAddressModeFromVkSamplerAddressMode(pCreateInfo->addressModeW);
    }
	mtlSampDesc.minFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->minFilter);
	mtlSampDesc.magFilter = mvkMTLSamplerMinMagFilterFromVkFilter(pCreateInfo->magFilter);
    mtlSampDesc.mipFilter = (pCreateInfo->unnormalizedCoordinates
                             ? MTLSamplerMipFilterNotMipmapped
                             : mvkMTLSamplerMipFilterFromVkSamplerMipmapMode(pCreateInfo->mipmapMode));
	mtlSampDesc.lodMinClamp = pCreateInfo->minLod;
	mtlSampDesc.lodMaxClamp = pCreateInfo->maxLod;
	mtlSampDesc.maxAnisotropy = (pCreateInfo->anisotropyEnable
								 ? mvkClamp(pCreateInfo->maxAnisotropy, 1.0f, _device->_pProperties->limits.maxSamplerAnisotropy)
								 : 1);
	mtlSampDesc.normalizedCoordinates = !pCreateInfo->unnormalizedCoordinates;

	// If compareEnable is true, but dynamic samplers with depth compare are not available
	// on this device, this sampler must only be used as an immutable sampler, and will
	// be automatically hardcoded into the shader MSL. An error will be triggered if this
	// sampler is used to update or push a descriptor.
	if (pCreateInfo->compareEnable && !_requiresConstExprSampler) {
		mtlSampDesc.compareFunctionMVK = mvkMTLCompareFunctionFromVkCompareOp(pCreateInfo->compareOp);
	}

#if MVK_MACOS
	mtlSampDesc.borderColorMVK = mvkMTLSamplerBorderColorFromVkBorderColor(pCreateInfo->borderColor);
	if (_device->getPhysicalDevice()->getMetalFeatures()->samplerClampToBorder) {
		if (pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
			mtlSampDesc.sAddressMode = MTLSamplerAddressModeClampToBorderColor;
		}
		if (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
			mtlSampDesc.tAddressMode = MTLSamplerAddressModeClampToBorderColor;
		}
		if (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) {
			mtlSampDesc.rAddressMode = MTLSamplerAddressModeClampToBorderColor;
		}
	}
#endif
	return mtlSampDesc;
}

MVKSampler::MVKSampler(MVKDevice* device, const VkSamplerCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
    _ycbcrConversion = NULL;
    for (const auto* next = (const VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
		switch (next->sType) {
			case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR: {
				const VkSamplerYcbcrConversionInfoKHR* sampConvInfo = (const VkSamplerYcbcrConversionInfoKHR*)next;
				_ycbcrConversion = (MVKSamplerYcbcrConversion*)(sampConvInfo->conversion);
				break;
			}
			default:
				break;
		}
	}

	_requiresConstExprSampler = (pCreateInfo->compareEnable && !_device->_pMetalFeatures->depthSampleCompare) || _ycbcrConversion;

	@autoreleasepool {
		MTLSamplerDescriptor* mtlSampDesc = newMTLSamplerDescriptor(pCreateInfo);	// temp retain
		_mtlSamplerState = [getMTLDevice() newSamplerStateWithDescriptor: mtlSampDesc];
		[mtlSampDesc release];														// temp release
	}

	initConstExprSampler(pCreateInfo);
}

static MSLSamplerMipFilter getSpvMipFilterFromVkMipMode(VkSamplerMipmapMode vkMipMode) {
	switch (vkMipMode) {
		case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return MSL_SAMPLER_MIP_FILTER_LINEAR;
		case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return MSL_SAMPLER_MIP_FILTER_NEAREST;

		default:
			return MSL_SAMPLER_MIP_FILTER_NONE;
	}
}

static MSLSamplerAddress getSpvAddressModeFromVkAddressMode(VkSamplerAddressMode vkAddrMode) {
	switch (vkAddrMode) {
		case VK_SAMPLER_ADDRESS_MODE_REPEAT:			return MSL_SAMPLER_ADDRESS_REPEAT;
		case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:	return MSL_SAMPLER_ADDRESS_MIRRORED_REPEAT;
		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:	return MSL_SAMPLER_ADDRESS_CLAMP_TO_BORDER;

		case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
		default:
			return MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
	}
}

static MSLSamplerCompareFunc getSpvCompFuncFromVkCompOp(VkCompareOp vkCompOp) {
	switch (vkCompOp) {
		case VK_COMPARE_OP_LESS:				return MSL_SAMPLER_COMPARE_FUNC_LESS;
		case VK_COMPARE_OP_EQUAL:				return MSL_SAMPLER_COMPARE_FUNC_EQUAL;
		case VK_COMPARE_OP_LESS_OR_EQUAL:		return MSL_SAMPLER_COMPARE_FUNC_LESS_EQUAL;
		case VK_COMPARE_OP_GREATER:				return MSL_SAMPLER_COMPARE_FUNC_GREATER;
		case VK_COMPARE_OP_NOT_EQUAL:			return MSL_SAMPLER_COMPARE_FUNC_NOT_EQUAL;
		case VK_COMPARE_OP_GREATER_OR_EQUAL:	return MSL_SAMPLER_COMPARE_FUNC_GREATER_EQUAL;
		case VK_COMPARE_OP_ALWAYS:				return MSL_SAMPLER_COMPARE_FUNC_ALWAYS;

		case VK_COMPARE_OP_NEVER:
		default:
			return MSL_SAMPLER_COMPARE_FUNC_NEVER;
	}
}

static MSLSamplerBorderColor getSpvBorderColorFromVkBorderColor(VkBorderColor vkBorderColor) {
	switch (vkBorderColor) {
		case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
		case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
			return MSL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK;

		case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
		case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
			return MSL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE;

		case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
		case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
		default:
			return MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK;
	}
}

void MVKSampler::initConstExprSampler(const VkSamplerCreateInfo* pCreateInfo) {
	if ( !_requiresConstExprSampler ) { return; }

	_constExprSampler.coord = pCreateInfo->unnormalizedCoordinates ? MSL_SAMPLER_COORD_PIXEL : MSL_SAMPLER_COORD_NORMALIZED;
	_constExprSampler.min_filter = getSpvMinMagFilterFromVkFilter(pCreateInfo->minFilter);
	_constExprSampler.mag_filter = getSpvMinMagFilterFromVkFilter(pCreateInfo->magFilter);
	_constExprSampler.mip_filter = getSpvMipFilterFromVkMipMode(pCreateInfo->mipmapMode);
	_constExprSampler.s_address = getSpvAddressModeFromVkAddressMode(pCreateInfo->addressModeU);
	_constExprSampler.t_address = getSpvAddressModeFromVkAddressMode(pCreateInfo->addressModeV);
	_constExprSampler.r_address = getSpvAddressModeFromVkAddressMode(pCreateInfo->addressModeW);
	_constExprSampler.compare_func = getSpvCompFuncFromVkCompOp(pCreateInfo->compareOp);
	_constExprSampler.border_color = getSpvBorderColorFromVkBorderColor(pCreateInfo->borderColor);
	_constExprSampler.lod_clamp_min = pCreateInfo->minLod;
	_constExprSampler.lod_clamp_max = pCreateInfo->maxLod;
	_constExprSampler.max_anisotropy = pCreateInfo->maxAnisotropy;
	_constExprSampler.compare_enable = pCreateInfo->compareEnable;
	_constExprSampler.lod_clamp_enable = false;
	_constExprSampler.anisotropy_enable = pCreateInfo->anisotropyEnable;
    if (_ycbcrConversion) {
        _ycbcrConversion->updateConstExprSampler(_constExprSampler);
    }
}

MVKSampler::~MVKSampler() {
	[_mtlSamplerState release];
}
