// 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 "Context.hpp"

#include "Primitive.hpp"
#include "Surface.hpp"
#include "Shader/PixelShader.hpp"
#include "Shader/VertexShader.hpp"
#include "Common/Memory.hpp"
#include "Common/Debug.hpp"

#include <string.h>

namespace sw
{
	extern bool perspectiveCorrection;

	bool halfIntegerCoordinates = false;     // Pixel centers are not at integer coordinates
	bool symmetricNormalizedDepth = false;   // [-1, 1] instead of [0, 1]
	bool booleanFaceRegister = false;
	bool fullPixelPositionRegister = false;
	bool leadingVertexFirst = false;         // Flat shading uses first vertex, else last
	bool secondaryColor = false;             // Specular lighting is applied after texturing
	bool colorsDefaultToZero = false;

	bool forceWindowed = false;
	bool quadLayoutEnabled = false;
	bool veryEarlyDepthTest = true;
	bool complementaryDepthBuffer = false;
	bool postBlendSRGB = false;
	bool exactColorRounding = false;
	TransparencyAntialiasing transparencyAntialiasing = TRANSPARENCY_NONE;
	bool forceClearRegisters = false;

	Context::Context()
	{
		init();
	}

	Context::~Context()
	{
	}

	void *Context::operator new(size_t bytes)
	{
		return allocate((unsigned int)bytes);
	}

	void Context::operator delete(void *pointer, size_t bytes)
	{
		deallocate(pointer);
	}

	bool Context::isDrawPoint(bool fillModeAware) const
	{
		switch(drawType)
		{
		case DRAW_POINTLIST:
		case DRAW_INDEXEDPOINTLIST8:
		case DRAW_INDEXEDPOINTLIST16:
		case DRAW_INDEXEDPOINTLIST32:
			return true;
		case DRAW_LINELIST:
		case DRAW_LINESTRIP:
		case DRAW_LINELOOP:
		case DRAW_INDEXEDLINELIST8:
		case DRAW_INDEXEDLINESTRIP8:
		case DRAW_INDEXEDLINELOOP8:
		case DRAW_INDEXEDLINELIST16:
		case DRAW_INDEXEDLINESTRIP16:
		case DRAW_INDEXEDLINELOOP16:
		case DRAW_INDEXEDLINELIST32:
		case DRAW_INDEXEDLINESTRIP32:
		case DRAW_INDEXEDLINELOOP32:
			return false;
		case DRAW_TRIANGLELIST:
		case DRAW_TRIANGLESTRIP:
		case DRAW_TRIANGLEFAN:
		case DRAW_INDEXEDTRIANGLELIST8:
		case DRAW_INDEXEDTRIANGLESTRIP8:
		case DRAW_INDEXEDTRIANGLEFAN8:
		case DRAW_INDEXEDTRIANGLELIST16:
		case DRAW_INDEXEDTRIANGLESTRIP16:
		case DRAW_INDEXEDTRIANGLEFAN16:
		case DRAW_INDEXEDTRIANGLELIST32:
		case DRAW_INDEXEDTRIANGLESTRIP32:
		case DRAW_INDEXEDTRIANGLEFAN32:
			return fillModeAware ? fillMode == FILL_VERTEX : false;
		case DRAW_QUADLIST:
			return false;
		default:
			ASSERT(false);
		}

		return false;
	}

	bool Context::isDrawLine(bool fillModeAware) const
	{
		switch(drawType)
		{
		case DRAW_POINTLIST:
		case DRAW_INDEXEDPOINTLIST8:
		case DRAW_INDEXEDPOINTLIST16:
		case DRAW_INDEXEDPOINTLIST32:
			return false;
		case DRAW_LINELIST:
		case DRAW_LINESTRIP:
		case DRAW_LINELOOP:
		case DRAW_INDEXEDLINELIST8:
		case DRAW_INDEXEDLINESTRIP8:
		case DRAW_INDEXEDLINELOOP8:
		case DRAW_INDEXEDLINELIST16:
		case DRAW_INDEXEDLINESTRIP16:
		case DRAW_INDEXEDLINELOOP16:
		case DRAW_INDEXEDLINELIST32:
		case DRAW_INDEXEDLINESTRIP32:
		case DRAW_INDEXEDLINELOOP32:
			return true;
		case DRAW_TRIANGLELIST:
		case DRAW_TRIANGLESTRIP:
		case DRAW_TRIANGLEFAN:
		case DRAW_INDEXEDTRIANGLELIST8:
		case DRAW_INDEXEDTRIANGLESTRIP8:
		case DRAW_INDEXEDTRIANGLEFAN8:
		case DRAW_INDEXEDTRIANGLELIST16:
		case DRAW_INDEXEDTRIANGLESTRIP16:
		case DRAW_INDEXEDTRIANGLEFAN16:
		case DRAW_INDEXEDTRIANGLELIST32:
		case DRAW_INDEXEDTRIANGLESTRIP32:
		case DRAW_INDEXEDTRIANGLEFAN32:
			return fillModeAware ? fillMode == FILL_WIREFRAME : false;
		case DRAW_QUADLIST:
			return false;
		default:
			ASSERT(false);
		}

		return false;
	}

