// 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_SAMPLER_HPP_
#define VK_SAMPLER_HPP_

#include "VkDevice.hpp"
#include "VkImageView.hpp"  // For ResolveIdentityMapping()
#include "Device/Config.hpp"
#include "System/Math.hpp"

#include <atomic>

namespace vk {

class Sampler : public Object<Sampler, VkSampler>
{
public:
	Sampler(const VkSamplerCreateInfo *pCreateInfo, void *mem, const vk::SamplerYcbcrConversion *ycbcrConversion)
	    : magFilter(pCreateInfo->magFilter)
	    , minFilter(pCreateInfo->minFilter)
	    , mipmapMode(pCreateInfo->mipmapMode)
	    , addressModeU(pCreateInfo->addressModeU)
	    , addressModeV(pCreateInfo->addressModeV)
	    , addressModeW(pCreateInfo->addressModeW)
	    , mipLodBias(pCreateInfo->mipLodBias)
	    , anisotropyEnable(pCreateInfo->anisotropyEnable)
	    , maxAnisotropy(pCreateInfo->maxAnisotropy)
	    , compareEnable(pCreateInfo->compareEnable)
	    , compareOp(pCreateInfo->compareOp)
	    , minLod(ClampLod(pCreateInfo->minLod))
	    , maxLod(ClampLod(pCreateInfo->maxLod))
	    , borderColor(pCreateInfo->borderColor)
	    , unnormalizedCoordinates(pCreateInfo->unnormalizedCoordinates)
	    , ycbcrConversion(ycbcrConversion)
	{
	}

	static size_t ComputeRequiredAllocationSize(const VkSamplerCreateInfo *pCreateInfo)
	{
		return 0;
	}

	// Prevents accessing mipmap levels out of range.
	static float ClampLod(float lod)
	{
		return sw::clamp(lod, 0.0f, (float)(sw::MAX_TEXTURE_LOD));
	}

	const uint32_t id = nextID++;
	const VkFilter magFilter = VK_FILTER_NEAREST;
	const VkFilter minFilter = VK_FILTER_NEAREST;
	const VkSamplerMipmapMode mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
	const VkSamplerAddressMode addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
	const VkSamplerAddressMode addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
	const VkSamplerAddressMode addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
	const float mipLodBias = 0.0f;
	const VkBool32 anisotropyEnable = VK_FALSE;
	const float maxAnisotropy = 0.0f;
	const VkBool32 compareEnable = VK_FALSE;
	const VkCompareOp compareOp = VK_COMPARE_OP_NEVER;
	const float minLod = 0.0f;
	const float maxLod = 0.0f;
	const VkBorderColor borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
	const VkBool32 unnormalizedCoordinates = VK_FALSE;

	const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;

private:
	static std::atomic<uint32_t> nextID;
};

class SamplerYcbcrConversion : public Object<SamplerYcbcrConversion, VkSamplerYcbcrConversion>
{
public:
	SamplerYcbcrConversion(const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, void *mem)
	    : format(pCreateInfo->format)
	    , ycbcrModel(pCreateInfo->ycbcrModel)
	    , ycbcrRange(pCreateInfo->ycbcrRange)
	    , components(ResolveIdentityMapping(pCreateInfo->components))
	    , xChromaOffset(pCreateInfo->xChromaOffset)
	    , yChromaOffset(pCreateInfo->yChromaOffset)
	    , chromaFilter(pCreateInfo->chromaFilter)
	    , forceExplicitReconstruction(pCreateInfo->forceExplicitReconstruction)
	{
	}

	~SamplerYcbcrConversion() = default;

	static size_t ComputeRequiredAllocationSize(const VkSamplerYcbcrConversionCreateInfo *pCreateInfo)
	{
		return 0;
	}

	const VkFormat format = VK_FORMAT_UNDEFINED;
	const VkSamplerYcbcrModelConversion ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
	const VkSamplerYcbcrRange ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
	const VkComponentMapping components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
	const VkChromaLocation xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
	const VkChromaLocation yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
	const VkFilter chromaFilter = VK_FILTER_NEAREST;
	const VkBool32 forceExplicitReconstruction = VK_FALSE;
};

static inline Sampler *Cast(VkSampler object)
{
	return Sampler::Cast(object);
}

static inline SamplerYcbcrConversion *Cast(VkSamplerYcbcrConversion object)
{
	return SamplerYcbcrConversion::Cast(object);
}

}  // namespace vk

#endif  // VK_SAMPLER_HPP_