/*-------------------------------------------------------------------------
 * drawElements Quality Program Reference Renderer
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Reference implementation for per-fragment operations.
 *//*--------------------------------------------------------------------*/

#include "rrFragmentOperations.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTextureUtil.hpp"
#include <limits>

using tcu::IVec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec4;
using tcu::UVec4;
using tcu::min;
using tcu::max;
using tcu::clamp;
using de::min;
using de::max;
using de::clamp;

namespace rr
{

// Return oldValue with the bits indicated by mask replaced by corresponding bits of newValue.
static inline int maskedBitReplace (int oldValue, int newValue, deUint32 mask)
{
	return (oldValue & ~mask) | (newValue & mask);
}

static inline bool isInsideRect (const IVec2& point, const WindowRectangle& rect)
{
	return de::inBounds(point.x(), rect.left,		rect.left + rect.width) &&
		   de::inBounds(point.y(), rect.bottom,		rect.bottom + rect.height);
}

static inline Vec4 unpremultiply (const Vec4& v)
{
	if (v.w() > 0.0f)
		return Vec4(v.x()/v.w(), v.y()/v.w(), v.z()/v.w(), v.w());
	else
	{
		DE_ASSERT(v.x() == 0.0f && v.y() == 0.0f && v.z() == 0.0f);
		return Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	}
}

void clearMultisampleColorBuffer	(const tcu::PixelBufferAccess& dst, const Vec4& v,	const WindowRectangle& r)	{ tcu::clear(tcu::getSubregion(dst, 0, r.left, r.bottom, dst.getWidth(), r.width, r.height), v);				}
void clearMultisampleColorBuffer	(const tcu::PixelBufferAccess& dst, const IVec4& v,	const WindowRectangle& r)	{ tcu::clear(tcu::getSubregion(dst, 0, r.left, r.bottom, dst.getWidth(), r.width, r.height), v);				}
void clearMultisampleColorBuffer	(const tcu::PixelBufferAccess& dst, const UVec4& v,	const WindowRectangle& r)	{ tcu::clear(tcu::getSubregion(dst, 0, r.left, r.bottom, dst.getWidth(), r.width, r.height), v.cast<int>());	}
void clearMultisampleDepthBuffer	(const tcu::PixelBufferAccess& dst, float v,		const WindowRectangle& r)	{ tcu::clearDepth(tcu::getSubregion(dst, 0, r.left, r.bottom, dst.getWidth(), r.width, r.height), v);			}
void clearMultisampleStencilBuffer	(const tcu::PixelBufferAccess& dst, int v,			const WindowRectangle& r)	{ tcu::clearStencil(tcu::getSubregion(dst, 0, r.left, r.bottom, dst.getWidth(), r.width, r.height), v);			}

FragmentProcessor::FragmentProcessor (void)
	: m_sampleRegister()
{
}

void FragmentProcessor::executeScissorTest (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const WindowRectangle& scissorRect)
{
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			int fragNdx = fragNdxOffset + regSampleNdx/numSamplesPerFragment;

			if (!isInsideRect(inputFragments[fragNdx].pixelCoord, scissorRect))
				m_sampleRegister[regSampleNdx].isAlive = false;
		}
	}
}

void FragmentProcessor::executeStencilCompare (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const StencilState& stencilState, int numStencilBits, const tcu::ConstPixelBufferAccess& stencilBuffer)
{
#define SAMPLE_REGISTER_STENCIL_COMPARE(COMPARE_EXPRESSION)																					\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)															\
	{																																		\
		if (m_sampleRegister[regSampleNdx].isAlive)																							\
		{																																	\
			int					fragSampleNdx		= regSampleNdx % numSamplesPerFragment;													\
			const Fragment&		frag				= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];					\
			int					stencilBufferValue	= stencilBuffer.getPixStencil(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());	\
			int					maskedRef			= stencilState.compMask & clampedStencilRef;											\
			int					maskedBuf			= stencilState.compMask & stencilBufferValue;											\
			DE_UNREF(maskedRef);																											\
			DE_UNREF(maskedBuf);																											\
																																			\
			m_sampleRegister[regSampleNdx].stencilPassed = (COMPARE_EXPRESSION);															\
		}																																	\
	}

	int clampedStencilRef = de::clamp(stencilState.ref, 0, (1<<numStencilBits)-1);

	switch (stencilState.func)
	{
		case TESTFUNC_NEVER:	SAMPLE_REGISTER_STENCIL_COMPARE(false)						break;
		case TESTFUNC_ALWAYS:	SAMPLE_REGISTER_STENCIL_COMPARE(true)						break;
		case TESTFUNC_LESS:		SAMPLE_REGISTER_STENCIL_COMPARE(maskedRef <  maskedBuf)		break;
		case TESTFUNC_LEQUAL:	SAMPLE_REGISTER_STENCIL_COMPARE(maskedRef <= maskedBuf)		break;
		case TESTFUNC_GREATER:	SAMPLE_REGISTER_STENCIL_COMPARE(maskedRef >  maskedBuf)		break;
		case TESTFUNC_GEQUAL:	SAMPLE_REGISTER_STENCIL_COMPARE(maskedRef >= maskedBuf)		break;
		case TESTFUNC_EQUAL:	SAMPLE_REGISTER_STENCIL_COMPARE(maskedRef == maskedBuf)		break;
		case TESTFUNC_NOTEQUAL:	SAMPLE_REGISTER_STENCIL_COMPARE(maskedRef != maskedBuf)		break;
		default:
			DE_ASSERT(false);
	}

#undef SAMPLE_REGISTER_STENCIL_COMPARE
}

