// Copyright 2016 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 "Sampler.hpp"

#include "Context.hpp"
#include "Pipeline/PixelRoutine.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkImage.hpp"

#include <cstring>

namespace sw
{
	FilterType Sampler::maximumTextureFilterQuality = FILTER_LINEAR;
	MipmapType Sampler::maximumMipmapFilterQuality = MIPMAP_POINT;

	Sampler::State::State()
	{
		memset(this, 0, sizeof(State));
	}

	Sampler::Sampler()
	{
		// FIXME: Mipmap::init
		static const unsigned int zero = 0x00FF00FF;

		for(int level = 0; level < MIPMAP_LEVELS; level++)
		{
			Mipmap &mipmap = texture.mipmap[level];

			memset(&mipmap, 0, sizeof(Mipmap));

			for(int face = 0; face < 6; face++)
			{
				mipmap.buffer[face] = &zero;
			}
		}

		textureFormat = VK_FORMAT_UNDEFINED;
		textureType = TEXTURE_NULL;

		textureFilter = FILTER_LINEAR;
		addressingModeU = ADDRESSING_WRAP;
		addressingModeV = ADDRESSING_WRAP;
		addressingModeW = ADDRESSING_WRAP;
		mipmapFilterState = MIPMAP_NONE;
		sRGB = false;
		gather = false;
		highPrecisionFiltering = false;
		border = 0;

		swizzleR = SWIZZLE_RED;
		swizzleG = SWIZZLE_GREEN;
		swizzleB = SWIZZLE_BLUE;
		swizzleA = SWIZZLE_ALPHA;

		compare = COMPARE_BYPASS;

		texture.LOD = 0.0f;
		exp2LOD = 1.0f;

		texture.baseLevel = 0;
		texture.maxLevel = 1000;
		texture.maxLod = MAX_TEXTURE_LOD;
		texture.minLod = 0;
	}

	Sampler::~Sampler()
	{
	}

	Sampler::State Sampler::samplerState() const
	{
		State state;

		if(textureType != TEXTURE_NULL)
		{
			state.textureType = textureType;
			state.textureFormat = textureFormat;
			state.textureFilter = getTextureFilter();
			state.addressingModeU = getAddressingModeU();
			state.addressingModeV = getAddressingModeV();
			state.addressingModeW = getAddressingModeW();
			state.mipmapFilter = mipmapFilter();
			state.sRGB = (sRGB && textureFormat.isSRGBreadable()) || textureFormat.isSRGBformat();
			state.swizzleR = swizzleR;
			state.swizzleG = swizzleG;
			state.swizzleB = swizzleB;
			state.swizzleA = swizzleA;
			state.highPrecisionFiltering = highPrecisionFiltering;
			state.compare = getCompareFunc();

			#if PERF_PROFILE
				state.compressedFormat = Surface::isCompressed(externalTextureFormat);
			#endif
		}

		return state;
	}