	bool Context::isDrawTriangle(bool fillModeAware) const
	{
		switch(drawType)
		{
		case DRAW_POINTLIST:
		case DRAW_INDEXEDPOINTLIST8:
		case DRAW_INDEXEDPOINTLIST16:
		case DRAW_INDEXEDPOINTLIST32:
			return false;
		case DRAW_LINELIST:
		case DRAW_LINESTRIP:
		case DRAW_LINELOOP:
		case DRAW_INDEXEDLINELIST8:
		case DRAW_INDEXEDLINESTRIP8:
		case DRAW_INDEXEDLINELOOP8:
		case DRAW_INDEXEDLINELIST16:
		case DRAW_INDEXEDLINESTRIP16:
		case DRAW_INDEXEDLINELOOP16:
		case DRAW_INDEXEDLINELIST32:
		case DRAW_INDEXEDLINESTRIP32:
		case DRAW_INDEXEDLINELOOP32:
			return false;
		case DRAW_TRIANGLELIST:
		case DRAW_TRIANGLESTRIP:
		case DRAW_TRIANGLEFAN:
		case DRAW_INDEXEDTRIANGLELIST8:
		case DRAW_INDEXEDTRIANGLESTRIP8:
		case DRAW_INDEXEDTRIANGLEFAN8:
		case DRAW_INDEXEDTRIANGLELIST16:
		case DRAW_INDEXEDTRIANGLESTRIP16:
		case DRAW_INDEXEDTRIANGLEFAN16:
		case DRAW_INDEXEDTRIANGLELIST32:
		case DRAW_INDEXEDTRIANGLESTRIP32:
		case DRAW_INDEXEDTRIANGLEFAN32:
			return fillModeAware ? fillMode == FILL_SOLID : true;
		case DRAW_QUADLIST:
			// Quads are broken up into triangles
			return fillModeAware ? fillMode == FILL_SOLID : true;
		default:
			ASSERT(false);
		}

		return true;
	}

	void Context::init()
	{
		for(int i = 0; i < 8; i++)
		{
			textureStage[i].init(i, &sampler[i], (i >= 1) ? &textureStage[i - 1] : 0);
		}

		// Set vertex streams to null stream
		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
		{
			input[i].defaults();
		}

		fogStart = 0.0f;
		fogEnd = 1.0f;

		for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++) textureWrap[i] = 0;
		for(int i = 0; i < 8; i++) texGen[i] = TEXGEN_PASSTHRU;
		for(int i = 0; i < 8; i++) textureTransformCount[i] = 0;
		for(int i = 0; i < 8; i++) textureTransformProject[i] = false;
		textureWrapActive = false;
		localViewer = true;
		normalizeNormals = false;

		for(int i = 0; i < RENDERTARGETS; ++i)
		{
			renderTarget[i] = nullptr;
		}
		depthBuffer = nullptr;
		stencilBuffer = nullptr;

		stencilEnable = false;
		stencilCompareMode = STENCIL_ALWAYS;
		stencilReference = 0;
		stencilMask = 0xFFFFFFFF;
		stencilFailOperation = OPERATION_KEEP;
		stencilPassOperation = OPERATION_KEEP;
		stencilZFailOperation = OPERATION_KEEP;
		stencilWriteMask = 0xFFFFFFFF;

		twoSidedStencil = false;
		stencilCompareModeCCW = STENCIL_ALWAYS;
		stencilReferenceCCW = 0;
		stencilMaskCCW = 0xFFFFFFFF;
		stencilFailOperationCCW = OPERATION_KEEP;
		stencilPassOperationCCW = OPERATION_KEEP;
		stencilZFailOperationCCW = OPERATION_KEEP;
		stencilWriteMaskCCW = 0xFFFFFFFF;

		setGlobalMipmapBias(0);

		lightingEnable = true;
		specularEnable = false;
		for(int i = 0; i < 8; i++) lightEnable[i] = false;
		for(int i = 0; i < 8; i++) worldLightPosition[i] = 0;