void FragmentProcessor::executeStencilSFail (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const StencilState& stencilState, int numStencilBits, const tcu::PixelBufferAccess& stencilBuffer)
{
#define SAMPLE_REGISTER_SFAIL(SFAIL_EXPRESSION)																																		\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)																									\
	{																																												\
		if (m_sampleRegister[regSampleNdx].isAlive && !m_sampleRegister[regSampleNdx].stencilPassed)																				\
		{																																											\
			int					fragSampleNdx		= regSampleNdx % numSamplesPerFragment;																							\
			const Fragment&		frag				= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];															\
			int					stencilBufferValue	= stencilBuffer.getPixStencil(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());											\
																																													\
			stencilBuffer.setPixStencil(maskedBitReplace(stencilBufferValue, (SFAIL_EXPRESSION), stencilState.writeMask), fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());	\
			m_sampleRegister[regSampleNdx].isAlive = false;																															\
		}																																											\
	}

	int clampedStencilRef = de::clamp(stencilState.ref, 0, (1<<numStencilBits)-1);

	switch (stencilState.sFail)
	{
		case STENCILOP_KEEP:		SAMPLE_REGISTER_SFAIL(stencilBufferValue)												break;
		case STENCILOP_ZERO:		SAMPLE_REGISTER_SFAIL(0)																break;
		case STENCILOP_REPLACE:		SAMPLE_REGISTER_SFAIL(clampedStencilRef)												break;
		case STENCILOP_INCR:		SAMPLE_REGISTER_SFAIL(de::clamp(stencilBufferValue+1, 0, (1<<numStencilBits) - 1))		break;
		case STENCILOP_DECR:		SAMPLE_REGISTER_SFAIL(de::clamp(stencilBufferValue-1, 0, (1<<numStencilBits) - 1))		break;
		case STENCILOP_INCR_WRAP:	SAMPLE_REGISTER_SFAIL((stencilBufferValue + 1) & ((1<<numStencilBits) - 1))				break;
		case STENCILOP_DECR_WRAP:	SAMPLE_REGISTER_SFAIL((stencilBufferValue - 1) & ((1<<numStencilBits) - 1))				break;
		case STENCILOP_INVERT:		SAMPLE_REGISTER_SFAIL((~stencilBufferValue) & ((1<<numStencilBits) - 1))				break;
		default:
			DE_ASSERT(false);
	}

#undef SAMPLE_REGISTER_SFAIL
}

void FragmentProcessor::executeDepthCompare (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, TestFunc depthFunc, const tcu::ConstPixelBufferAccess& depthBuffer)
{
#define SAMPLE_REGISTER_DEPTH_COMPARE_F(COMPARE_EXPRESSION)																						\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)																\
	{																																			\
		if (m_sampleRegister[regSampleNdx].isAlive)																								\
		{																																		\
			int					fragSampleNdx		= regSampleNdx % numSamplesPerFragment;														\
			const Fragment&		frag				= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];						\
			float				depthBufferValue	= depthBuffer.getPixDepth(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());			\
			float				sampleDepthFloat	= frag.sampleDepths[fragSampleNdx];															\
			float				sampleDepth			= de::clamp(sampleDepthFloat, 0.0f, 1.0f);													\
																																				\
			m_sampleRegister[regSampleNdx].depthPassed = (COMPARE_EXPRESSION);																	\
																																				\
			DE_UNREF(depthBufferValue);																											\
			DE_UNREF(sampleDepth);																												\
		}																																		\
	}

#define SAMPLE_REGISTER_DEPTH_COMPARE_UI(COMPARE_EXPRESSION)																					\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)																\
	{																																			\
		if (m_sampleRegister[regSampleNdx].isAlive)																								\
		{																																		\
			int					fragSampleNdx		= regSampleNdx % numSamplesPerFragment;														\
			const Fragment&		frag				= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];						\
			deUint32			depthBufferValue	= depthBuffer.getPixelUint(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y()).x();	\
			float				sampleDepthFloat	= frag.sampleDepths[fragSampleNdx];															\
																																				\
			/* Convert input float to target buffer format for comparison */																	\
																																				\
			deUint32 buffer[2];																													\
																																				\
			DE_ASSERT(sizeof(buffer) >= (size_t)depthBuffer.getFormat().getPixelSize());														\
																																				\
			tcu::PixelBufferAccess access(depthBuffer.getFormat(), 1, 1, 1, &buffer);															\
			access.setPixDepth(sampleDepthFloat, 0, 0, 0);																						\
			deUint32 sampleDepth = access.getPixelUint(0, 0, 0).x();																			\
																																				\
			m_sampleRegister[regSampleNdx].depthPassed = (COMPARE_EXPRESSION);																	\
																																				\
			DE_UNREF(depthBufferValue);																											\
			DE_UNREF(sampleDepth);																												\
		}																																		\
	}

	if (depthBuffer.getFormat().type == tcu::TextureFormat::FLOAT || depthBuffer.getFormat().type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
	{

		switch (depthFunc)
		{
			case TESTFUNC_NEVER:	SAMPLE_REGISTER_DEPTH_COMPARE_F(false)							break;
			case TESTFUNC_ALWAYS:	SAMPLE_REGISTER_DEPTH_COMPARE_F(true)								break;
			case TESTFUNC_LESS:		SAMPLE_REGISTER_DEPTH_COMPARE_F(sampleDepth <  depthBufferValue)	break;
			case TESTFUNC_LEQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_F(sampleDepth <= depthBufferValue)	break;
			case TESTFUNC_GREATER:	SAMPLE_REGISTER_DEPTH_COMPARE_F(sampleDepth >  depthBufferValue)	break;
			case TESTFUNC_GEQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_F(sampleDepth >= depthBufferValue)	break;
			case TESTFUNC_EQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_F(sampleDepth == depthBufferValue)	break;
			case TESTFUNC_NOTEQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_F(sampleDepth != depthBufferValue)	break;
			default:
				DE_ASSERT(false);
		}

	}
	else
	{
		switch (depthFunc)
		{
			case TESTFUNC_NEVER:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(false)							break;
			case TESTFUNC_ALWAYS:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(true)								break;
			case TESTFUNC_LESS:		SAMPLE_REGISTER_DEPTH_COMPARE_UI(sampleDepth <  depthBufferValue)	break;
			case TESTFUNC_LEQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(sampleDepth <= depthBufferValue)	break;
			case TESTFUNC_GREATER:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(sampleDepth >  depthBufferValue)	break;
			case TESTFUNC_GEQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(sampleDepth >= depthBufferValue)	break;
			case TESTFUNC_EQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(sampleDepth == depthBufferValue)	break;
			case TESTFUNC_NOTEQUAL:	SAMPLE_REGISTER_DEPTH_COMPARE_UI(sampleDepth != depthBufferValue)	break;
			default:
				DE_ASSERT(false);
		}
	}

#undef SAMPLE_REGISTER_DEPTH_COMPARE_F
#undef SAMPLE_REGISTER_DEPTH_COMPARE_UI
}

