// 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 "PixelShader.hpp"
#include "VertexShader.hpp"
#include "Primitive.hpp"
#include "Surface.hpp"
#include "Memory.hpp"
#include "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;
		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(pixelShaderVersion() >= 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(pixelShaderVersion() <= 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] && pixelShaderVersion() <= 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::pixelShaderVersion() const
	{
		return pixelShader ? pixelShader->getVersion() : 0x0000;
	}

	unsigned short Context::vertexShaderVersion() const
	{
		return vertexShader ? vertexShader->getVersion() : 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;
		}
	}

	int Context::colorWriteActive()
	{
		return colorWriteActive(0) | colorWriteActive(1) | colorWriteActive(2) | colorWriteActive(3);
	}

	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());
	}
}