	void Sampler::setTextureLevel(int face, int level, vk::Image *image, TextureType type)
	{
		if(image)
		{
			Mipmap &mipmap = texture.mipmap[level];

			border = image->isCube() ? 1 : 0;
			VkImageSubresourceLayers subresourceLayers =
			{
				VK_IMAGE_ASPECT_COLOR_BIT,
				static_cast<uint32_t>(level),
				static_cast<uint32_t>(face),
				1
			};
			mipmap.buffer[face] = image->getTexelPointer({ -border, -border, 0 }, subresourceLayers);

			if(face == 0)
			{
				VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT; // FIXME: get proper aspect
				textureFormat = image->getFormat(aspect);

				VkExtent3D mipLevelExtent = image->getMipLevelExtent(level);
				int width = mipLevelExtent.width;
				int height = mipLevelExtent.height;
				int depth = mipLevelExtent.depth;
				int pitchP = image->rowPitchBytes(aspect, level);
				int sliceP = image->slicePitchBytes(aspect, level);

				if(level == 0)
				{
					texture.widthHeightLOD[0] = width * exp2LOD;
					texture.widthHeightLOD[1] = width * exp2LOD;
					texture.widthHeightLOD[2] = height * exp2LOD;
					texture.widthHeightLOD[3] = height * exp2LOD;

					texture.widthLOD[0] = width * exp2LOD;
					texture.widthLOD[1] = width * exp2LOD;
					texture.widthLOD[2] = width * exp2LOD;
					texture.widthLOD[3] = width * exp2LOD;

					texture.heightLOD[0] = height * exp2LOD;
					texture.heightLOD[1] = height * exp2LOD;
					texture.heightLOD[2] = height * exp2LOD;
					texture.heightLOD[3] = height * exp2LOD;

					texture.depthLOD[0] = depth * exp2LOD;
					texture.depthLOD[1] = depth * exp2LOD;
					texture.depthLOD[2] = depth * exp2LOD;
					texture.depthLOD[3] = depth * exp2LOD;
				}

				if(textureFormat.isFloatFormat())
				{
					mipmap.fWidth[0] = (float)width / 65536.0f;
					mipmap.fWidth[1] = (float)width / 65536.0f;
					mipmap.fWidth[2] = (float)width / 65536.0f;
					mipmap.fWidth[3] = (float)width / 65536.0f;

					mipmap.fHeight[0] = (float)height / 65536.0f;
					mipmap.fHeight[1] = (float)height / 65536.0f;
					mipmap.fHeight[2] = (float)height / 65536.0f;
					mipmap.fHeight[3] = (float)height / 65536.0f;

					mipmap.fDepth[0] = (float)depth / 65536.0f;
					mipmap.fDepth[1] = (float)depth / 65536.0f;
					mipmap.fDepth[2] = (float)depth / 65536.0f;
					mipmap.fDepth[3] = (float)depth / 65536.0f;
				}

				short halfTexelU = 0x8000 / width;
				short halfTexelV = 0x8000 / height;
				short halfTexelW = 0x8000 / depth;

				mipmap.uHalf[0] = halfTexelU;
				mipmap.uHalf[1] = halfTexelU;
				mipmap.uHalf[2] = halfTexelU;
				mipmap.uHalf[3] = halfTexelU;

				mipmap.vHalf[0] = halfTexelV;
				mipmap.vHalf[1] = halfTexelV;
				mipmap.vHalf[2] = halfTexelV;
				mipmap.vHalf[3] = halfTexelV;

				mipmap.wHalf[0] = halfTexelW;
				mipmap.wHalf[1] = halfTexelW;
				mipmap.wHalf[2] = halfTexelW;
				mipmap.wHalf[3] = halfTexelW;

				mipmap.width[0] = width;
				mipmap.width[1] = width;
				mipmap.width[2] = width;
				mipmap.width[3] = width;

				mipmap.height[0] = height;
				mipmap.height[1] = height;
				mipmap.height[2] = height;
				mipmap.height[3] = height;

				mipmap.depth[0] = depth;
				mipmap.depth[1] = depth;
				mipmap.depth[2] = depth;
				mipmap.depth[3] = depth;

				mipmap.onePitchP[0] = 1;
				mipmap.onePitchP[1] = pitchP;
				mipmap.onePitchP[2] = 1;
				mipmap.onePitchP[3] = pitchP;

				mipmap.pitchP[0] = pitchP;
				mipmap.pitchP[1] = pitchP;
				mipmap.pitchP[2] = pitchP;
				mipmap.pitchP[3] = pitchP;

				mipmap.sliceP[0] = sliceP;
				mipmap.sliceP[1] = sliceP;
				mipmap.sliceP[2] = sliceP;
				mipmap.sliceP[3] = sliceP;

				if(textureFormat.hasYuvFormat())
				{
					unsigned int YStride = pitchP;
					unsigned int YSize = YStride * height;
					unsigned int CStride = align<16>(YStride / 2);
					unsigned int CSize = CStride * height / 2;

					mipmap.buffer[1] = (byte*)mipmap.buffer[0] + YSize;
					mipmap.buffer[2] = (byte*)mipmap.buffer[1] + CSize;

					texture.mipmap[1].width[0] = width / 2;
					texture.mipmap[1].width[1] = width / 2;
					texture.mipmap[1].width[2] = width / 2;
					texture.mipmap[1].width[3] = width / 2;
					texture.mipmap[1].height[0] = height / 2;
					texture.mipmap[1].height[1] = height / 2;
					texture.mipmap[1].height[2] = height / 2;
					texture.mipmap[1].height[3] = height / 2;
					texture.mipmap[1].onePitchP[0] = 1;
					texture.mipmap[1].onePitchP[1] = CStride;
					texture.mipmap[1].onePitchP[2] = 1;
					texture.mipmap[1].onePitchP[3] = CStride;
				}
			}
		}

		textureType = type;
	}