void FragmentProcessor::executeDepthWrite (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const tcu::PixelBufferAccess& depthBuffer)
{
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive && m_sampleRegister[regSampleNdx].depthPassed)
		{
			int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
			const Fragment&		frag			= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];
			const float			clampedDepth	= de::clamp(frag.sampleDepths[fragSampleNdx], 0.0f, 1.0f);

			depthBuffer.setPixDepth(clampedDepth, fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());
		}
	}
}

void FragmentProcessor::executeStencilDpFailAndPass (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const StencilState& stencilState, int numStencilBits, const tcu::PixelBufferAccess& stencilBuffer)
{
#define SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, EXPRESSION)																													\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)																								\
	{																																											\
		if (m_sampleRegister[regSampleNdx].isAlive && (CONDITION))																												\
		{																																										\
			int					fragSampleNdx		= regSampleNdx % numSamplesPerFragment;																						\
			const Fragment&		frag				= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];														\
			int					stencilBufferValue	= stencilBuffer.getPixStencil(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());										\
																																												\
			stencilBuffer.setPixStencil(maskedBitReplace(stencilBufferValue, (EXPRESSION), stencilState.writeMask), fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());	\
		}																																										\
	}

#define SWITCH_DPFAIL_OR_DPPASS(OP_NAME, CONDITION)																											\
		switch (stencilState.OP_NAME)																														\
		{																																					\
			case STENCILOP_KEEP:		SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, stencilBufferValue)												break;	\
			case STENCILOP_ZERO:		SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, 0)																break;	\
			case STENCILOP_REPLACE:		SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, clampedStencilRef)												break;	\
			case STENCILOP_INCR:		SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, de::clamp(stencilBufferValue+1, 0, (1<<numStencilBits) - 1))	break;	\
			case STENCILOP_DECR:		SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, de::clamp(stencilBufferValue-1, 0, (1<<numStencilBits) - 1))	break;	\
			case STENCILOP_INCR_WRAP:	SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, (stencilBufferValue + 1) & ((1<<numStencilBits) - 1))			break;	\
			case STENCILOP_DECR_WRAP:	SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, (stencilBufferValue - 1) & ((1<<numStencilBits) - 1))			break;	\
			case STENCILOP_INVERT:		SAMPLE_REGISTER_DPFAIL_OR_DPPASS(CONDITION, (~stencilBufferValue) & ((1<<numStencilBits) - 1))				break;	\
			default:																																		\
				DE_ASSERT(false);																															\
		}

	int clampedStencilRef = de::clamp(stencilState.ref, 0, (1<<numStencilBits)-1);

	SWITCH_DPFAIL_OR_DPPASS(dpFail, !m_sampleRegister[regSampleNdx].depthPassed)
	SWITCH_DPFAIL_OR_DPPASS(dpPass, m_sampleRegister[regSampleNdx].depthPassed)

#undef SWITCH_DPFAIL_OR_DPPASS
#undef SAMPLE_REGISTER_DPFAIL_OR_DPPASS
}

void FragmentProcessor::executeBlendFactorComputeRGB (const Vec4& blendColor, const BlendState& blendRGBState)
{
#define SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, FACTOR_EXPRESSION)																				\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)																	\
	{																																				\
		if (m_sampleRegister[regSampleNdx].isAlive)																									\
		{																																			\
			const Vec4& src		= m_sampleRegister[regSampleNdx].clampedBlendSrcColor;																\
			const Vec4& src1	= m_sampleRegister[regSampleNdx].clampedBlendSrc1Color;																\
			const Vec4& dst		= m_sampleRegister[regSampleNdx].clampedBlendDstColor;																\
			DE_UNREF(src);																															\
			DE_UNREF(src1);																															\
			DE_UNREF(dst);																															\
																																					\
			m_sampleRegister[regSampleNdx].FACTOR_NAME = (FACTOR_EXPRESSION);																		\
		}																																			\
	}

#define SWITCH_SRC_OR_DST_FACTOR_RGB(FUNC_NAME, FACTOR_NAME)																					\
	switch (blendRGBState.FUNC_NAME)																											\
	{																																			\
		case BLENDFUNC_ZERO:						SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(0.0f))								break;	\
		case BLENDFUNC_ONE:							SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f))								break;	\
		case BLENDFUNC_SRC_COLOR:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src.swizzle(0,1,2))						break;	\
		case BLENDFUNC_ONE_MINUS_SRC_COLOR:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - src.swizzle(0,1,2))			break;	\
		case BLENDFUNC_DST_COLOR:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, dst.swizzle(0,1,2))						break;	\
		case BLENDFUNC_ONE_MINUS_DST_COLOR:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - dst.swizzle(0,1,2))			break;	\
		case BLENDFUNC_SRC_ALPHA:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(src.w()))							break;	\
		case BLENDFUNC_ONE_MINUS_SRC_ALPHA:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - src.w()))						break;	\
		case BLENDFUNC_DST_ALPHA:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(dst.w()))							break;	\
		case BLENDFUNC_ONE_MINUS_DST_ALPHA:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - dst.w()))						break;	\
		case BLENDFUNC_CONSTANT_COLOR:				SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, blendColor.swizzle(0,1,2))				break;	\
		case BLENDFUNC_ONE_MINUS_CONSTANT_COLOR:	SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - blendColor.swizzle(0,1,2))	break;	\
		case BLENDFUNC_CONSTANT_ALPHA:				SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(blendColor.w()))						break;	\
		case BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA:	SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - blendColor.w()))				break;	\
		case BLENDFUNC_SRC_ALPHA_SATURATE:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(de::min(src.w(), 1.0f - dst.w())))	break;	\
		case BLENDFUNC_SRC1_COLOR:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src1.swizzle(0,1,2))						break;	\
		case BLENDFUNC_ONE_MINUS_SRC1_COLOR:		SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - src1.swizzle(0,1,2))			break;	\
		case BLENDFUNC_SRC1_ALPHA:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(src1.w()))							break;	\
		case BLENDFUNC_ONE_MINUS_SRC1_ALPHA:		SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - src1.w()))					break;	\
		default:																																\
			DE_ASSERT(false);																													\
	}

	SWITCH_SRC_OR_DST_FACTOR_RGB(srcFunc, blendSrcFactorRGB)
	SWITCH_SRC_OR_DST_FACTOR_RGB(dstFunc, blendDstFactorRGB)

#undef SWITCH_SRC_OR_DST_FACTOR_RGB
#undef SAMPLE_REGISTER_BLEND_FACTOR
}