		alphaCompareMode = ALPHA_ALWAYS;
		alphaTestEnable = false;
		fillMode = FILL_SOLID;
		shadingMode = SHADING_GOURAUD;

		rasterizerDiscard = false;

		depthCompareMode = DEPTH_LESS;
		depthBufferEnable = true;
		depthWriteEnable = true;

		alphaBlendEnable = false;
		sourceBlendFactorState = BLEND_ONE;
		destBlendFactorState = BLEND_ZERO;
		blendOperationState = BLENDOP_ADD;

		separateAlphaBlendEnable = false;
		sourceBlendFactorStateAlpha = BLEND_ONE;
		destBlendFactorStateAlpha = BLEND_ZERO;
		blendOperationStateAlpha = BLENDOP_ADD;

		cullMode = CULL_CLOCKWISE;
		frontFacingCCW = true;
		alphaReference = 0.0f;

		depthBias = 0.0f;
		slopeDepthBias = 0.0f;

		for(int i = 0; i < RENDERTARGETS; i++)
		{
			colorWriteMask[i] = 0x0000000F;
		}

		ambientMaterialSource = MATERIAL_MATERIAL;
		diffuseMaterialSource = MATERIAL_COLOR1;
		specularMaterialSource = MATERIAL_COLOR2;
		emissiveMaterialSource = MATERIAL_MATERIAL;
		colorVertexEnable = true;

		fogEnable = false;
		pixelFogMode = FOG_NONE;
		vertexFogMode = FOG_NONE;
		wBasedFog = false;
		rangeFogEnable = false;

		indexedVertexBlendEnable = false;
		vertexBlendMatrixCount = 0;

		pixelShader = 0;
		vertexShader = 0;

		instanceID = 0;

		occlusionEnabled = false;
		transformFeedbackQueryEnabled = false;
		transformFeedbackEnabled = 0;

		pointSpriteEnable = false;
		pointScaleEnable = false;
		lineWidth = 1.0f;

		writeSRGB = false;
		sampleMask = 0xFFFFFFFF;

