// 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 "Surface.hpp"
#include "Pipeline/PixelRoutine.hpp"
#include "System/Debug.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;
			}
		}

		externalTextureFormat = VK_FORMAT_UNDEFINED;
		internalTextureFormat = 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 = internalTextureFormat;
			state.textureFilter = getTextureFilter();
			state.addressingModeU = getAddressingModeU();
			state.addressingModeV = getAddressingModeV();
			state.addressingModeW = getAddressingModeW();
			state.mipmapFilter = mipmapFilter();
			state.sRGB = (sRGB && Surface::isSRGBreadable(externalTextureFormat)) || Surface::isSRGBformat(internalTextureFormat);
			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, Surface *surface, TextureType type)
	{
		if(surface)
		{
			Mipmap &mipmap = texture.mipmap[level];

			border = surface->getBorder();
			mipmap.buffer[face] = surface->lockInternal(-border, -border, 0, LOCK_UNLOCKED, PRIVATE);

			if(face == 0)
			{
				externalTextureFormat = surface->getExternalFormat();
				internalTextureFormat = surface->getInternalFormat();

				int width = surface->getWidth();
				int height = surface->getHeight();
				int depth = surface->getDepth();
				int pitchP = surface->getInternalPitchP();
				int sliceP = surface->getInternalSliceP();

				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(Surface::isFloatFormat(internalTextureFormat))
				{
					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(internalTextureFormat == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)
				{
					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 Surface::isUnsignedComponent(internalTextureFormat, 0) &&
		       Surface::isUnsignedComponent(internalTextureFormat, 1) &&
		       Surface::isUnsignedComponent(internalTextureFormat, 2) &&
		       Surface::isUnsignedComponent(internalTextureFormat, 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 && Surface::componentCount(internalTextureFormat) == 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;
	}
}