void FragmentProcessor::executeBlendFactorComputeA (const Vec4& blendColor, const BlendState& blendAState)
{
#define SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, FACTOR_EXPRESSION)														\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)											\
	{																														\
		if (m_sampleRegister[regSampleNdx].isAlive)																			\
		{																													\
			const Vec4& src		= m_sampleRegister[regSampleNdx].clampedBlendSrcColor;										\
			const Vec4& src1	= m_sampleRegister[regSampleNdx].clampedBlendSrc1Color;										\
			const Vec4& dst		= m_sampleRegister[regSampleNdx].clampedBlendDstColor;										\
			DE_UNREF(src);																									\
			DE_UNREF(src1);																									\
			DE_UNREF(dst);																									\
																															\
			m_sampleRegister[regSampleNdx].FACTOR_NAME = (FACTOR_EXPRESSION);												\
		}																													\
	}

#define SWITCH_SRC_OR_DST_FACTOR_A(FUNC_NAME, FACTOR_NAME)																		\
	switch (blendAState.FUNC_NAME)																								\
	{																															\
		case BLENDFUNC_ZERO:						SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 0.0f)						break;	\
		case BLENDFUNC_ONE:							SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f)						break;	\
		case BLENDFUNC_SRC_COLOR:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src.w())					break;	\
		case BLENDFUNC_ONE_MINUS_SRC_COLOR:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - src.w())			break;	\
		case BLENDFUNC_DST_COLOR:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, dst.w())					break;	\
		case BLENDFUNC_ONE_MINUS_DST_COLOR:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - dst.w())			break;	\
		case BLENDFUNC_SRC_ALPHA:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src.w())					break;	\
		case BLENDFUNC_ONE_MINUS_SRC_ALPHA:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - src.w())			break;	\
		case BLENDFUNC_DST_ALPHA:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, dst.w())					break;	\
		case BLENDFUNC_ONE_MINUS_DST_ALPHA:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - dst.w())			break;	\
		case BLENDFUNC_CONSTANT_COLOR:				SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, blendColor.w())			break;	\
		case BLENDFUNC_ONE_MINUS_CONSTANT_COLOR:	SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - blendColor.w())	break;	\
		case BLENDFUNC_CONSTANT_ALPHA:				SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, blendColor.w())			break;	\
		case BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA:	SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - blendColor.w())	break;	\
		case BLENDFUNC_SRC_ALPHA_SATURATE:			SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f)						break;	\
		case BLENDFUNC_SRC1_COLOR:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src1.w())					break;	\
		case BLENDFUNC_ONE_MINUS_SRC1_COLOR:		SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - src1.w())			break;	\
		case BLENDFUNC_SRC1_ALPHA:					SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src1.w())					break;	\
		case BLENDFUNC_ONE_MINUS_SRC1_ALPHA:		SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, 1.0f - src1.w())			break;	\
		default:																												\
			DE_ASSERT(false);																									\
	}

	SWITCH_SRC_OR_DST_FACTOR_A(srcFunc, blendSrcFactorA)
	SWITCH_SRC_OR_DST_FACTOR_A(dstFunc, blendDstFactorA)

#undef SWITCH_SRC_OR_DST_FACTOR_A
#undef SAMPLE_REGISTER_BLEND_FACTOR
}

void FragmentProcessor::executeBlend (const BlendState& blendRGBState, const BlendState& blendAState)
{
#define SAMPLE_REGISTER_BLENDED_COLOR(COLOR_NAME, COLOR_EXPRESSION)						\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)		\
	{																					\
		if (m_sampleRegister[regSampleNdx].isAlive)										\
		{																				\
			SampleData& sample		= m_sampleRegister[regSampleNdx];					\
			const Vec4& srcColor	= sample.clampedBlendSrcColor;						\
			const Vec4& dstColor	= sample.clampedBlendDstColor;						\
																						\
			sample.COLOR_NAME = (COLOR_EXPRESSION);										\
		}																				\
	}

	switch (blendRGBState.equation)
	{
		case BLENDEQUATION_ADD:					SAMPLE_REGISTER_BLENDED_COLOR(blendedRGB, srcColor.swizzle(0,1,2)*sample.blendSrcFactorRGB + dstColor.swizzle(0,1,2)*sample.blendDstFactorRGB)	break;
		case BLENDEQUATION_SUBTRACT:			SAMPLE_REGISTER_BLENDED_COLOR(blendedRGB, srcColor.swizzle(0,1,2)*sample.blendSrcFactorRGB - dstColor.swizzle(0,1,2)*sample.blendDstFactorRGB)	break;
		case BLENDEQUATION_REVERSE_SUBTRACT:	SAMPLE_REGISTER_BLENDED_COLOR(blendedRGB, dstColor.swizzle(0,1,2)*sample.blendDstFactorRGB - srcColor.swizzle(0,1,2)*sample.blendSrcFactorRGB)	break;
		case BLENDEQUATION_MIN:					SAMPLE_REGISTER_BLENDED_COLOR(blendedRGB, min(srcColor.swizzle(0,1,2), dstColor.swizzle(0,1,2)))												break;
		case BLENDEQUATION_MAX:					SAMPLE_REGISTER_BLENDED_COLOR(blendedRGB, max(srcColor.swizzle(0,1,2), dstColor.swizzle(0,1,2)))												break;
		default:
			DE_ASSERT(false);
	}

	switch (blendAState.equation)
	{
		case BLENDEQUATION_ADD:					SAMPLE_REGISTER_BLENDED_COLOR(blendedA, srcColor.w()*sample.blendSrcFactorA + dstColor.w()*sample.blendDstFactorA)	break;
		case BLENDEQUATION_SUBTRACT:			SAMPLE_REGISTER_BLENDED_COLOR(blendedA, srcColor.w()*sample.blendSrcFactorA - dstColor.w()*sample.blendDstFactorA)	break;
		case BLENDEQUATION_REVERSE_SUBTRACT:	SAMPLE_REGISTER_BLENDED_COLOR(blendedA, dstColor.w()*sample.blendDstFactorA - srcColor.w()*sample.blendSrcFactorA)	break;
		case BLENDEQUATION_MIN:					SAMPLE_REGISTER_BLENDED_COLOR(blendedA, min(srcColor.w(), dstColor.w()))											break;
		case BLENDEQUATION_MAX:					SAMPLE_REGISTER_BLENDED_COLOR(blendedA, max(srcColor.w(), dstColor.w()))											break;
		default:
			DE_ASSERT(false);
	}
#undef SAMPLE_REGISTER_BLENDED_COLOR
}

