// 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.

#ifndef VK_IMAGE_VIEW_HPP_
#define VK_IMAGE_VIEW_HPP_

#include "VkFormat.hpp"
#include "VkImage.hpp"
#include "VkObject.hpp"

#include "System/Debug.hpp"

#include <atomic>

namespace vk {

class SamplerYcbcrConversion;

// Uniquely identifies state used by sampling routine generation.
// ID space shared by image views and buffer views.
union Identifier
{
	// Image view identifier
	Identifier(const Image *image, VkImageViewType type, VkFormat format, VkComponentMapping mapping);

	// Buffer view identifier
	Identifier(VkFormat format);

	operator uint32_t() const
	{
		static_assert(sizeof(Identifier) == sizeof(uint32_t), "Identifier must be 32-bit");
		return id;
	}

	uint32_t id = 0;

	struct
	{
		uint32_t imageViewType : 3;
		uint32_t format : 8;
		uint32_t r : 3;
		uint32_t g : 3;
		uint32_t b : 3;
		uint32_t a : 3;
	};
};

class ImageView : public Object<ImageView, VkImageView>
{
public:
	// Image usage:
	// RAW: Use the base image as is
	// SAMPLING: Image used for texture sampling
	enum Usage
	{
		RAW,
		SAMPLING
	};

	ImageView(const VkImageViewCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion);
	void destroy(const VkAllocationCallbacks *pAllocator);

	static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo *pCreateInfo);

	void clear(const VkClearValue &clearValues, VkImageAspectFlags aspectMask, const VkRect2D &renderArea);
	void clear(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkClearRect &renderArea);
	void clearWithLayerMask(const VkClearValue &clearValue, VkImageAspectFlags aspectMask, const VkRect2D &renderArea, uint32_t layerMask);
	void resolve(ImageView *resolveAttachment);
	void resolve(ImageView *resolveAttachment, int layer);
	void resolveWithLayerMask(ImageView *resolveAttachment, uint32_t layerMask);
	void resolveDepthStencil(ImageView *resolveAttachment, const VkSubpassDescriptionDepthStencilResolve &dsResolve);

	VkImageViewType getType() const { return viewType; }
	Format getFormat(Usage usage = RAW) const;
	Format getFormat(VkImageAspectFlagBits aspect) const { return image->getFormat(aspect); }
	int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
	int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
	int getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
	int layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage = RAW) const;
	VkExtent2D getMipLevelExtent(uint32_t mipLevel) const;
	VkExtent2D getMipLevelExtent(uint32_t mipLevel, VkImageAspectFlagBits aspect) const;
	int getDepthOrLayerCount(uint32_t mipLevel) const;

	int getSampleCount() const
	{
		switch(image->getSampleCountFlagBits())
		{
			case VK_SAMPLE_COUNT_1_BIT: return 1;
			case VK_SAMPLE_COUNT_4_BIT: return 4;
			default:
				UNSUPPORTED("Sample count flags %d", image->getSampleCountFlagBits());
				return 1;
		}
	}

	void *getOffsetPointer(const VkOffset3D &offset, VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer, Usage usage = RAW) const;
	bool hasDepthAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; }
	bool hasStencilAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; }

	// This function is only called from the renderer, so use the USING_STORAGE flag,
	// as it is required in order to write to an image from a shader
	void contentsChanged() { image->contentsChanged(subresourceRange, Image::USING_STORAGE); }

	void prepareForSampling() { image->prepareForSampling(subresourceRange); }

	const VkComponentMapping &getComponentMapping() const { return components; }
	const VkImageSubresourceRange &getSubresourceRange() const { return subresourceRange; }
	size_t getSizeInBytes() const { return image->getSizeInBytes(subresourceRange); }

private:
	bool imageTypesMatch(VkImageType imageType) const;
	const Image *getImage(Usage usage) const;

	Image *const image = nullptr;
	const VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D;
	const Format format = VK_FORMAT_UNDEFINED;
	const VkComponentMapping components = {};
	const VkImageSubresourceRange subresourceRange = {};

	const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;

public:
	const Identifier id;
};

VkComponentMapping ResolveIdentityMapping(VkComponentMapping mapping);
VkComponentMapping ResolveComponentMapping(VkComponentMapping mapping, vk::Format format);
VkImageSubresourceRange ResolveRemainingLevelsLayers(VkImageSubresourceRange range, const vk::Image *image);

static inline ImageView *Cast(VkImageView object)
{
	return ImageView::Cast(object);
}

}  // namespace vk

#endif  // VK_IMAGE_VIEW_HPP_
