// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// 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 "VkImage.hpp"

#include "VkBuffer.hpp"
#include "VkDevice.hpp"
#include "VkDeviceMemory.hpp"
#include "VkImageView.hpp"
#include "VkStringify.hpp"
#include "VkStructConversion.hpp"
#include "Device/ASTC_Decoder.hpp"
#include "Device/BC_Decoder.hpp"
#include "Device/Blitter.hpp"
#include "Device/ETC_Decoder.hpp"

#ifdef __ANDROID__
#	include "System/GrallocAndroid.hpp"
#	include "VkDeviceMemoryExternalAndroid.hpp"
#endif

#include <cstring>

namespace {

ETC_Decoder::InputType GetInputType(const vk::Format &format)
{
	switch(format)
	{
	case VK_FORMAT_EAC_R11_UNORM_BLOCK:
		return ETC_Decoder::ETC_R_UNSIGNED;
	case VK_FORMAT_EAC_R11_SNORM_BLOCK:
		return ETC_Decoder::ETC_R_SIGNED;
	case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
		return ETC_Decoder::ETC_RG_UNSIGNED;
	case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
		return ETC_Decoder::ETC_RG_SIGNED;
	case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
		return ETC_Decoder::ETC_RGB;
	case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
		return ETC_Decoder::ETC_RGB_PUNCHTHROUGH_ALPHA;
	case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
		return ETC_Decoder::ETC_RGBA;
	default:
		UNSUPPORTED("format: %d", int(format));
		return ETC_Decoder::ETC_RGBA;
	}
}

int GetBCn(const vk::Format &format)
{
	switch(format)
	{
	case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
	case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
	case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
	case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
		return 1;
	case VK_FORMAT_BC2_UNORM_BLOCK:
	case VK_FORMAT_BC2_SRGB_BLOCK:
		return 2;
	case VK_FORMAT_BC3_UNORM_BLOCK:
	case VK_FORMAT_BC3_SRGB_BLOCK:
		return 3;
	case VK_FORMAT_BC4_UNORM_BLOCK:
	case VK_FORMAT_BC4_SNORM_BLOCK:
		return 4;
	case VK_FORMAT_BC5_UNORM_BLOCK:
	case VK_FORMAT_BC5_SNORM_BLOCK:
		return 5;
	case VK_FORMAT_BC6H_UFLOAT_BLOCK:
	case VK_FORMAT_BC6H_SFLOAT_BLOCK:
		return 6;
	case VK_FORMAT_BC7_UNORM_BLOCK:
	case VK_FORMAT_BC7_SRGB_BLOCK:
		return 7;
	default:
		UNSUPPORTED("format: %d", int(format));
		return 0;
	}
}

// Returns true for BC1 if we have an RGB format, false for RGBA
// Returns true for BC4, BC5, BC6H if we have an unsigned format, false for signed
// Ignored by BC2, BC3, and BC7
bool GetNoAlphaOrUnsigned(const vk::Format &format)
{
	switch(format)
	{
	case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
	case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
	case VK_FORMAT_BC4_UNORM_BLOCK:
	case VK_FORMAT_BC5_UNORM_BLOCK:
	case VK_FORMAT_BC6H_UFLOAT_BLOCK:
		return true;
	case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
	case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
	case VK_FORMAT_BC2_UNORM_BLOCK:
	case VK_FORMAT_BC2_SRGB_BLOCK:
	case VK_FORMAT_BC3_UNORM_BLOCK:
	case VK_FORMAT_BC3_SRGB_BLOCK:
	case VK_FORMAT_BC4_SNORM_BLOCK:
	case VK_FORMAT_BC5_SNORM_BLOCK:
	case VK_FORMAT_BC6H_SFLOAT_BLOCK:
	case VK_FORMAT_BC7_SRGB_BLOCK:
	case VK_FORMAT_BC7_UNORM_BLOCK:
		return false;
	default:
		UNSUPPORTED("format: %d", int(format));
		return false;
	}
}

VkFormat GetImageFormat(const VkImageCreateInfo *pCreateInfo)
{
	auto nextInfo = reinterpret_cast<VkBaseInStructure const *>(pCreateInfo->pNext);
	while(nextInfo)
	{
		// Casting to an int since some structures, such as VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID and
		// VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID, are not enumerated in the official Vulkan headers.
		switch((int)(nextInfo->sType))
		{
#ifdef __ANDROID__
		case VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID:
			{
				const VkExternalFormatANDROID *externalFormatAndroid = reinterpret_cast<const VkExternalFormatANDROID *>(nextInfo);

				// VkExternalFormatANDROID: "If externalFormat is zero, the effect is as if the VkExternalFormatANDROID structure was not present."
				if(externalFormatAndroid->externalFormat == 0)
				{
					break;
				}

				const VkFormat correspondingVkFormat = AHardwareBufferExternalMemory::GetVkFormatFromAHBFormat(externalFormatAndroid->externalFormat);
				ASSERT(pCreateInfo->format == VK_FORMAT_UNDEFINED || pCreateInfo->format == correspondingVkFormat);
				return correspondingVkFormat;
			}
			break;
		case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID:
			break;
		case VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID:
			break;
#endif
		// We support these extensions, but they don't affect the image format.
		case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO:
		case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
		case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
		case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
			break;
		case VK_STRUCTURE_TYPE_MAX_ENUM:
			// dEQP tests that this value is ignored.
			break;
		default:
			UNSUPPORTED("pCreateInfo->pNext->sType = %s", vk::Stringify(nextInfo->sType).c_str());
			break;
		}

		nextInfo = nextInfo->pNext;
	}

	return pCreateInfo->format;
}

}  // anonymous namespace