namespace advblend
{

inline float	multiply	(float src, float dst) { return src*dst;					}
inline float	screen		(float src, float dst) { return src + dst - src*dst;		}
inline float	darken		(float src, float dst) { return de::min(src, dst);			}
inline float	lighten		(float src, float dst) { return de::max(src, dst);			}
inline float	difference	(float src, float dst) { return de::abs(dst-src);			}
inline float	exclusion	(float src, float dst) { return src + dst - 2.0f*src*dst;	}

inline float overlay (float src, float dst)
{
	if (dst <= 0.5f)
		return 2.0f*src*dst;
	else
		return 1.0f - 2.0f*(1.0f-src)*(1.0f-dst);
}

inline float colordodge (float src, float dst)
{
	if (dst <= 0.0f)
		return 0.0f;
	else if (src < 1.0f)
		return de::min(1.0f, dst/(1.0f-src));
	else
		return 1.0f;
}

inline float colorburn (float src, float dst)
{
	if (dst >= 1.0f)
		return 1.0f;
	else if (src > 0.0f)
		return 1.0f - de::min(1.0f, (1.0f-dst)/src);
	else
		return 0.0f;
}

inline float hardlight (float src, float dst)
{
	if (src <= 0.5f)
		return 2.0f*src*dst;
	else
		return 1.0f - 2.0f*(1.0f-src)*(1.0f-dst);
}

inline float softlight (float src, float dst)
{
	if (src <= 0.5f)
		return dst - (1.0f - 2.0f*src)*dst*(1.0f-dst);
	else if (dst <= 0.25f)
		return dst + (2.0f*src - 1.0f)*dst*((16.0f*dst - 12.0f)*dst + 3.0f);
	else
		return dst + (2.0f*src - 1.0f)*(deFloatSqrt(dst)-dst);
}

inline float minComp (const Vec3& v)
{
	return de::min(de::min(v.x(), v.y()), v.z());
}

inline float maxComp (const Vec3& v)
{
	return de::max(de::max(v.x(), v.y()), v.z());
}

inline float luminosity (const Vec3& rgb)
{
	return dot(rgb, Vec3(0.3f, 0.59f, 0.11f));
}

inline float saturation (const Vec3& rgb)
{
	return maxComp(rgb) - minComp(rgb);
}

Vec3 setLum (const Vec3& cbase, const Vec3& clum)
{
	const float		lbase	= luminosity(cbase);
	const float		llum	= luminosity(clum);
	const float		ldiff	= llum - lbase;
	const Vec3		color	= cbase + Vec3(ldiff);
	const float		minC	= minComp(color);
	const float		maxC	= maxComp(color);

	if (minC < 0.0f)
		return llum + ((color-llum)*llum / (llum != minC ? (llum-minC) : 1.0f));
	else if (maxC > 1.0f)
		return llum + ((color-llum)*(1.0f-llum) / (llum != maxC ? (maxC-llum) : 1.0f));
	else
		return color;
}

Vec3 setLumSat (const Vec3& cbase, const Vec3& csat, const Vec3& clum)
{
	const float		minbase	= minComp(cbase);
	const float		sbase	= saturation(cbase);
	const float		ssat	= saturation(csat);
	Vec3			color	= Vec3(0.0f);

	if (sbase > 0.0f)
		color = (cbase - minbase) * ssat / sbase;
	else
		color = color;

	return setLum(color, clum);
}

} // advblend

void FragmentProcessor::executeAdvancedBlend (BlendEquationAdvanced equation)
{
	using namespace advblend;

#define SAMPLE_REGISTER_ADV_BLEND(FUNCTION_NAME)											\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)			\
	{																						\
		if (m_sampleRegister[regSampleNdx].isAlive)											\
		{																					\
			SampleData&	sample		= m_sampleRegister[regSampleNdx];						\
			const Vec4&	srcColor	= sample.clampedBlendSrcColor;							\
			const Vec4&	dstColor	= sample.clampedBlendDstColor;							\
			const Vec3&	bias		= sample.blendSrcFactorRGB;								\
			const float	p0			= sample.blendSrcFactorA;								\
			const float	r			= FUNCTION_NAME(srcColor[0], dstColor[0])*p0 + bias[0];	\
			const float	g			= FUNCTION_NAME(srcColor[1], dstColor[1])*p0 + bias[1];	\
			const float	b			= FUNCTION_NAME(srcColor[2], dstColor[2])*p0 + bias[2];	\
																							\
			sample.blendedRGB = Vec3(r, g, b);												\
		}																					\
	}

#define SAMPLE_REGISTER_ADV_BLEND_HSL(COLOR_EXPRESSION)										\
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)			\
	{																						\
		if (m_sampleRegister[regSampleNdx].isAlive)											\
		{																					\
			SampleData&	sample		= m_sampleRegister[regSampleNdx];						\
			const Vec3	srcColor	= sample.clampedBlendSrcColor.swizzle(0,1,2);			\
			const Vec3	dstColor	= sample.clampedBlendDstColor.swizzle(0,1,2);			\
			const Vec3&	bias		= sample.blendSrcFactorRGB;								\
			const float	p0			= sample.blendSrcFactorA;								\
																							\
			sample.blendedRGB = (COLOR_EXPRESSION)*p0 + bias;								\
		}																					\
	}

	// Pre-compute factors & compute alpha \todo [2014-03-18 pyry] Re-using variable names.
	// \note clampedBlend*Color contains clamped & unpremultiplied colors
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			SampleData&	sample		= m_sampleRegister[regSampleNdx];
			const Vec4&	srcColor	= sample.clampedBlendSrcColor;
			const Vec4&	dstColor	= sample.clampedBlendDstColor;
			const float	srcA		= srcColor.w();
			const float	dstA		= dstColor.w();
			const float	p0			= srcA*dstA;
			const float p1			= srcA*(1.0f-dstA);
			const float p2			= dstA*(1.0f-srcA);
			const Vec3	bias		(srcColor[0]*p1 + dstColor[0]*p2,
									 srcColor[1]*p1 + dstColor[1]*p2,
									 srcColor[2]*p1 + dstColor[2]*p2);

			sample.blendSrcFactorRGB	= bias;
			sample.blendSrcFactorA		= p0;
			sample.blendedA				= p0 + p1 + p2;
		}
	}

	switch (equation)
	{
		case BLENDEQUATION_ADVANCED_MULTIPLY:		SAMPLE_REGISTER_ADV_BLEND(multiply);									break;
		case BLENDEQUATION_ADVANCED_SCREEN:			SAMPLE_REGISTER_ADV_BLEND(screen);										break;
		case BLENDEQUATION_ADVANCED_OVERLAY:		SAMPLE_REGISTER_ADV_BLEND(overlay);										break;
		case BLENDEQUATION_ADVANCED_DARKEN:			SAMPLE_REGISTER_ADV_BLEND(darken);										break;
		case BLENDEQUATION_ADVANCED_LIGHTEN:		SAMPLE_REGISTER_ADV_BLEND(lighten);										break;
		case BLENDEQUATION_ADVANCED_COLORDODGE:		SAMPLE_REGISTER_ADV_BLEND(colordodge);									break;
		case BLENDEQUATION_ADVANCED_COLORBURN:		SAMPLE_REGISTER_ADV_BLEND(colorburn);									break;
		case BLENDEQUATION_ADVANCED_HARDLIGHT:		SAMPLE_REGISTER_ADV_BLEND(hardlight);									break;
		case BLENDEQUATION_ADVANCED_SOFTLIGHT:		SAMPLE_REGISTER_ADV_BLEND(softlight);									break;
		case BLENDEQUATION_ADVANCED_DIFFERENCE:		SAMPLE_REGISTER_ADV_BLEND(difference);									break;
		case BLENDEQUATION_ADVANCED_EXCLUSION:		SAMPLE_REGISTER_ADV_BLEND(exclusion);									break;
		case BLENDEQUATION_ADVANCED_HSL_HUE:		SAMPLE_REGISTER_ADV_BLEND_HSL(setLumSat(srcColor, dstColor, dstColor));	break;
		case BLENDEQUATION_ADVANCED_HSL_SATURATION:	SAMPLE_REGISTER_ADV_BLEND_HSL(setLumSat(dstColor, srcColor, dstColor));	break;
		case BLENDEQUATION_ADVANCED_HSL_COLOR:		SAMPLE_REGISTER_ADV_BLEND_HSL(setLum(srcColor, dstColor));				break;
		case BLENDEQUATION_ADVANCED_HSL_LUMINOSITY:	SAMPLE_REGISTER_ADV_BLEND_HSL(setLum(dstColor, srcColor));				break;
		default:
			DE_ASSERT(false);
	}