		colorLogicOpEnabled = false;
		logicalOperation = LOGICALOP_COPY;
	}

	const float &Context::exp2Bias()
	{
		return bias;
	}

	const Point &Context::getLightPosition(int light)
	{
		return worldLightPosition[light];
	}

	void Context::setGlobalMipmapBias(float bias)
	{
		this->bias = exp2(bias + 0.5f);
	}

	void Context::setLightingEnable(bool lightingEnable)
	{
		this->lightingEnable = lightingEnable;
	}

	void Context::setSpecularEnable(bool specularEnable)
	{
		Context::specularEnable = specularEnable;
	}

	void Context::setLightEnable(int light, bool lightEnable)
	{
		Context::lightEnable[light] = lightEnable;
	}

	void Context::setLightPosition(int light, Point worldLightPosition)
	{
		Context::worldLightPosition[light] = worldLightPosition;
	}

	void Context::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
	{
		Context::ambientMaterialSource = ambientMaterialSource;
	}

	void Context::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
	{
		Context::diffuseMaterialSource = diffuseMaterialSource;
	}

	void Context::setSpecularMaterialSource(MaterialSource specularMaterialSource)
	{
		Context::specularMaterialSource = specularMaterialSource;
	}

	void Context::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
	{
		Context::emissiveMaterialSource = emissiveMaterialSource;
	}

	void Context::setPointSpriteEnable(bool pointSpriteEnable)
	{
		Context::pointSpriteEnable = pointSpriteEnable;
	}

	void Context::setPointScaleEnable(bool pointScaleEnable)
	{
		Context::pointScaleEnable = pointScaleEnable;
	}

	bool Context::setDepthBufferEnable(bool depthBufferEnable)
	{
		bool modified = (Context::depthBufferEnable != depthBufferEnable);
		Context::depthBufferEnable = depthBufferEnable;
		return modified;
	}

	bool Context::setAlphaBlendEnable(bool alphaBlendEnable)
	{
		bool modified = (Context::alphaBlendEnable != alphaBlendEnable);
		Context::alphaBlendEnable = alphaBlendEnable;
		return modified;
	}

	bool Context::setSourceBlendFactor(BlendFactor sourceBlendFactor)
	{
		bool modified = (Context::sourceBlendFactorState != sourceBlendFactor);
		Context::sourceBlendFactorState = sourceBlendFactor;
		return modified;
	}

	bool Context::setDestBlendFactor(BlendFactor destBlendFactor)
	{
		bool modified = (Context::destBlendFactorState != destBlendFactor);
		Context::destBlendFactorState = destBlendFactor;
		return modified;
	}

	bool Context::setBlendOperation(BlendOperation blendOperation)
	{
		bool modified = (Context::blendOperationState != blendOperation);
		Context::blendOperationState = blendOperation;
		return modified;
	}

	bool Context::setSeparateAlphaBlendEnable(bool separateAlphaBlendEnable)
	{
		bool modified = (Context::separateAlphaBlendEnable != separateAlphaBlendEnable);
		Context::separateAlphaBlendEnable = separateAlphaBlendEnable;
		return modified;
	}

	bool Context::setSourceBlendFactorAlpha(BlendFactor sourceBlendFactorAlpha)
	{
		bool modified = (Context::sourceBlendFactorStateAlpha != sourceBlendFactorAlpha);
		Context::sourceBlendFactorStateAlpha = sourceBlendFactorAlpha;
		return modified;
	}

	bool Context::setDestBlendFactorAlpha(BlendFactor destBlendFactorAlpha)
	{
		bool modified = (Context::destBlendFactorStateAlpha != destBlendFactorAlpha);
		Context::destBlendFactorStateAlpha = destBlendFactorAlpha;
		return modified;
	}

	bool Context::setBlendOperationAlpha(BlendOperation blendOperationAlpha)
	{
		bool modified = (Context::blendOperationStateAlpha != blendOperationAlpha);
		Context::blendOperationStateAlpha = blendOperationAlpha;
		return modified;
	}

	bool Context::setColorWriteMask(int index, int colorWriteMask)
	{
		bool modified = (Context::colorWriteMask[index] != colorWriteMask);
		Context::colorWriteMask[index] = colorWriteMask;
		return modified;
	}

	bool Context::setWriteSRGB(bool sRGB)
	{
		bool modified = (Context::writeSRGB != sRGB);
		Context::writeSRGB = sRGB;
		return modified;
	}

	bool Context::setColorLogicOpEnabled(bool enabled)
	{
		bool modified = (Context::colorLogicOpEnabled != enabled);
		Context::colorLogicOpEnabled = enabled;
		return modified;
	}

	bool Context::setLogicalOperation(LogicalOperation logicalOperation)
	{
		bool modified = (Context::logicalOperation != logicalOperation);
		Context::logicalOperation = logicalOperation;
		return modified;
	}

	void Context::setColorVertexEnable(bool colorVertexEnable)
	{
		Context::colorVertexEnable = colorVertexEnable;
	}

	bool Context::fogActive()
	{
		if(!colorUsed()) return false;

		if(pixelShaderModel() >= 0x0300) return false;

		return fogEnable;
	}

	bool Context::pointSizeActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return isDrawPoint(true) && (input[PointSize] || (!preTransformed && pointScaleActive()));
	}

	FogMode Context::pixelFogActive()
	{
		if(fogActive())
		{
			return pixelFogMode;
		}

		return FOG_NONE;
	}

	bool Context::depthWriteActive()
	{
		if(!depthBufferActive()) return false;

		return depthWriteEnable;
	}

	bool Context::alphaTestActive()
	{
		if(transparencyAntialiasing != TRANSPARENCY_NONE) return true;
		if(!alphaTestEnable) return false;
		if(alphaCompareMode == ALPHA_ALWAYS) return false;
		if(alphaReference == 0.0f && alphaCompareMode == ALPHA_GREATEREQUAL) return false;

		return true;
	}

	bool Context::depthBufferActive()
	{
		return depthBuffer && depthBufferEnable;
	}

	bool Context::stencilActive()
	{
		return stencilBuffer && stencilEnable;
	}

	bool Context::vertexLightingActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return lightingEnable && !preTransformed;
	}

	bool Context::texCoordActive(int coordinate, int component)
	{
		bool hasTexture = pointSpriteActive();

		if(vertexShader)
		{
			if(!preTransformed)
			{
				if(vertexShader->getOutput(T0 + coordinate, component).usage == Shader::USAGE_TEXCOORD)
				{
					hasTexture = true;
				}
			}
			else
			{
				hasTexture = true;   // FIXME: Check vertex buffer streams
			}
		}
		else
		{
			switch(texGen[coordinate])
			{
			case TEXGEN_NONE:
				hasTexture = true;
				break;
			case TEXGEN_PASSTHRU:
				hasTexture = hasTexture || (component < input[TexCoord0 + textureStage[coordinate].texCoordIndex].count);
				break;
			case TEXGEN_NORMAL:
				hasTexture = hasTexture || (component <= 2);
				break;
			case TEXGEN_POSITION:
				hasTexture = hasTexture || (component <= 2);
				break;
			case TEXGEN_REFLECTION:
				hasTexture = hasTexture || (component <= 2);
				break;
			case TEXGEN_SPHEREMAP:
				hasTexture = hasTexture || (component <= 1);
				break;
			default:
				ASSERT(false);
			}
		}

		bool project = isProjectionComponent(coordinate, component);
		bool usesTexture = false;

		if(pixelShader)
		{
			usesTexture = pixelShader->usesTexture(coordinate, component) || project;
		}
		else
		{
			usesTexture = textureStage[coordinate].usesTexture() || project;
		}

		return hasTexture && usesTexture;
	}

	bool Context::texCoordActive(int coordinate)
	{
		return texCoordActive(coordinate, 0) ||
		       texCoordActive(coordinate, 1) ||
		       texCoordActive(coordinate, 2) ||
		       texCoordActive(coordinate, 3);
	}

	bool Context::isProjectionComponent(unsigned int coordinate, int component)
	{
		if(pixelShaderModel() <= 0x0103 && coordinate < 8 && textureTransformProject[coordinate])
		{
			if(textureTransformCount[coordinate] == 2)
			{
				if(component == 1) return true;
			}
			else if(textureTransformCount[coordinate] == 3)
			{
				if(component == 2) return true;
			}
			else if(textureTransformCount[coordinate] == 4 || textureTransformCount[coordinate] == 0)
			{
				if(component == 3) return true;
			}
		}

		return false;
	}

	bool Context::vertexSpecularActive()
	{
		return vertexLightingActive() && specularEnable && vertexNormalActive();
	}

	bool Context::vertexNormalActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return input[Normal];
	}

	bool Context::vertexLightActive(int i)
	{
		if(vertexShader)
		{
			return false;
		}

		return lightingEnable && lightEnable[i];
	}

	MaterialSource Context::vertexDiffuseMaterialSourceActive()
	{
		if(vertexShader)
		{
			return MATERIAL_MATERIAL;
		}

		if(diffuseMaterialSource == MATERIAL_MATERIAL || !colorVertexEnable ||
		   (diffuseMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
		   (diffuseMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
		{
			return MATERIAL_MATERIAL;
		}

		return diffuseMaterialSource;
	}

	MaterialSource Context::vertexSpecularMaterialSourceActive()
	{
		if(vertexShader)
		{
			return MATERIAL_MATERIAL;
		}

		if(!colorVertexEnable ||
		   (specularMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
		   (specularMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
		{
			return MATERIAL_MATERIAL;
		}

		return specularMaterialSource;
	}

	MaterialSource Context::vertexAmbientMaterialSourceActive()
	{
		if(vertexShader)
		{
			return MATERIAL_MATERIAL;
		}

		if(!colorVertexEnable ||
		   (ambientMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
		   (ambientMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
		{
			return MATERIAL_MATERIAL;
		}

		return ambientMaterialSource;
	}

	MaterialSource Context::vertexEmissiveMaterialSourceActive()
	{
		if(vertexShader)
		{
			return MATERIAL_MATERIAL;
		}

		if(!colorVertexEnable ||
		   (emissiveMaterialSource == MATERIAL_COLOR1 && !input[Color0]) ||
		   (emissiveMaterialSource == MATERIAL_COLOR2 && !input[Color1]))
		{
			return MATERIAL_MATERIAL;
		}

		return emissiveMaterialSource;
	}

	bool Context::pointSpriteActive()
	{
		return isDrawPoint(true) && pointSpriteEnable;
	}

	bool Context::pointScaleActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return isDrawPoint(true) && pointScaleEnable;
	}

	bool Context::alphaBlendActive()
	{
		if(!alphaBlendEnable)
		{
			return false;
		}

		if(!colorUsed())
		{
			return false;
		}

		bool colorBlend = !(blendOperation() == BLENDOP_SOURCE && sourceBlendFactor() == BLEND_ONE);
		bool alphaBlend = separateAlphaBlendEnable ? !(blendOperationAlpha() == BLENDOP_SOURCE && sourceBlendFactorAlpha() == BLEND_ONE) : colorBlend;

		return colorBlend || alphaBlend;
	}

	LogicalOperation Context::colorLogicOp()
	{
		return colorLogicOpEnabled ? logicalOperation : LOGICALOP_COPY;
	}

	BlendFactor Context::sourceBlendFactor()
	{
		if(!alphaBlendEnable) return BLEND_ONE;

		switch(blendOperationState)
		{
		case BLENDOP_ADD:
		case BLENDOP_SUB:
		case BLENDOP_INVSUB:
			return sourceBlendFactorState;
		case BLENDOP_MIN:
			return BLEND_ONE;
		case BLENDOP_MAX:
			return BLEND_ONE;
		default:
			ASSERT(false);
		}

		return sourceBlendFactorState;
	}

	BlendFactor Context::destBlendFactor()
	{
		if(!alphaBlendEnable) return BLEND_ZERO;

		switch(blendOperationState)
		{
		case BLENDOP_ADD:
		case BLENDOP_SUB:
		case BLENDOP_INVSUB:
			return destBlendFactorState;
		case BLENDOP_MIN:
			return BLEND_ONE;
		case BLENDOP_MAX:
			return BLEND_ONE;
		default:
			ASSERT(false);
		}

		return destBlendFactorState;
	}

	BlendOperation Context::blendOperation()
	{
		if(!alphaBlendEnable) return BLENDOP_SOURCE;

		switch(blendOperationState)
		{
		case BLENDOP_ADD:
			if(sourceBlendFactor() == BLEND_ZERO)
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_NULL;
				}
				else
				{
					return BLENDOP_DEST;
				}
			}
			else if(sourceBlendFactor() == BLEND_ONE)
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_SOURCE;
				}
				else
				{
					return BLENDOP_ADD;
				}
			}
			else
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_SOURCE;
				}
				else
				{
					return BLENDOP_ADD;
				}
			}
		case BLENDOP_SUB:
			if(sourceBlendFactor() == BLEND_ZERO)
			{
				return BLENDOP_NULL;   // Negative, clamped to zero
			}
			else if(sourceBlendFactor() == BLEND_ONE)
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_SOURCE;
				}
				else
				{
					return BLENDOP_SUB;
				}
			}
			else
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_SOURCE;
				}
				else
				{
					return BLENDOP_SUB;
				}
			}
		case BLENDOP_INVSUB:
			if(sourceBlendFactor() == BLEND_ZERO)
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_NULL;
				}
				else
				{
					return BLENDOP_DEST;
				}
			}
			else if(sourceBlendFactor() == BLEND_ONE)
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_NULL;   // Negative, clamped to zero
				}
				else
				{
					return BLENDOP_INVSUB;
				}
			}
			else
			{
				if(destBlendFactor() == BLEND_ZERO)
				{
					return BLENDOP_NULL;   // Negative, clamped to zero
				}
				else
				{
					return BLENDOP_INVSUB;
				}
			}
		case BLENDOP_MIN:
			return BLENDOP_MIN;
		case BLENDOP_MAX:
			return BLENDOP_MAX;
		default:
			ASSERT(false);
		}

		return blendOperationState;
	}

	BlendFactor Context::sourceBlendFactorAlpha()
	{
		if(!separateAlphaBlendEnable)
		{
			return sourceBlendFactor();
		}
		else
		{
			switch(blendOperationStateAlpha)
			{
			case BLENDOP_ADD:
			case BLENDOP_SUB:
			case BLENDOP_INVSUB:
				return sourceBlendFactorStateAlpha;
			case BLENDOP_MIN:
				return BLEND_ONE;
			case BLENDOP_MAX:
				return BLEND_ONE;
			default:
				ASSERT(false);
			}

			return sourceBlendFactorStateAlpha;
		}
	}

	BlendFactor Context::destBlendFactorAlpha()
	{
		if(!separateAlphaBlendEnable)
		{
			return destBlendFactor();
		}
		else
		{
			switch(blendOperationStateAlpha)
			{
			case BLENDOP_ADD:
			case BLENDOP_SUB:
			case BLENDOP_INVSUB:
				return destBlendFactorStateAlpha;
			case BLENDOP_MIN:
				return BLEND_ONE;
			case BLENDOP_MAX:
				return BLEND_ONE;
			default:
				ASSERT(false);
			}

			return destBlendFactorStateAlpha;
		}
	}

	BlendOperation Context::blendOperationAlpha()
	{
		if(!separateAlphaBlendEnable)
		{
			return blendOperation();
		}
		else
		{
			switch(blendOperationStateAlpha)
			{
			case BLENDOP_ADD:
				if(sourceBlendFactorAlpha() == BLEND_ZERO)
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_NULL;
					}
					else
					{
						return BLENDOP_DEST;
					}
				}
				else if(sourceBlendFactorAlpha() == BLEND_ONE)
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_SOURCE;
					}
					else
					{
						return BLENDOP_ADD;
					}
				}
				else
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_SOURCE;
					}
					else
					{
						return BLENDOP_ADD;
					}
				}
			case BLENDOP_SUB:
				if(sourceBlendFactorAlpha() == BLEND_ZERO)
				{
					return BLENDOP_NULL;   // Negative, clamped to zero
				}
				else if(sourceBlendFactorAlpha() == BLEND_ONE)
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_SOURCE;
					}
					else
					{
						return BLENDOP_SUB;
					}
				}
				else
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_SOURCE;
					}
					else
					{
						return BLENDOP_SUB;
					}
				}
			case BLENDOP_INVSUB:
				if(sourceBlendFactorAlpha() == BLEND_ZERO)
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_NULL;
					}
					else
					{
						return BLENDOP_DEST;
					}
				}
				else if(sourceBlendFactorAlpha() == BLEND_ONE)
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_NULL;   // Negative, clamped to zero
					}
					else
					{
						return BLENDOP_INVSUB;
					}
				}
				else
				{
					if(destBlendFactorAlpha() == BLEND_ZERO)
					{
						return BLENDOP_NULL;   // Negative, clamped to zero
					}
					else
					{
						return BLENDOP_INVSUB;
					}
				}
			case BLENDOP_MIN:
				return BLENDOP_MIN;
			case BLENDOP_MAX:
				return BLENDOP_MAX;
			default:
				ASSERT(false);
			}

			return blendOperationStateAlpha;
		}
	}

	bool Context::indexedVertexBlendActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return indexedVertexBlendEnable;
	}

	int Context::vertexBlendMatrixCountActive()
	{
		if(vertexShader)
		{
			return 0;
		}

		return vertexBlendMatrixCount;
	}

	bool Context::localViewerActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return localViewer;
	}

	bool Context::normalizeNormalsActive()
	{
		if(vertexShader)
		{
			return false;
		}

		return normalizeNormals;
	}

	FogMode Context::vertexFogModeActive()
	{
		if(vertexShader || !fogActive())
		{
			return FOG_NONE;
		}

		return vertexFogMode;
	}

	bool Context::rangeFogActive()
	{
		if(vertexShader || !fogActive())
		{
			return false;
		}

		return rangeFogEnable;
	}

	TexGen Context::texGenActive(int stage)
	{
		if(vertexShader || !texCoordActive(stage))
		{
			return TEXGEN_PASSTHRU;
		}

		return texGen[stage];
	}

	int Context::textureTransformCountActive(int stage)
	{
		if(vertexShader || !texCoordActive(stage))
		{
			return 0;
		}

		return textureTransformCount[stage];
	}

	int Context::texCoordIndexActive(int stage)
	{
		if(vertexShader || !texCoordActive(stage))
		{
			return stage;
		}

		return textureStage[stage].texCoordIndex;
	}

	bool Context::perspectiveActive()
	{
		if(!colorUsed())
		{
			return false;
		}

		if(!perspectiveCorrection)
		{
			return false;
		}

		if(isDrawPoint(true))
		{
			return false;
		}

		return true;
	}

	bool Context::diffuseUsed()
	{
		return diffuseUsed(0) || diffuseUsed(1) || diffuseUsed(2) || diffuseUsed(3);
	}

	bool Context::diffuseUsed(int component)
	{
		if(!colorUsed())
		{
			return false;
		}

		if(pixelShader)
		{
			return pixelShader->usesDiffuse(component);
		}

		// Directly using the diffuse input color
		for(int i = 0; i < 8; i++)
		{
			if(textureStage[i].isStageDisabled())
			{
				break;
			}

			if(textureStage[i].usesDiffuse())
			{
				return true;
			}
		}

		// Using the current color (initialized to diffuse) before it's overwritten
		for(int i = 0; i < 8; i++)
		{
			if(textureStage[i].usesCurrent() || textureStage[i].isStageDisabled())   // Current color contains diffuse before being overwritten
			{
				return true;
			}

			if(textureStage[i].writesCurrent())
			{
				return false;
			}
		}

		return true;
	}

	bool Context::diffuseActive()
	{
		return diffuseActive(0) || diffuseActive(1) || diffuseActive(2) || diffuseActive(3);
	}

	bool Context::diffuseActive(int component)
	{
		if(!colorUsed())
		{
			return false;
		}

		// Vertex processor provides diffuse component
		bool vertexDiffuse;

		if(vertexShader)
		{
			vertexDiffuse = vertexShader->getOutput(C0, component).active();
		}
		else if(!preTransformed)
		{
			vertexDiffuse = input[Color0] || lightingEnable;
		}
		else
		{
			vertexDiffuse = input[Color0];
		}

		// Pixel processor requires diffuse component
		bool pixelDiffuse = diffuseUsed(component);

		return vertexDiffuse && pixelDiffuse;
	}

	bool Context::specularUsed()
	{
		return Context::specularUsed(0) || Context::specularUsed(1) || Context::specularUsed(2) || Context::specularUsed(3);
	}

	bool Context::specularUsed(int component)
	{
		if(!colorUsed())
		{
			return false;
		}

		if(pixelShader)
		{
			return pixelShader->usesSpecular(component);
		}

		bool pixelSpecular = specularEnable;

		for(int i = 0; i < 8; i++)
		{
			if(textureStage[i].isStageDisabled()) break;

			pixelSpecular = pixelSpecular || textureStage[i].usesSpecular();
		}

		return pixelSpecular;
	}

	bool Context::specularActive()
	{
		return specularActive(0) || specularActive(1) || specularActive(2) || specularActive(3);
	}

	bool Context::specularActive(int component)
	{
		if(!colorUsed())
		{
			return false;
		}

		// Vertex processor provides specular component
		bool vertexSpecular;

		if(!vertexShader)
		{
			vertexSpecular = input[Color1] || (lightingEnable && specularEnable);
		}
		else
		{
			vertexSpecular = vertexShader->getOutput(C1, component).active();
		}

		// Pixel processor requires specular component
		bool pixelSpecular = specularUsed(component);

		return vertexSpecular && pixelSpecular;
	}

	bool Context::colorActive(int color, int component)
	{
		if(color == 0)
		{
			return diffuseActive(component);
		}
		else
		{
			return specularActive(component);
		}
	}

	bool Context::textureActive()
	{
		for(int i = 0; i < 8; i++)
		{
			if(textureActive(i))
			{
				return true;
			}
		}

		return false;
	}

	bool Context::textureActive(int coordinate)
	{
		return textureActive(coordinate, 0) || textureActive(coordinate, 1) || textureActive(coordinate, 2) || textureActive(coordinate, 3);
	}

	bool Context::textureActive(int coordinate, int component)
	{
		if(!colorUsed())
		{
			return false;
		}

		if(!texCoordActive(coordinate, component))
		{
			return false;
		}

		if(textureTransformProject[coordinate] && pixelShaderModel() <= 0x0103)
		{
			if(textureTransformCount[coordinate] == 2)
			{
				if(component == 1) return true;
			}
			else if(textureTransformCount[coordinate] == 3)
			{
				if(component == 2) return true;
			}
			else if(textureTransformCount[coordinate] == 4 || textureTransformCount[coordinate] == 0)
			{
				if(component == 3) return true;
			}
		}

		if(!pixelShader)
		{
			bool texture = textureStage[coordinate].usesTexture();
			bool cube = sampler[coordinate].hasCubeTexture();
			bool volume = sampler[coordinate].hasVolumeTexture();

			if(texture)
			{
				for(int i = coordinate; i >= 0; i--)
				{
					if(textureStage[i].stageOperation == TextureStage::STAGE_DISABLE)
					{
						return false;
					}
				}
			}

			switch(component)
			{
			case 0:
				return texture;
			case 1:
				return texture;
			case 2:
				return (texture && (cube || volume));
			case 3:
				return false;
			}
		}
		else
		{
			return pixelShader->usesTexture(coordinate, component);
		}

		return false;
	}

	unsigned short Context::pixelShaderModel() const
	{
		return pixelShader ? pixelShader->getShaderModel() : 0x0000;
	}

	unsigned short Context::vertexShaderModel() const
	{
		return vertexShader ? vertexShader->getShaderModel() : 0x0000;
	}

	int Context::getMultiSampleCount() const
	{
		return renderTarget[0] ? renderTarget[0]->getMultiSampleCount() : 1;
	}

	int Context::getSuperSampleCount() const
	{
		return renderTarget[0] ? renderTarget[0]->getSuperSampleCount() : 1;
	}

	Format Context::renderTargetInternalFormat(int index)
	{
		if(renderTarget[index])
		{
			return renderTarget[index]->getInternalFormat();
		}
		else
		{
			return FORMAT_NULL;
		}
	}

	bool Context::colorWriteActive()
	{
		for (int i = 0; i < RENDERTARGETS; i++)
		{
			if (colorWriteActive(i))
			{
				return true;
			}
		}

		return false;
	}

	int Context::colorWriteActive(int index)
	{
		if(!renderTarget[index] || renderTarget[index]->getInternalFormat() == FORMAT_NULL)
		{
			return 0;
		}

		if(blendOperation() == BLENDOP_DEST && destBlendFactor() == BLEND_ONE &&
		   (!separateAlphaBlendEnable || (blendOperationAlpha() == BLENDOP_DEST && destBlendFactorAlpha() == BLEND_ONE)))
		{
			return 0;
		}

		return colorWriteMask[index];
	}

	bool Context::colorUsed()
	{
		return colorWriteActive() || alphaTestActive() || (pixelShader && pixelShader->containsKill());
	}
}