namespace vk {

Image::Image(const VkImageCreateInfo *pCreateInfo, void *mem, Device *device)
    : device(device)
    , flags(pCreateInfo->flags)
    , imageType(pCreateInfo->imageType)
    , format(GetImageFormat(pCreateInfo))
    , extent(pCreateInfo->extent)
    , mipLevels(pCreateInfo->mipLevels)
    , arrayLayers(pCreateInfo->arrayLayers)
    , samples(pCreateInfo->samples)
    , tiling(pCreateInfo->tiling)
    , usage(pCreateInfo->usage)
{
	if(format.isCompressed())
	{
		VkImageCreateInfo compressedImageCreateInfo = *pCreateInfo;
		compressedImageCreateInfo.format = format.getDecompressedFormat();
		decompressedImage = new(mem) Image(&compressedImageCreateInfo, nullptr, device);
	}

	const auto *nextInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
	for(; nextInfo != nullptr; nextInfo = nextInfo->pNext)
	{
		if(nextInfo->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO)
		{
			const auto *externalInfo = reinterpret_cast<const VkExternalMemoryImageCreateInfo *>(nextInfo);
			supportedExternalMemoryHandleTypes = externalInfo->handleTypes;
		}
	}
}

void Image::destroy(const VkAllocationCallbacks *pAllocator)
{
	if(decompressedImage)
	{
		vk::freeHostMemory(decompressedImage, pAllocator);
	}
}

size_t Image::ComputeRequiredAllocationSize(const VkImageCreateInfo *pCreateInfo)
{
	return Format(pCreateInfo->format).isCompressed() ? sizeof(Image) : 0;
}

const VkMemoryRequirements Image::getMemoryRequirements() const
{
	VkMemoryRequirements memoryRequirements;
	memoryRequirements.alignment = vk::REQUIRED_MEMORY_ALIGNMENT;
	memoryRequirements.memoryTypeBits = vk::MEMORY_TYPE_GENERIC_BIT;
	memoryRequirements.size = getStorageSize(format.getAspects()) +
	                          (decompressedImage ? decompressedImage->getStorageSize(decompressedImage->format.getAspects()) : 0);
	return memoryRequirements;
}

size_t Image::getSizeInBytes(const VkImageSubresourceRange &subresourceRange) const
{
	size_t size = 0;
	uint32_t lastLayer = getLastLayerIndex(subresourceRange);
	uint32_t lastMipLevel = getLastMipLevel(subresourceRange);
	uint32_t layerCount = lastLayer - subresourceRange.baseArrayLayer + 1;
	uint32_t mipLevelCount = lastMipLevel - subresourceRange.baseMipLevel + 1;

	auto aspect = static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask);

	if(layerCount > 1)
	{
		if(mipLevelCount < mipLevels)  // Compute size for all layers except the last one, then add relevant mip level sizes only for last layer
		{
			size = (layerCount - 1) * getLayerSize(aspect);
			for(uint32_t mipLevel = subresourceRange.baseMipLevel; mipLevel <= lastMipLevel; ++mipLevel)
			{
				size += getMultiSampledLevelSize(aspect, mipLevel);
			}
		}
		else  // All mip levels used, compute full layer sizes
		{
			size = layerCount * getLayerSize(aspect);
		}
	}
	else  // Single layer, add all mip levels in the subresource range
	{
		for(uint32_t mipLevel = subresourceRange.baseMipLevel; mipLevel <= lastMipLevel; ++mipLevel)
		{
			size += getMultiSampledLevelSize(aspect, mipLevel);
		}
	}

	return size;
}

bool Image::canBindToMemory(DeviceMemory *pDeviceMemory) const
{
	return pDeviceMemory->checkExternalMemoryHandleType(supportedExternalMemoryHandleTypes);
}

void Image::bind(DeviceMemory *pDeviceMemory, VkDeviceSize pMemoryOffset)
{
	deviceMemory = pDeviceMemory;
	memoryOffset = pMemoryOffset;
	if(decompressedImage)
	{
		decompressedImage->deviceMemory = deviceMemory;
		decompressedImage->memoryOffset = memoryOffset + getStorageSize(format.getAspects());
	}
}

#ifdef __ANDROID__
VkResult Image::prepareForExternalUseANDROID() const
{
	void *nativeBuffer = nullptr;
	VkExtent3D extent = getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);

	buffer_handle_t importedBufferHandle = nullptr;
	if(GrallocModule::getInstance()->import(backingMemory.nativeHandle, &importedBufferHandle) != 0)
	{
		return VK_ERROR_OUT_OF_DATE_KHR;
	}
	if(!importedBufferHandle)
	{
		return VK_ERROR_OUT_OF_DATE_KHR;
	}

	if(GrallocModule::getInstance()->lock(importedBufferHandle, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, extent.width, extent.height, &nativeBuffer) != 0)
	{
		return VK_ERROR_OUT_OF_DATE_KHR;
	}

	if(!nativeBuffer)
	{
		return VK_ERROR_OUT_OF_DATE_KHR;
	}

	int imageRowBytes = rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
	int bufferRowBytes = backingMemory.stride * getFormat().bytes();
	ASSERT(imageRowBytes <= bufferRowBytes);

	uint8_t *srcBuffer = static_cast<uint8_t *>(deviceMemory->getOffsetPointer(0));
	uint8_t *dstBuffer = static_cast<uint8_t *>(nativeBuffer);
	for(uint32_t i = 0; i < extent.height; i++)
	{
		memcpy(dstBuffer + (i * bufferRowBytes), srcBuffer + (i * imageRowBytes), imageRowBytes);
	}

	if(GrallocModule::getInstance()->unlock(importedBufferHandle) != 0)
	{
		return VK_ERROR_OUT_OF_DATE_KHR;
	}

	if(GrallocModule::getInstance()->release(importedBufferHandle) != 0)
	{
		return VK_ERROR_OUT_OF_DATE_KHR;
	}

	return VK_SUCCESS;
}

VkDeviceMemory Image::getExternalMemory() const
{
	return backingMemory.externalMemory ? *deviceMemory : VkDeviceMemory{ VK_NULL_HANDLE };
}
#endif