#undef SAMPLE_REGISTER_ADV_BLEND
#undef SAMPLE_REGISTER_ADV_BLEND_HSL
}

void FragmentProcessor::executeColorWrite (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, bool isSRGB, const tcu::PixelBufferAccess& colorBuffer)
{
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
			const Fragment&		frag			= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];
			Vec4				combinedColor;

			combinedColor.xyz()	= m_sampleRegister[regSampleNdx].blendedRGB;
			combinedColor.w()	= m_sampleRegister[regSampleNdx].blendedA;

			if (isSRGB)
				combinedColor = tcu::linearToSRGB(combinedColor);

			colorBuffer.setPixel(combinedColor, fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());
		}
	}
}

void FragmentProcessor::executeRGBA8ColorWrite (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const tcu::PixelBufferAccess& colorBuffer)
{
	const int		fragStride	= 4;
	const int		xStride		= colorBuffer.getRowPitch();
	const int		yStride		= colorBuffer.getSlicePitch();
	deUint8* const	basePtr		= (deUint8*)colorBuffer.getDataPtr();

	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			const int			fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
			const Fragment&		frag			= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];
			deUint8*			dstPtr			= basePtr + fragSampleNdx*fragStride + frag.pixelCoord.x()*xStride + frag.pixelCoord.y()*yStride;

			dstPtr[0] = tcu::floatToU8(m_sampleRegister[regSampleNdx].blendedRGB.x());
			dstPtr[1] = tcu::floatToU8(m_sampleRegister[regSampleNdx].blendedRGB.y());
			dstPtr[2] = tcu::floatToU8(m_sampleRegister[regSampleNdx].blendedRGB.z());
			dstPtr[3] = tcu::floatToU8(m_sampleRegister[regSampleNdx].blendedA);
		}
	}
}

void FragmentProcessor::executeMaskedColorWrite (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const Vec4& colorMaskFactor, const Vec4& colorMaskNegationFactor, bool isSRGB, const tcu::PixelBufferAccess& colorBuffer)
{
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
			const Fragment&		frag			= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];
			Vec4				originalColor	= colorBuffer.getPixel(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());
			Vec4				newColor;

			newColor.xyz()	= m_sampleRegister[regSampleNdx].blendedRGB;
			newColor.w()	= m_sampleRegister[regSampleNdx].blendedA;

			if (isSRGB)
				newColor = tcu::linearToSRGB(newColor);

			newColor = colorMaskFactor*newColor + colorMaskNegationFactor*originalColor;

			colorBuffer.setPixel(newColor, fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());
		}
	}
}

void FragmentProcessor::executeSignedValueWrite (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const tcu::BVec4& colorMask, const tcu::PixelBufferAccess& colorBuffer)
{
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
			const Fragment&		frag			= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];
			const IVec4			originalValue	= colorBuffer.getPixelInt(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());

			colorBuffer.setPixel(tcu::select(m_sampleRegister[regSampleNdx].signedValue, originalValue, colorMask), fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());
		}
	}
}

void FragmentProcessor::executeUnsignedValueWrite (int fragNdxOffset, int numSamplesPerFragment, const Fragment* inputFragments, const tcu::BVec4& colorMask, const tcu::PixelBufferAccess& colorBuffer)
{
	for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
	{
		if (m_sampleRegister[regSampleNdx].isAlive)
		{
			int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
			const Fragment&		frag			= inputFragments[fragNdxOffset + regSampleNdx/numSamplesPerFragment];
			const UVec4			originalValue	= colorBuffer.getPixelUint(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());

			colorBuffer.setPixel(tcu::select(m_sampleRegister[regSampleNdx].unsignedValue, originalValue, colorMask), fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());
		}
	}
}