	void Sampler::setTextureFilter(FilterType textureFilter)
	{
		this->textureFilter = (FilterType)min(textureFilter, maximumTextureFilterQuality);
	}

	void Sampler::setMipmapFilter(MipmapType mipmapFilter)
	{
		mipmapFilterState = (MipmapType)min(mipmapFilter, maximumMipmapFilterQuality);
	}

	void Sampler::setGatherEnable(bool enable)
	{
		gather = enable;
	}

	void Sampler::setAddressingModeU(AddressingMode addressingMode)
	{
		addressingModeU = addressingMode;
	}

	void Sampler::setAddressingModeV(AddressingMode addressingMode)
	{
		addressingModeV = addressingMode;
	}

	void Sampler::setAddressingModeW(AddressingMode addressingMode)
	{
		addressingModeW = addressingMode;
	}

	void Sampler::setReadSRGB(bool sRGB)
	{
		this->sRGB = sRGB;
	}

	void Sampler::setBorderColor(const Color<float> &borderColor)
	{
		// FIXME: Compact into generic function   // FIXME: Clamp
		short r = iround(0xFFFF * borderColor.r);
		short g = iround(0xFFFF * borderColor.g);
		short b = iround(0xFFFF * borderColor.b);
		short a = iround(0xFFFF * borderColor.a);

		texture.borderColor4[0][0] = texture.borderColor4[0][1] = texture.borderColor4[0][2] = texture.borderColor4[0][3] = r;
		texture.borderColor4[1][0] = texture.borderColor4[1][1] = texture.borderColor4[1][2] = texture.borderColor4[1][3] = g;
		texture.borderColor4[2][0] = texture.borderColor4[2][1] = texture.borderColor4[2][2] = texture.borderColor4[2][3] = b;
		texture.borderColor4[3][0] = texture.borderColor4[3][1] = texture.borderColor4[3][2] = texture.borderColor4[3][3] = a;

		texture.borderColorF[0][0] = texture.borderColorF[0][1] = texture.borderColorF[0][2] = texture.borderColorF[0][3] = borderColor.r;
		texture.borderColorF[1][0] = texture.borderColorF[1][1] = texture.borderColorF[1][2] = texture.borderColorF[1][3] = borderColor.g;
		texture.borderColorF[2][0] = texture.borderColorF[2][1] = texture.borderColorF[2][2] = texture.borderColorF[2][3] = borderColor.b;
		texture.borderColorF[3][0] = texture.borderColorF[3][1] = texture.borderColorF[3][2] = texture.borderColorF[3][3] = borderColor.a;
	}

	void Sampler::setMaxAnisotropy(float maxAnisotropy)
	{
		texture.maxAnisotropy = maxAnisotropy;
	}

	void Sampler::setHighPrecisionFiltering(bool highPrecisionFiltering)
	{
		this->highPrecisionFiltering = highPrecisionFiltering;
	}

	void Sampler::setSwizzleR(SwizzleType swizzleR)
	{
		this->swizzleR = swizzleR;
	}

	void Sampler::setSwizzleG(SwizzleType swizzleG)
	{
		this->swizzleG = swizzleG;
	}

	void Sampler::setSwizzleB(SwizzleType swizzleB)
	{
		this->swizzleB = swizzleB;
	}

	void Sampler::setSwizzleA(SwizzleType swizzleA)
	{
		this->swizzleA = swizzleA;
	}

	void Sampler::setCompareFunc(CompareFunc compare)
	{
		this->compare = compare;
	}