void Image::getSubresourceLayout(const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) const
{
	// By spec, aspectMask has a single bit set.
	if(!((pSubresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
	     (pSubresource->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
	     (pSubresource->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) ||
	     (pSubresource->aspectMask == VK_IMAGE_ASPECT_PLANE_0_BIT) ||
	     (pSubresource->aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT) ||
	     (pSubresource->aspectMask == VK_IMAGE_ASPECT_PLANE_2_BIT)))
	{
		UNSUPPORTED("aspectMask %X", pSubresource->aspectMask);
	}

	auto aspect = static_cast<VkImageAspectFlagBits>(pSubresource->aspectMask);
	pLayout->offset = getMemoryOffset(aspect, pSubresource->mipLevel, pSubresource->arrayLayer);
	pLayout->size = getMultiSampledLevelSize(aspect, pSubresource->mipLevel);
	pLayout->rowPitch = rowPitchBytes(aspect, pSubresource->mipLevel);
	pLayout->depthPitch = slicePitchBytes(aspect, pSubresource->mipLevel);
	pLayout->arrayPitch = getLayerSize(aspect);
}

void Image::copyTo(Image *dstImage, const VkImageCopy2KHR &region) const
{
	static constexpr VkImageAspectFlags CombinedDepthStencilAspects =
	    VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
	if((region.srcSubresource.aspectMask == CombinedDepthStencilAspects) &&
	   (region.dstSubresource.aspectMask == CombinedDepthStencilAspects))
	{
		// Depth and stencil can be specified together, copy each separately
		VkImageCopy2KHR singleAspectRegion = region;
		singleAspectRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
		singleAspectRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
		copySingleAspectTo(dstImage, singleAspectRegion);
		singleAspectRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
		singleAspectRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
		copySingleAspectTo(dstImage, singleAspectRegion);
		return;
	}

	copySingleAspectTo(dstImage, region);
}

void Image::copySingleAspectTo(Image *dstImage, const VkImageCopy2KHR &region) const
{
	// Image copy does not perform any conversion, it simply copies memory from
	// an image to another image that has the same number of bytes per pixel.

	if(!((region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
	     (region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
	     (region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) ||
	     (region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_0_BIT) ||
	     (region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT) ||
	     (region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_2_BIT)))
	{
		UNSUPPORTED("srcSubresource.aspectMask %X", region.srcSubresource.aspectMask);
	}

	if(!((region.dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
	     (region.dstSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
	     (region.dstSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) ||
	     (region.dstSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_0_BIT) ||
	     (region.dstSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT) ||
	     (region.dstSubresource.aspectMask == VK_IMAGE_ASPECT_PLANE_2_BIT)))
	{
		UNSUPPORTED("dstSubresource.aspectMask %X", region.dstSubresource.aspectMask);
	}

	VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(region.srcSubresource.aspectMask);
	VkImageAspectFlagBits dstAspect = static_cast<VkImageAspectFlagBits>(region.dstSubresource.aspectMask);

	Format srcFormat = getFormat(srcAspect);
	Format dstFormat = dstImage->getFormat(dstAspect);
	int bytesPerBlock = srcFormat.bytesPerBlock();
	ASSERT(bytesPerBlock == dstFormat.bytesPerBlock());
	ASSERT(samples == dstImage->samples);

	VkExtent3D srcExtent = getMipLevelExtent(srcAspect, region.srcSubresource.mipLevel);
	VkExtent3D dstExtent = dstImage->getMipLevelExtent(dstAspect, region.dstSubresource.mipLevel);
	VkExtent3D copyExtent = imageExtentInBlocks(region.extent, srcAspect);

	VkImageType srcImageType = imageType;
	VkImageType dstImageType = dstImage->getImageType();
	bool one3D = (srcImageType == VK_IMAGE_TYPE_3D) != (dstImageType == VK_IMAGE_TYPE_3D);
	bool both3D = (srcImageType == VK_IMAGE_TYPE_3D) && (dstImageType == VK_IMAGE_TYPE_3D);

	// Texel layout pitches, using the VkSubresourceLayout nomenclature.
	int srcRowPitch = rowPitchBytes(srcAspect, region.srcSubresource.mipLevel);
	int srcDepthPitch = slicePitchBytes(srcAspect, region.srcSubresource.mipLevel);
	int dstRowPitch = dstImage->rowPitchBytes(dstAspect, region.dstSubresource.mipLevel);
	int dstDepthPitch = dstImage->slicePitchBytes(dstAspect, region.dstSubresource.mipLevel);
	VkDeviceSize srcArrayPitch = getLayerSize(srcAspect);
	VkDeviceSize dstArrayPitch = dstImage->getLayerSize(dstAspect);

	// These are the pitches used when iterating over the layers that are being copied by the
	// vkCmdCopyImage command. They can differ from the above array piches because the spec states that:
	// "If one image is VK_IMAGE_TYPE_3D and the other image is VK_IMAGE_TYPE_2D with multiple
	//  layers, then each slice is copied to or from a different layer."
	VkDeviceSize srcLayerPitch = (srcImageType == VK_IMAGE_TYPE_3D) ? srcDepthPitch : srcArrayPitch;
	VkDeviceSize dstLayerPitch = (dstImageType == VK_IMAGE_TYPE_3D) ? dstDepthPitch : dstArrayPitch;

	// If one image is 3D, extent.depth must match the layer count. If both images are 2D,
	// depth is 1 but the source and destination subresource layer count must match.
	uint32_t layerCount = one3D ? copyExtent.depth : region.srcSubresource.layerCount;

	// Copies between 2D and 3D images are treated as layers, so only use depth as the slice count when
	// both images are 3D.
	// Multisample images are currently implemented similar to 3D images by storing one sample per slice.
	// TODO(b/160600347): Store samples consecutively.
	uint32_t sliceCount = both3D ? copyExtent.depth : samples;

	bool isSingleSlice = (sliceCount == 1);
	bool isSingleRow = (copyExtent.height == 1) && isSingleSlice;
	// In order to copy multiple rows using a single memcpy call, we
	// have to make sure that we need to copy the entire row and that
	// both source and destination rows have the same size in bytes
	bool isEntireRow = (region.extent.width == srcExtent.width) &&
	                   (region.extent.width == dstExtent.width) &&
	                   // For non-compressed formats, blockWidth is 1. For compressed
	                   // formats, rowPitchBytes returns the number of bytes for a row of
	                   // blocks, so we have to divide by the block height, which means:
	                   // srcRowPitchBytes / srcBlockWidth == dstRowPitchBytes / dstBlockWidth
	                   // And, to avoid potential non exact integer division, for example if a
	                   // block has 16 bytes and represents 5 rows, we change the equation to:
	                   // srcRowPitchBytes * dstBlockWidth == dstRowPitchBytes * srcBlockWidth
	                   ((srcRowPitch * dstFormat.blockWidth()) ==
	                    (dstRowPitch * srcFormat.blockWidth()));
	// In order to copy multiple slices using a single memcpy call, we
	// have to make sure that we need to copy the entire slice and that
	// both source and destination slices have the same size in bytes
	bool isEntireSlice = isEntireRow &&
	                     (copyExtent.height == srcExtent.height) &&
	                     (copyExtent.height == dstExtent.height) &&
	                     (srcDepthPitch == dstDepthPitch);

	const uint8_t *srcLayer = static_cast<const uint8_t *>(getTexelPointer(region.srcOffset, ImageSubresource(region.srcSubresource)));
	uint8_t *dstLayer = static_cast<uint8_t *>(dstImage->getTexelPointer(region.dstOffset, ImageSubresource(region.dstSubresource)));

	for(uint32_t layer = 0; layer < layerCount; layer++)
	{
		if(isSingleRow)  // Copy one row
		{
			size_t copySize = copyExtent.width * bytesPerBlock;
			ASSERT((srcLayer + copySize) < end());
			ASSERT((dstLayer + copySize) < dstImage->end());
			memcpy(dstLayer, srcLayer, copySize);
		}
		else if(isEntireRow && isSingleSlice)  // Copy one slice
		{
			size_t copySize = copyExtent.height * srcRowPitch;
			ASSERT((srcLayer + copySize) < end());
			ASSERT((dstLayer + copySize) < dstImage->end());
			memcpy(dstLayer, srcLayer, copySize);
		}
		else if(isEntireSlice)  // Copy multiple slices
		{
			size_t copySize = sliceCount * srcDepthPitch;
			ASSERT((srcLayer + copySize) < end());
			ASSERT((dstLayer + copySize) < dstImage->end());
			memcpy(dstLayer, srcLayer, copySize);
		}
		else if(isEntireRow)  // Copy slice by slice
		{
			size_t sliceSize = copyExtent.height * srcRowPitch;
			const uint8_t *srcSlice = srcLayer;
			uint8_t *dstSlice = dstLayer;

			for(uint32_t z = 0; z < sliceCount; z++)
			{
				ASSERT((srcSlice + sliceSize) < end());
				ASSERT((dstSlice + sliceSize) < dstImage->end());

				memcpy(dstSlice, srcSlice, sliceSize);

				dstSlice += dstDepthPitch;
				srcSlice += srcDepthPitch;
			}
		}
		else  // Copy row by row
		{
			size_t rowSize = copyExtent.width * bytesPerBlock;
			const uint8_t *srcSlice = srcLayer;
			uint8_t *dstSlice = dstLayer;

			for(uint32_t z = 0; z < sliceCount; z++)
			{
				const uint8_t *srcRow = srcSlice;
				uint8_t *dstRow = dstSlice;

				for(uint32_t y = 0; y < copyExtent.height; y++)
				{
					ASSERT((srcRow + rowSize) < end());
					ASSERT((dstRow + rowSize) < dstImage->end());

					memcpy(dstRow, srcRow, rowSize);

					srcRow += srcRowPitch;
					dstRow += dstRowPitch;
				}

				srcSlice += srcDepthPitch;
				dstSlice += dstDepthPitch;
			}
		}

		srcLayer += srcLayerPitch;
		dstLayer += dstLayerPitch;
	}

	dstImage->contentsChanged(ImageSubresourceRange(region.dstSubresource));
}

void Image::copy(Buffer *buffer, const VkBufferImageCopy2KHR &region, bool bufferIsSource)
{
	switch(region.imageSubresource.aspectMask)
	{
	case VK_IMAGE_ASPECT_COLOR_BIT:
	case VK_IMAGE_ASPECT_DEPTH_BIT:
	case VK_IMAGE_ASPECT_STENCIL_BIT:
	case VK_IMAGE_ASPECT_PLANE_0_BIT:
	case VK_IMAGE_ASPECT_PLANE_1_BIT:
	case VK_IMAGE_ASPECT_PLANE_2_BIT:
		break;
	default:
		UNSUPPORTED("aspectMask %x", int(region.imageSubresource.aspectMask));
		break;
	}

	auto aspect = static_cast<VkImageAspectFlagBits>(region.imageSubresource.aspectMask);
	Format copyFormat = getFormat(aspect);

	VkExtent3D imageExtent = imageExtentInBlocks(region.imageExtent, aspect);

	if(imageExtent.width == 0 || imageExtent.height == 0 || imageExtent.depth == 0)
	{
		return;
	}

	VkExtent2D bufferExtent = bufferExtentInBlocks(Extent2D(imageExtent), region);
	int bytesPerBlock = copyFormat.bytesPerBlock();
	int bufferRowPitchBytes = bufferExtent.width * bytesPerBlock;
	int bufferSlicePitchBytes = bufferExtent.height * bufferRowPitchBytes;
	ASSERT(samples == 1);

	uint8_t *bufferMemory = static_cast<uint8_t *>(buffer->getOffsetPointer(region.bufferOffset));
	uint8_t *imageMemory = static_cast<uint8_t *>(getTexelPointer(region.imageOffset, ImageSubresource(region.imageSubresource)));
	uint8_t *srcMemory = bufferIsSource ? bufferMemory : imageMemory;
	uint8_t *dstMemory = bufferIsSource ? imageMemory : bufferMemory;
	int imageRowPitchBytes = rowPitchBytes(aspect, region.imageSubresource.mipLevel);
	int imageSlicePitchBytes = slicePitchBytes(aspect, region.imageSubresource.mipLevel);

	int srcSlicePitchBytes = bufferIsSource ? bufferSlicePitchBytes : imageSlicePitchBytes;
	int dstSlicePitchBytes = bufferIsSource ? imageSlicePitchBytes : bufferSlicePitchBytes;
	int srcRowPitchBytes = bufferIsSource ? bufferRowPitchBytes : imageRowPitchBytes;
	int dstRowPitchBytes = bufferIsSource ? imageRowPitchBytes : bufferRowPitchBytes;

	VkExtent3D mipLevelExtent = getMipLevelExtent(aspect, region.imageSubresource.mipLevel);
	bool isSingleSlice = (imageExtent.depth == 1);
	bool isSingleRow = (imageExtent.height == 1) && isSingleSlice;
	bool isEntireRow = (imageExtent.width == mipLevelExtent.width) &&
	                   (imageRowPitchBytes == bufferRowPitchBytes);
	bool isEntireSlice = isEntireRow && (imageExtent.height == mipLevelExtent.height) &&
	                     (imageSlicePitchBytes == bufferSlicePitchBytes);

	VkDeviceSize copySize = 0;
	if(isSingleRow)
	{
		copySize = imageExtent.width * bytesPerBlock;
	}
	else if(isEntireRow && isSingleSlice)
	{
		copySize = (imageExtent.height - 1) * imageRowPitchBytes + imageExtent.width * bytesPerBlock;
	}
	else if(isEntireSlice)
	{
		copySize = (imageExtent.depth - 1) * imageSlicePitchBytes + (imageExtent.height - 1) * imageRowPitchBytes + imageExtent.width * bytesPerBlock;  // Copy multiple slices
	}
	else if(isEntireRow)  // Copy slice by slice
	{
		copySize = (imageExtent.height - 1) * imageRowPitchBytes + imageExtent.width * bytesPerBlock;
	}
	else  // Copy row by row
	{
		copySize = imageExtent.width * bytesPerBlock;
	}

	VkDeviceSize imageLayerSize = getLayerSize(aspect);
	VkDeviceSize srcLayerSize = bufferIsSource ? bufferSlicePitchBytes : imageLayerSize;
	VkDeviceSize dstLayerSize = bufferIsSource ? imageLayerSize : bufferSlicePitchBytes;

	for(uint32_t i = 0; i < region.imageSubresource.layerCount; i++)
	{
		if(isSingleRow || (isEntireRow && isSingleSlice) || isEntireSlice)
		{
			ASSERT(((bufferIsSource ? dstMemory : srcMemory) + copySize) < end());
			ASSERT(((bufferIsSource ? srcMemory : dstMemory) + copySize) < buffer->end());
			memcpy(dstMemory, srcMemory, copySize);
		}
		else if(isEntireRow)  // Copy slice by slice
		{
			uint8_t *srcSliceMemory = srcMemory;
			uint8_t *dstSliceMemory = dstMemory;
			for(uint32_t z = 0; z < imageExtent.depth; z++)
			{
				ASSERT(((bufferIsSource ? dstSliceMemory : srcSliceMemory) + copySize) < end());
				ASSERT(((bufferIsSource ? srcSliceMemory : dstSliceMemory) + copySize) < buffer->end());
				memcpy(dstSliceMemory, srcSliceMemory, copySize);
				srcSliceMemory += srcSlicePitchBytes;
				dstSliceMemory += dstSlicePitchBytes;
			}
		}
		else  // Copy row by row
		{
			uint8_t *srcLayerMemory = srcMemory;
			uint8_t *dstLayerMemory = dstMemory;
			for(uint32_t z = 0; z < imageExtent.depth; z++)
			{
				uint8_t *srcSliceMemory = srcLayerMemory;
				uint8_t *dstSliceMemory = dstLayerMemory;
				for(uint32_t y = 0; y < imageExtent.height; y++)
				{
					ASSERT(((bufferIsSource ? dstSliceMemory : srcSliceMemory) + copySize) < end());
					ASSERT(((bufferIsSource ? srcSliceMemory : dstSliceMemory) + copySize) < buffer->end());
					memcpy(dstSliceMemory, srcSliceMemory, copySize);
					srcSliceMemory += srcRowPitchBytes;
					dstSliceMemory += dstRowPitchBytes;
				}
				srcLayerMemory += srcSlicePitchBytes;
				dstLayerMemory += dstSlicePitchBytes;
			}
		}

		srcMemory += srcLayerSize;
		dstMemory += dstLayerSize;
	}

	if(bufferIsSource)
	{
		contentsChanged(ImageSubresourceRange(region.imageSubresource));
	}
}

void Image::copyTo(Buffer *dstBuffer, const VkBufferImageCopy2KHR &region)
{
	copy(dstBuffer, region, false);
}

void Image::copyFrom(Buffer *srcBuffer, const VkBufferImageCopy2KHR &region)
{
	copy(srcBuffer, region, true);
}

void *Image::getTexelPointer(const VkOffset3D &offset, const VkImageSubresource &subresource) const
{
	VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
	return deviceMemory->getOffsetPointer(texelOffsetBytesInStorage(offset, subresource) +
	                                      getMemoryOffset(aspect, subresource.mipLevel, subresource.arrayLayer));
}

VkExtent3D Image::imageExtentInBlocks(const VkExtent3D &extent, VkImageAspectFlagBits aspect) const
{
	VkExtent3D adjustedExtent = extent;
	Format usedFormat = getFormat(aspect);
	if(usedFormat.isCompressed())
	{
		// When using a compressed format, we use the block as the base unit, instead of the texel
		int blockWidth = usedFormat.blockWidth();
		int blockHeight = usedFormat.blockHeight();

		// Mip level allocations will round up to the next block for compressed texture
		adjustedExtent.width = ((adjustedExtent.width + blockWidth - 1) / blockWidth);
		adjustedExtent.height = ((adjustedExtent.height + blockHeight - 1) / blockHeight);
	}
	return adjustedExtent;
}

VkOffset3D Image::imageOffsetInBlocks(const VkOffset3D &offset, VkImageAspectFlagBits aspect) const
{
	VkOffset3D adjustedOffset = offset;
	Format usedFormat = getFormat(aspect);
	if(usedFormat.isCompressed())
	{
		// When using a compressed format, we use the block as the base unit, instead of the texel
		int blockWidth = usedFormat.blockWidth();
		int blockHeight = usedFormat.blockHeight();

		ASSERT(((offset.x % blockWidth) == 0) && ((offset.y % blockHeight) == 0));  // We can't offset within a block

		adjustedOffset.x /= blockWidth;
		adjustedOffset.y /= blockHeight;
	}
	return adjustedOffset;
}

VkExtent2D Image::bufferExtentInBlocks(const VkExtent2D &extent, const VkBufferImageCopy2KHR &region) const
{
	VkExtent2D adjustedExtent = extent;
	VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(region.imageSubresource.aspectMask);
	Format usedFormat = getFormat(aspect);

	if(region.bufferRowLength != 0)
	{
		adjustedExtent.width = region.bufferRowLength;

		if(usedFormat.isCompressed())
		{
			int blockWidth = usedFormat.blockWidth();
			ASSERT((adjustedExtent.width % blockWidth == 0) || (adjustedExtent.width + region.imageOffset.x == extent.width));
			adjustedExtent.width = (region.bufferRowLength + blockWidth - 1) / blockWidth;
		}
	}

	if(region.bufferImageHeight != 0)
	{
		adjustedExtent.height = region.bufferImageHeight;

		if(usedFormat.isCompressed())
		{
			int blockHeight = usedFormat.blockHeight();
			ASSERT((adjustedExtent.height % blockHeight == 0) || (adjustedExtent.height + region.imageOffset.y == extent.height));
			adjustedExtent.height = (region.bufferImageHeight + blockHeight - 1) / blockHeight;
		}
	}

	return adjustedExtent;
}

int Image::borderSize() const
{
	// We won't add a border to compressed cube textures, we'll add it when we decompress the texture
	return (isCubeCompatible() && !format.isCompressed()) ? 1 : 0;
}

VkDeviceSize Image::texelOffsetBytesInStorage(const VkOffset3D &offset, const VkImageSubresource &subresource) const
{
	VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
	VkOffset3D adjustedOffset = imageOffsetInBlocks(offset, aspect);
	int border = borderSize();
	return adjustedOffset.z * slicePitchBytes(aspect, subresource.mipLevel) +
	       (adjustedOffset.y + border) * rowPitchBytes(aspect, subresource.mipLevel) +
	       (adjustedOffset.x + border) * getFormat(aspect).bytesPerBlock();
}

VkExtent3D Image::getMipLevelExtent(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	VkExtent3D mipLevelExtent;
	mipLevelExtent.width = extent.width >> mipLevel;
	mipLevelExtent.height = extent.height >> mipLevel;
	mipLevelExtent.depth = extent.depth >> mipLevel;

	if(mipLevelExtent.width == 0) { mipLevelExtent.width = 1; }
	if(mipLevelExtent.height == 0) { mipLevelExtent.height = 1; }
	if(mipLevelExtent.depth == 0) { mipLevelExtent.depth = 1; }

	switch(aspect)
	{
	case VK_IMAGE_ASPECT_COLOR_BIT:
	case VK_IMAGE_ASPECT_DEPTH_BIT:
	case VK_IMAGE_ASPECT_STENCIL_BIT:
	case VK_IMAGE_ASPECT_PLANE_0_BIT:  // Vulkan 1.1 Table 31. Plane Format Compatibility Table: plane 0 of all defined formats is full resolution.
		break;
	case VK_IMAGE_ASPECT_PLANE_1_BIT:
	case VK_IMAGE_ASPECT_PLANE_2_BIT:
		switch(format)
		{
		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
			ASSERT(mipLevelExtent.width % 2 == 0 && mipLevelExtent.height % 2 == 0);  // Vulkan 1.1: "Images in this format must be defined with a width and height that is a multiple of two."
			// Vulkan 1.1 Table 31. Plane Format Compatibility Table:
			// Half-resolution U and V planes.
			mipLevelExtent.width /= 2;
			mipLevelExtent.height /= 2;
			break;
		default:
			UNSUPPORTED("format %d", int(format));
		}
		break;
	default:
		UNSUPPORTED("aspect %x", int(aspect));
	}

	return mipLevelExtent;
}

size_t Image::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	if(deviceMemory && deviceMemory->hasExternalImageProperties())
	{
		return deviceMemory->externalImageRowPitchBytes(aspect);
	}

	// Depth and Stencil pitch should be computed separately
	ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
	       (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));

	VkExtent3D mipLevelExtent = getMipLevelExtent(aspect, mipLevel);
	Format usedFormat = getFormat(aspect);
	if(usedFormat.isCompressed())
	{
		VkExtent3D extentInBlocks = imageExtentInBlocks(mipLevelExtent, aspect);
		return extentInBlocks.width * usedFormat.bytesPerBlock();
	}

	return usedFormat.pitchB(mipLevelExtent.width, borderSize());
}

size_t Image::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	// Depth and Stencil slice should be computed separately
	ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
	       (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));

	VkExtent3D mipLevelExtent = getMipLevelExtent(aspect, mipLevel);
	Format usedFormat = getFormat(aspect);
	if(usedFormat.isCompressed())
	{
		VkExtent3D extentInBlocks = imageExtentInBlocks(mipLevelExtent, aspect);
		return extentInBlocks.height * extentInBlocks.width * usedFormat.bytesPerBlock();
	}

	return usedFormat.sliceB(mipLevelExtent.width, mipLevelExtent.height, borderSize());
}

Format Image::getFormat(VkImageAspectFlagBits aspect) const
{
	return format.getAspectFormat(aspect);
}

bool Image::isCubeCompatible() const
{
	bool cubeCompatible = (flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
	ASSERT(!cubeCompatible || (imageType == VK_IMAGE_TYPE_2D));  // VUID-VkImageCreateInfo-flags-00949
	ASSERT(!cubeCompatible || (arrayLayers >= 6));               // VUID-VkImageCreateInfo-imageType-00954

	return cubeCompatible;
}

uint8_t *Image::end() const
{
	return reinterpret_cast<uint8_t *>(deviceMemory->getOffsetPointer(deviceMemory->getCommittedMemoryInBytes() + 1));
}

VkDeviceSize Image::getMemoryOffset(VkImageAspectFlagBits aspect) const
{
	if(deviceMemory && deviceMemory->hasExternalImageProperties())
	{
		return deviceMemory->externalImageMemoryOffset(aspect);
	}

	switch(format)
	{
	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
		if(aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
		{
			// Offset by depth buffer to get to stencil buffer
			return memoryOffset + getStorageSize(VK_IMAGE_ASPECT_DEPTH_BIT);
		}
		break;

	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		if(aspect == VK_IMAGE_ASPECT_PLANE_2_BIT)
		{
			return memoryOffset + getStorageSize(VK_IMAGE_ASPECT_PLANE_1_BIT) + getStorageSize(VK_IMAGE_ASPECT_PLANE_0_BIT);
		}
		// Fall through to 2PLANE case:
	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
		if(aspect == VK_IMAGE_ASPECT_PLANE_1_BIT)
		{
			return memoryOffset + getStorageSize(VK_IMAGE_ASPECT_PLANE_0_BIT);
		}
		else
		{
			ASSERT(aspect == VK_IMAGE_ASPECT_PLANE_0_BIT);

			return memoryOffset;
		}
		break;

	default:
		break;
	}

	return memoryOffset;
}

VkDeviceSize Image::getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	VkDeviceSize offset = getMemoryOffset(aspect);
	for(uint32_t i = 0; i < mipLevel; ++i)
	{
		offset += getMultiSampledLevelSize(aspect, i);
	}
	return offset;
}

VkDeviceSize Image::getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const
{
	return layer * getLayerOffset(aspect, mipLevel) + getMemoryOffset(aspect, mipLevel);
}

VkDeviceSize Image::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	return slicePitchBytes(aspect, mipLevel) * getMipLevelExtent(aspect, mipLevel).depth;
}

VkDeviceSize Image::getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	return getMipLevelSize(aspect, mipLevel) * samples;
}

bool Image::is3DSlice() const
{
	return ((imageType == VK_IMAGE_TYPE_3D) && (flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT));
}

VkDeviceSize Image::getLayerOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
	if(is3DSlice())
	{
		// When the VkImageSubresourceRange structure is used to select a subset of the slices of a 3D
		// image's mip level in order to create a 2D or 2D array image view of a 3D image created with
		// VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, baseArrayLayer and layerCount specify the first
		// slice index and the number of slices to include in the created image view.
		ASSERT(samples == VK_SAMPLE_COUNT_1_BIT);

		// Offset to the proper slice of the 3D image's mip level
		return slicePitchBytes(aspect, mipLevel);
	}

	return getLayerSize(aspect);
}