void FragmentProcessor::render (const rr::MultisamplePixelBufferAccess&		msColorBuffer,
								const rr::MultisamplePixelBufferAccess&		msDepthBuffer,
								const rr::MultisamplePixelBufferAccess&		msStencilBuffer,
								const Fragment*								inputFragments,
								int											numFragments,
								FaceType									fragmentFacing,
								const FragmentOperationState&				state)
{
	DE_ASSERT(fragmentFacing < FACETYPE_LAST);
	DE_ASSERT(state.numStencilBits < 32); // code bitshifts numStencilBits, avoid undefined behavior

	const tcu::PixelBufferAccess&	colorBuffer			= msColorBuffer.raw();
	const tcu::PixelBufferAccess&	depthBuffer			= msDepthBuffer.raw();
	const tcu::PixelBufferAccess&	stencilBuffer		= msStencilBuffer.raw();

	bool							hasDepth			= depthBuffer.getWidth() > 0	&& depthBuffer.getHeight() > 0		&& depthBuffer.getDepth() > 0;
	bool							hasStencil			= stencilBuffer.getWidth() > 0	&& stencilBuffer.getHeight() > 0	&& stencilBuffer.getDepth() > 0;
	bool							doDepthTest			= hasDepth && state.depthTestEnabled;
	bool							doStencilTest		= hasStencil && state.stencilTestEnabled;

	tcu::TextureChannelClass		colorbufferClass	= tcu::getTextureChannelClass(msColorBuffer.raw().getFormat().type);
	rr::GenericVecType				fragmentDataType	= (colorbufferClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? (rr::GENERICVECTYPE_INT32) : ((colorbufferClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (rr::GENERICVECTYPE_UINT32) : (rr::GENERICVECTYPE_FLOAT));

	DE_ASSERT((!hasDepth || colorBuffer.getWidth() == depthBuffer.getWidth())	&& (!hasStencil || colorBuffer.getWidth() == stencilBuffer.getWidth()));
	DE_ASSERT((!hasDepth || colorBuffer.getHeight() == depthBuffer.getHeight())	&& (!hasStencil || colorBuffer.getHeight() == stencilBuffer.getHeight()));
	DE_ASSERT((!hasDepth || colorBuffer.getDepth() == depthBuffer.getDepth())	&& (!hasStencil || colorBuffer.getDepth() == stencilBuffer.getDepth()));

	// Combined formats must be separated beforehand
	DE_ASSERT(!hasDepth || (!tcu::isCombinedDepthStencilType(depthBuffer.getFormat().type) && depthBuffer.getFormat().order == tcu::TextureFormat::D));
	DE_ASSERT(!hasStencil || (!tcu::isCombinedDepthStencilType(stencilBuffer.getFormat().type) && stencilBuffer.getFormat().order == tcu::TextureFormat::S));

	int						numSamplesPerFragment		= colorBuffer.getWidth();
	int						totalNumSamples				= numFragments*numSamplesPerFragment;
	int						numSampleGroups				= (totalNumSamples - 1) / SAMPLE_REGISTER_SIZE + 1; // \note totalNumSamples/SAMPLE_REGISTER_SIZE rounded up.
	const StencilState&		stencilState				= state.stencilStates[fragmentFacing];
	Vec4					colorMaskFactor				(state.colorMask[0] ? 1.0f : 0.0f, state.colorMask[1] ? 1.0f : 0.0f, state.colorMask[2] ? 1.0f : 0.0f, state.colorMask[3] ? 1.0f : 0.0f);
	Vec4					colorMaskNegationFactor		(state.colorMask[0] ? 0.0f : 1.0f, state.colorMask[1] ? 0.0f : 1.0f, state.colorMask[2] ? 0.0f : 1.0f, state.colorMask[3] ? 0.0f : 1.0f);
	bool					sRGBTarget					= state.sRGBEnabled && tcu::isSRGB(colorBuffer.getFormat());

	DE_ASSERT(SAMPLE_REGISTER_SIZE % numSamplesPerFragment == 0);

	// Divide the fragments' samples into groups of size SAMPLE_REGISTER_SIZE, and perform
	// the per-sample operations for one group at a time.

	for (int sampleGroupNdx = 0; sampleGroupNdx < numSampleGroups; sampleGroupNdx++)
	{
		// The index of the fragment of the sample at the beginning of m_sampleRegisters.
		int groupFirstFragNdx = (sampleGroupNdx*SAMPLE_REGISTER_SIZE) / numSamplesPerFragment;

		// Initialize sample data in the sample register.

		for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
		{
			int fragNdx			= groupFirstFragNdx + regSampleNdx/numSamplesPerFragment;
			int fragSampleNdx	= regSampleNdx % numSamplesPerFragment;

			if (fragNdx < numFragments)
			{
				m_sampleRegister[regSampleNdx].isAlive		= (inputFragments[fragNdx].coverage & (1u << fragSampleNdx)) != 0;
				m_sampleRegister[regSampleNdx].depthPassed	= true; // \note This will stay true if depth test is disabled.
			}
			else
				m_sampleRegister[regSampleNdx].isAlive = false;
		}

		// Scissor test.

		if (state.scissorTestEnabled)
			executeScissorTest(groupFirstFragNdx, numSamplesPerFragment, inputFragments, state.scissorRectangle);

		// Stencil test.

		if (doStencilTest)
		{
			executeStencilCompare(groupFirstFragNdx, numSamplesPerFragment, inputFragments, stencilState, state.numStencilBits, stencilBuffer);
			executeStencilSFail(groupFirstFragNdx, numSamplesPerFragment, inputFragments, stencilState, state.numStencilBits, stencilBuffer);
		}

		// Depth test.
		// \note Current value of isAlive is needed for dpPass and dpFail, so it's only updated after them and not right after depth test.

		if (doDepthTest)
		{
			executeDepthCompare(groupFirstFragNdx, numSamplesPerFragment, inputFragments, state.depthFunc, depthBuffer);

			if (state.depthMask)
				executeDepthWrite(groupFirstFragNdx, numSamplesPerFragment, inputFragments, depthBuffer);
		}

		// Do dpFail and dpPass stencil writes.

		if (doStencilTest)
			executeStencilDpFailAndPass(groupFirstFragNdx, numSamplesPerFragment, inputFragments, stencilState, state.numStencilBits, stencilBuffer);

		// Kill the samples that failed depth test.

		if (doDepthTest)
		{
			for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
				m_sampleRegister[regSampleNdx].isAlive = m_sampleRegister[regSampleNdx].isAlive && m_sampleRegister[regSampleNdx].depthPassed;
		}

		// Paint fragments to target

		switch (fragmentDataType)
		{
			case rr::GENERICVECTYPE_FLOAT:
			{
				// Select min/max clamping values for blending factors and operands
				Vec4 minClampValue;
				Vec4 maxClampValue;

				if (colorbufferClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
				{
					minClampValue = Vec4(0.0f);
					maxClampValue = Vec4(1.0f);
				}
				else if (colorbufferClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
				{
					minClampValue = Vec4(-1.0f);
					maxClampValue = Vec4(1.0f);
				}
				else
				{
					// No clamping
					minClampValue = Vec4(-std::numeric_limits<float>::infinity());
					maxClampValue = Vec4(std::numeric_limits<float>::infinity());
				}

				// Blend calculation - only if using blend.
				if (state.blendMode == BLENDMODE_STANDARD)
				{
					// Put dst color to register, doing srgb-to-linear conversion if needed.
					for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
					{
						if (m_sampleRegister[regSampleNdx].isAlive)
						{
							int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
							const Fragment&		frag			= inputFragments[groupFirstFragNdx + regSampleNdx/numSamplesPerFragment];
							Vec4				dstColor		= colorBuffer.getPixel(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());

							m_sampleRegister[regSampleNdx].clampedBlendSrcColor		= clamp(frag.value.get<float>(), minClampValue, maxClampValue);
							m_sampleRegister[regSampleNdx].clampedBlendSrc1Color	= clamp(frag.value1.get<float>(), minClampValue, maxClampValue);
							m_sampleRegister[regSampleNdx].clampedBlendDstColor		= clamp(sRGBTarget ? tcu::sRGBToLinear(dstColor) : dstColor, minClampValue, maxClampValue);
						}
					}

					// Calculate blend factors to register.
					executeBlendFactorComputeRGB(state.blendColor, state.blendRGBState);
					executeBlendFactorComputeA(state.blendColor, state.blendAState);

					// Compute blended color.
					executeBlend(state.blendRGBState, state.blendAState);
				}
				else if (state.blendMode == BLENDMODE_ADVANCED)
				{
					// Unpremultiply colors for blending, and do sRGB->linear if necessary
					// \todo [2014-03-17 pyry] Re-consider clampedBlend*Color var names
					for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
					{
						if (m_sampleRegister[regSampleNdx].isAlive)
						{
							int					fragSampleNdx	= regSampleNdx % numSamplesPerFragment;
							const Fragment&		frag			= inputFragments[groupFirstFragNdx + regSampleNdx/numSamplesPerFragment];
							const Vec4			srcColor		= frag.value.get<float>();
							const Vec4			dstColor		= colorBuffer.getPixel(fragSampleNdx, frag.pixelCoord.x(), frag.pixelCoord.y());

							m_sampleRegister[regSampleNdx].clampedBlendSrcColor		= unpremultiply(clamp(srcColor, minClampValue, maxClampValue));
							m_sampleRegister[regSampleNdx].clampedBlendDstColor		= unpremultiply(clamp(sRGBTarget ? tcu::sRGBToLinear(dstColor) : dstColor, minClampValue, maxClampValue));
						}
					}

					executeAdvancedBlend(state.blendEquationAdvaced);
				}
				else
				{
					// Not using blend - just put values to register as-is.
					DE_ASSERT(state.blendMode == BLENDMODE_NONE);

					for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
					{
						if (m_sampleRegister[regSampleNdx].isAlive)
						{
							const Fragment& frag = inputFragments[groupFirstFragNdx + regSampleNdx/numSamplesPerFragment];

							m_sampleRegister[regSampleNdx].blendedRGB	= frag.value.get<float>().xyz();
							m_sampleRegister[regSampleNdx].blendedA		= frag.value.get<float>().w();
						}
					}
				}

				// Clamp result values in sample register
				if (colorbufferClass != tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
				{
					for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
					{
						if (m_sampleRegister[regSampleNdx].isAlive)
						{
							m_sampleRegister[regSampleNdx].blendedRGB	= clamp(m_sampleRegister[regSampleNdx].blendedRGB, minClampValue.swizzle(0, 1, 2), maxClampValue.swizzle(0, 1, 2));
							m_sampleRegister[regSampleNdx].blendedA		= clamp(m_sampleRegister[regSampleNdx].blendedA, minClampValue.w(), maxClampValue.w());
						}
					}
				}

				// Finally, write the colors to the color buffer.

				if (state.colorMask[0] && state.colorMask[1] && state.colorMask[2] && state.colorMask[3])
				{
					if (colorBuffer.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
						executeRGBA8ColorWrite(groupFirstFragNdx, numSamplesPerFragment, inputFragments, colorBuffer);
					else
						executeColorWrite(groupFirstFragNdx, numSamplesPerFragment, inputFragments, sRGBTarget, colorBuffer);
				}
				else if (state.colorMask[0] || state.colorMask[1] || state.colorMask[2] || state.colorMask[3])
					executeMaskedColorWrite(groupFirstFragNdx, numSamplesPerFragment, inputFragments, colorMaskFactor, colorMaskNegationFactor, sRGBTarget, colorBuffer);
				break;
			}
			case rr::GENERICVECTYPE_INT32:
				// Write fragments
				for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
				{
					if (m_sampleRegister[regSampleNdx].isAlive)
					{
						const Fragment& frag = inputFragments[groupFirstFragNdx + regSampleNdx/numSamplesPerFragment];

						m_sampleRegister[regSampleNdx].signedValue = frag.value.get<deInt32>();
					}
				}

				if (state.colorMask[0] || state.colorMask[1] || state.colorMask[2] || state.colorMask[3])
					executeSignedValueWrite(groupFirstFragNdx, numSamplesPerFragment, inputFragments, state.colorMask, colorBuffer);
				break;

			case rr::GENERICVECTYPE_UINT32:
				// Write fragments
				for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)
				{
					if (m_sampleRegister[regSampleNdx].isAlive)
					{
						const Fragment& frag = inputFragments[groupFirstFragNdx + regSampleNdx/numSamplesPerFragment];

						m_sampleRegister[regSampleNdx].unsignedValue = frag.value.get<deUint32>();
					}
				}

				if (state.colorMask[0] || state.colorMask[1] || state.colorMask[2] || state.colorMask[3])
					executeUnsignedValueWrite(groupFirstFragNdx, numSamplesPerFragment, inputFragments, state.colorMask, colorBuffer);
				break;

			default:
				DE_ASSERT(DE_FALSE);
		}
	}
}

} // rr