	void Sampler::setBaseLevel(int baseLevel)
	{
		texture.baseLevel = baseLevel;
	}

	void Sampler::setMaxLevel(int maxLevel)
	{
		texture.maxLevel = maxLevel;
	}

	void Sampler::setMinLod(float minLod)
	{
		texture.minLod = clamp(minLod, 0.0f, (float)(MAX_TEXTURE_LOD));
	}

	void Sampler::setMaxLod(float maxLod)
	{
		texture.maxLod = clamp(maxLod, 0.0f, (float)(MAX_TEXTURE_LOD));
	}

	void Sampler::setFilterQuality(FilterType maximumFilterQuality)
	{
		Sampler::maximumTextureFilterQuality = maximumFilterQuality;
	}

	void Sampler::setMipmapQuality(MipmapType maximumFilterQuality)
	{
		Sampler::maximumMipmapFilterQuality = maximumFilterQuality;
	}

	void Sampler::setMipmapLOD(float LOD)
	{
		texture.LOD = LOD;
		exp2LOD = exp2(LOD);
	}

	bool Sampler::hasTexture() const
	{
		return textureType != TEXTURE_NULL;
	}

	bool Sampler::hasUnsignedTexture() const
	{
		return textureFormat.isUnsignedComponent(0) &&
		       textureFormat.isUnsignedComponent(1) &&
		       textureFormat.isUnsignedComponent(2) &&
		       textureFormat.isUnsignedComponent(3);
	}

	bool Sampler::hasCubeTexture() const
	{
		return textureType == TEXTURE_CUBE;
	}

	bool Sampler::hasVolumeTexture() const
	{
		return textureType == TEXTURE_3D || textureType == TEXTURE_2D_ARRAY;
	}

	const Texture &Sampler::getTextureData()
	{
		return texture;
	}

	MipmapType Sampler::mipmapFilter() const
	{
		if(mipmapFilterState != MIPMAP_NONE)
		{
			for(int i = 1; i < MIPMAP_LEVELS; i++)
			{
				if(texture.mipmap[0].buffer[0] != texture.mipmap[i].buffer[0])
				{
					return mipmapFilterState;
				}
			}
		}

		// Only one mipmap level
		return MIPMAP_NONE;
	}

	TextureType Sampler::getTextureType() const
	{
		return textureType;
	}

	FilterType Sampler::getTextureFilter() const
	{
		// Don't filter 1x1 textures.
		if(texture.mipmap[0].width[0] == 1 && texture.mipmap[0].height[0] == 1 && texture.mipmap[0].depth[0] == 1)
		{
			if(mipmapFilter() == MIPMAP_NONE)
			{
				return FILTER_POINT;
			}
		}

		FilterType filter = textureFilter;

		if(gather && textureFormat.componentCount() == 1)
		{
			filter = FILTER_GATHER;
		}

		if(textureType != TEXTURE_2D || texture.maxAnisotropy == 1.0f)
		{
			return (FilterType)min(filter, FILTER_LINEAR);
		}

		return filter;
	}

	AddressingMode Sampler::getAddressingModeU() const
	{
		if(textureType == TEXTURE_CUBE)
		{
			return border ? ADDRESSING_SEAMLESS : ADDRESSING_CLAMP;
		}

		return addressingModeU;
	}

	AddressingMode Sampler::getAddressingModeV() const
	{
		if(textureType == TEXTURE_CUBE)
		{
			return border ? ADDRESSING_SEAMLESS : ADDRESSING_CLAMP;
		}

		return addressingModeV;
	}

	AddressingMode Sampler::getAddressingModeW() const
	{
		if(textureType == TEXTURE_2D_ARRAY ||
		   textureType == TEXTURE_2D ||
		   textureType == TEXTURE_CUBE ||
		   textureType == TEXTURE_RECTANGLE)
		{
			return ADDRESSING_LAYER;
		}

		return addressingModeW;
	}

	CompareFunc Sampler::getCompareFunc() const
	{
		if(getTextureFilter() == FILTER_GATHER)
		{
			return COMPARE_BYPASS;
		}

		return compare;
	}
}