VkDeviceSize Image::getLayerSize(VkImageAspectFlagBits aspect) const
{
	VkDeviceSize layerSize = 0;

	for(uint32_t mipLevel = 0; mipLevel < mipLevels; ++mipLevel)
	{
		layerSize += getMultiSampledLevelSize(aspect, mipLevel);
	}

	return layerSize;
}

VkDeviceSize Image::getStorageSize(VkImageAspectFlags aspectMask) const
{
	if((aspectMask & ~(VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT |
	                   VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)) != 0)
	{
		UNSUPPORTED("aspectMask %x", int(aspectMask));
	}

	VkDeviceSize storageSize = 0;

	if(aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) storageSize += getLayerSize(VK_IMAGE_ASPECT_COLOR_BIT);
	if(aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) storageSize += getLayerSize(VK_IMAGE_ASPECT_DEPTH_BIT);
	if(aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) storageSize += getLayerSize(VK_IMAGE_ASPECT_STENCIL_BIT);
	if(aspectMask & VK_IMAGE_ASPECT_PLANE_0_BIT) storageSize += getLayerSize(VK_IMAGE_ASPECT_PLANE_0_BIT);
	if(aspectMask & VK_IMAGE_ASPECT_PLANE_1_BIT) storageSize += getLayerSize(VK_IMAGE_ASPECT_PLANE_1_BIT);
	if(aspectMask & VK_IMAGE_ASPECT_PLANE_2_BIT) storageSize += getLayerSize(VK_IMAGE_ASPECT_PLANE_2_BIT);

	return arrayLayers * storageSize;
}

const Image *Image::getSampledImage(const vk::Format &imageViewFormat) const
{
	bool isImageViewCompressed = imageViewFormat.isCompressed();
	if(decompressedImage && !isImageViewCompressed)
	{
		ASSERT(flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT);
		ASSERT(format.bytesPerBlock() == imageViewFormat.bytesPerBlock());
	}
	// If the ImageView's format is compressed, then we do need to decompress the image so that
	// it may be sampled properly by texture sampling functions, which don't support compressed
	// textures. If the ImageView's format is NOT compressed, then we reinterpret cast the
	// compressed image into the ImageView's format, so we must return the compressed image as is.
	return (decompressedImage && isImageViewCompressed) ? decompressedImage : this;
}

void Image::blitTo(Image *dstImage, const VkImageBlit2KHR &region, VkFilter filter) const
{
	prepareForSampling(ImageSubresourceRange(region.srcSubresource));
	device->getBlitter()->blit(decompressedImage ? decompressedImage : this, dstImage, region, filter);
}

void Image::copyTo(uint8_t *dst, unsigned int dstPitch) const
{
	device->getBlitter()->copy(this, dst, dstPitch);
}

void Image::resolveTo(Image *dstImage, const VkImageResolve2KHR &region) const
{
	device->getBlitter()->resolve(this, dstImage, region);
}

void Image::resolveDepthStencilTo(const ImageView *src, ImageView *dst, const VkSubpassDescriptionDepthStencilResolve &dsResolve) const
{
	device->getBlitter()->resolveDepthStencil(src, dst, dsResolve);
}

uint32_t Image::getLastLayerIndex(const VkImageSubresourceRange &subresourceRange) const
{
	return ((subresourceRange.layerCount == VK_REMAINING_ARRAY_LAYERS) ? arrayLayers : (subresourceRange.baseArrayLayer + subresourceRange.layerCount)) - 1;
}

uint32_t Image::getLastMipLevel(const VkImageSubresourceRange &subresourceRange) const
{
	return ((subresourceRange.levelCount == VK_REMAINING_MIP_LEVELS) ? mipLevels : (subresourceRange.baseMipLevel + subresourceRange.levelCount)) - 1;
}

void Image::clear(const void *pixelData, VkFormat pixelFormat, const vk::Format &viewFormat, const VkImageSubresourceRange &subresourceRange, const VkRect2D *renderArea)
{
	device->getBlitter()->clear(pixelData, pixelFormat, this, viewFormat, subresourceRange, renderArea);
}

void Image::clear(const VkClearColorValue &color, const VkImageSubresourceRange &subresourceRange)
{
	ASSERT(subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);

	clear(color.float32, format.getClearFormat(), format, subresourceRange, nullptr);
}

void Image::clear(const VkClearDepthStencilValue &color, const VkImageSubresourceRange &subresourceRange)
{
	ASSERT((subresourceRange.aspectMask & ~(VK_IMAGE_ASPECT_DEPTH_BIT |
	                                        VK_IMAGE_ASPECT_STENCIL_BIT)) == 0);

	if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
	{
		VkImageSubresourceRange depthSubresourceRange = subresourceRange;
		depthSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
		clear(&color.depth, VK_FORMAT_D32_SFLOAT, format, depthSubresourceRange, nullptr);
	}

	if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
	{
		VkImageSubresourceRange stencilSubresourceRange = subresourceRange;
		stencilSubresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
		clear(&color.stencil, VK_FORMAT_S8_UINT, format, stencilSubresourceRange, nullptr);
	}
}

void Image::clear(const VkClearValue &clearValue, const vk::Format &viewFormat, const VkRect2D &renderArea, const VkImageSubresourceRange &subresourceRange)
{
	ASSERT((subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
	       (subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
	                                       VK_IMAGE_ASPECT_STENCIL_BIT)));

	if(subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
	{
		clear(clearValue.color.float32, viewFormat.getClearFormat(), viewFormat, subresourceRange, &renderArea);
	}
	else
	{
		if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
		{
			VkImageSubresourceRange depthSubresourceRange = subresourceRange;
			depthSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
			clear(&clearValue.depthStencil.depth, VK_FORMAT_D32_SFLOAT, viewFormat, depthSubresourceRange, &renderArea);
		}

		if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
		{
			VkImageSubresourceRange stencilSubresourceRange = subresourceRange;
			stencilSubresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
			clear(&clearValue.depthStencil.stencil, VK_FORMAT_S8_UINT, viewFormat, stencilSubresourceRange, &renderArea);
		}
	}
}

bool Image::requiresPreprocessing() const
{
	return isCubeCompatible() || decompressedImage;
}

void Image::contentsChanged(const VkImageSubresourceRange &subresourceRange, ContentsChangedContext contentsChangedContext)
{
	// If this function is called after (possibly) writing to this image from a shader,
	// this must have the VK_IMAGE_USAGE_STORAGE_BIT set for the write operation to be
	// valid. Otherwise, we can't have legally written to this image, so we know we can
	// skip updating dirtyResources.
	if((contentsChangedContext == USING_STORAGE) && !(usage & VK_IMAGE_USAGE_STORAGE_BIT))
	{
		return;
	}

	// If this isn't a cube or a compressed image, we'll never need dirtyResources,
	// so we can skip updating dirtyResources
	if(!requiresPreprocessing())
	{
		return;
	}

	uint32_t lastLayer = getLastLayerIndex(subresourceRange);
	uint32_t lastMipLevel = getLastMipLevel(subresourceRange);

	VkImageSubresource subresource = {
		subresourceRange.aspectMask,
		subresourceRange.baseMipLevel,
		subresourceRange.baseArrayLayer
	};

	marl::lock lock(mutex);
	for(subresource.arrayLayer = subresourceRange.baseArrayLayer;
	    subresource.arrayLayer <= lastLayer;
	    subresource.arrayLayer++)
	{
		for(subresource.mipLevel = subresourceRange.baseMipLevel;
		    subresource.mipLevel <= lastMipLevel;
		    subresource.mipLevel++)
		{
			dirtySubresources.insert(subresource);
		}
	}
}

void Image::prepareForSampling(const VkImageSubresourceRange &subresourceRange) const
{
	// If this isn't a cube or a compressed image, there's nothing to do
	if(!requiresPreprocessing())
	{
		return;
	}

	uint32_t lastLayer = getLastLayerIndex(subresourceRange);
	uint32_t lastMipLevel = getLastMipLevel(subresourceRange);

	VkImageSubresource subresource = {
		subresourceRange.aspectMask,
		subresourceRange.baseMipLevel,
		subresourceRange.baseArrayLayer
	};

	marl::lock lock(mutex);

	if(dirtySubresources.empty())
	{
		return;
	}

	// First, decompress all relevant dirty subregions
	if(decompressedImage)
	{
		for(subresource.mipLevel = subresourceRange.baseMipLevel;
		    subresource.mipLevel <= lastMipLevel;
		    subresource.mipLevel++)
		{
			for(subresource.arrayLayer = subresourceRange.baseArrayLayer;
			    subresource.arrayLayer <= lastLayer;
			    subresource.arrayLayer++)
			{
				auto it = dirtySubresources.find(subresource);
				if(it != dirtySubresources.end())
				{
					decompress(subresource);
				}
			}
		}
	}

	// Second, update cubemap borders
	if(isCubeCompatible())
	{
		for(subresource.mipLevel = subresourceRange.baseMipLevel;
		    subresource.mipLevel <= lastMipLevel;
		    subresource.mipLevel++)
		{
			for(subresource.arrayLayer = subresourceRange.baseArrayLayer;
			    subresource.arrayLayer <= lastLayer;
			    subresource.arrayLayer++)
			{
				auto it = dirtySubresources.find(subresource);
				if(it != dirtySubresources.end())
				{
					// Since cube faces affect each other's borders, we update all 6 layers.

					subresource.arrayLayer -= subresource.arrayLayer % 6;  // Round down to a multiple of 6.

					if(subresource.arrayLayer + 5 <= lastLayer)
					{
						device->getBlitter()->updateBorders(decompressedImage ? decompressedImage : this, subresource);
					}

					subresource.arrayLayer += 5;  // Together with the loop increment, advances to the next cube.
				}
			}
		}
	}

	// Finally, mark all updated subregions clean
	for(subresource.mipLevel = subresourceRange.baseMipLevel;
	    subresource.mipLevel <= lastMipLevel;
	    subresource.mipLevel++)
	{
		for(subresource.arrayLayer = subresourceRange.baseArrayLayer;
		    subresource.arrayLayer <= lastLayer;
		    subresource.arrayLayer++)
		{
			auto it = dirtySubresources.find(subresource);
			if(it != dirtySubresources.end())
			{
				dirtySubresources.erase(it);
			}
		}
	}
}

void Image::decompress(const VkImageSubresource &subresource) const
{
	switch(format)
	{
	case VK_FORMAT_EAC_R11_UNORM_BLOCK:
	case VK_FORMAT_EAC_R11_SNORM_BLOCK:
	case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
	case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
		decodeETC2(subresource);
		break;
	case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
	case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
	case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
	case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
	case VK_FORMAT_BC2_UNORM_BLOCK:
	case VK_FORMAT_BC2_SRGB_BLOCK:
	case VK_FORMAT_BC3_UNORM_BLOCK:
	case VK_FORMAT_BC3_SRGB_BLOCK:
	case VK_FORMAT_BC4_UNORM_BLOCK:
	case VK_FORMAT_BC4_SNORM_BLOCK:
	case VK_FORMAT_BC5_UNORM_BLOCK:
	case VK_FORMAT_BC5_SNORM_BLOCK:
	case VK_FORMAT_BC6H_UFLOAT_BLOCK:
	case VK_FORMAT_BC6H_SFLOAT_BLOCK:
	case VK_FORMAT_BC7_UNORM_BLOCK:
	case VK_FORMAT_BC7_SRGB_BLOCK:
		decodeBC(subresource);
		break;
	case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
	case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
	case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
	case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
	case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
	case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
	case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
	case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
	case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
	case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
	case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
	case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
	case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
	case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
	case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
	case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
	case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
	case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
	case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
	case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
	case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
		decodeASTC(subresource);
		break;
	default:
		UNSUPPORTED("Compressed format %d", (VkFormat)format);
		break;
	}
}

void Image::decodeETC2(const VkImageSubresource &subresource) const
{
	ASSERT(decompressedImage);

	ETC_Decoder::InputType inputType = GetInputType(format);

	int bytes = decompressedImage->format.bytes();
	bool fakeAlpha = (format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK) || (format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK);
	size_t sizeToWrite = 0;

	VkExtent3D mipLevelExtent = getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresource.aspectMask), subresource.mipLevel);

	int pitchB = decompressedImage->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, subresource.mipLevel);

	if(fakeAlpha)
	{
		// To avoid overflow in case of cube textures, which are offset in memory to account for the border,
		// compute the size from the first pixel to the last pixel, excluding any padding or border before
		// the first pixel or after the last pixel.
		sizeToWrite = ((mipLevelExtent.height - 1) * pitchB) + (mipLevelExtent.width * bytes);
	}

	for(int32_t depth = 0; depth < static_cast<int32_t>(mipLevelExtent.depth); depth++)
	{
		uint8_t *source = static_cast<uint8_t *>(getTexelPointer({ 0, 0, depth }, subresource));
		uint8_t *dest = static_cast<uint8_t *>(decompressedImage->getTexelPointer({ 0, 0, depth }, subresource));

		if(fakeAlpha)
		{
			ASSERT((dest + sizeToWrite) < decompressedImage->end());
			memset(dest, 0xFF, sizeToWrite);
		}

		ETC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height,
		                    pitchB, bytes, inputType);
	}
}

void Image::decodeBC(const VkImageSubresource &subresource) const
{
	ASSERT(decompressedImage);

	int n = GetBCn(format);
	int noAlphaU = GetNoAlphaOrUnsigned(format);

	int bytes = decompressedImage->format.bytes();

	VkExtent3D mipLevelExtent = getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresource.aspectMask), subresource.mipLevel);

	int pitchB = decompressedImage->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, subresource.mipLevel);

	for(int32_t depth = 0; depth < static_cast<int32_t>(mipLevelExtent.depth); depth++)
	{
		uint8_t *source = static_cast<uint8_t *>(getTexelPointer({ 0, 0, depth }, subresource));
		uint8_t *dest = static_cast<uint8_t *>(decompressedImage->getTexelPointer({ 0, 0, depth }, subresource));

		BC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height,
		                   pitchB, bytes, n, noAlphaU);
	}
}

void Image::decodeASTC(const VkImageSubresource &subresource) const
{
	ASSERT(decompressedImage);

	int xBlockSize = format.blockWidth();
	int yBlockSize = format.blockHeight();
	int zBlockSize = 1;
	bool isUnsigned = format.isUnsignedComponent(0);

	int bytes = decompressedImage->format.bytes();

	VkExtent3D mipLevelExtent = getMipLevelExtent(static_cast<VkImageAspectFlagBits>(subresource.aspectMask), subresource.mipLevel);

	int xblocks = (mipLevelExtent.width + xBlockSize - 1) / xBlockSize;
	int yblocks = (mipLevelExtent.height + yBlockSize - 1) / yBlockSize;
	int zblocks = (zBlockSize > 1) ? (mipLevelExtent.depth + zBlockSize - 1) / zBlockSize : 1;

	if(xblocks <= 0 || yblocks <= 0 || zblocks <= 0)
	{
		return;
	}

	int pitchB = decompressedImage->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, subresource.mipLevel);
	int sliceB = decompressedImage->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, subresource.mipLevel);

	for(int32_t depth = 0; depth < static_cast<int32_t>(mipLevelExtent.depth); depth++)
	{
		uint8_t *source = static_cast<uint8_t *>(getTexelPointer({ 0, 0, depth }, subresource));
		uint8_t *dest = static_cast<uint8_t *>(decompressedImage->getTexelPointer({ 0, 0, depth }, subresource));

		ASTC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height, mipLevelExtent.depth, bytes, pitchB, sliceB,
		                     xBlockSize, yBlockSize, zBlockSize, xblocks, yblocks, zblocks, isUnsigned);
	}
}

}  // namespace vk
