/*-------------------------------------------------------------------------
 * 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"

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 = clamp((FACTOR_EXPRESSION), Vec3(0.0f), Vec3(1.0f));	\
		}																										\
	}

#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 = clamp((FACTOR_EXPRESSION), 0.0f, 1.0f);	\
		}																							\
	}

#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);

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

	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:
				// 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>(), Vec4(0.0f), Vec4(1.0f));
							m_sampleRegister[regSampleNdx].clampedBlendSrc1Color	= clamp(frag.value1.get<float>(), Vec4(0.0f), Vec4(1.0f));
							m_sampleRegister[regSampleNdx].clampedBlendDstColor		= clamp(sRGBTarget ? tcu::sRGBToLinear(dstColor) : dstColor, Vec4(0.0f), Vec4(1.0f));
						}
					}

					// 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, Vec4(0.0f), Vec4(1.0f)));
							m_sampleRegister[regSampleNdx].clampedBlendDstColor		= unpremultiply(clamp(sRGBTarget ? tcu::sRGBToLinear(dstColor) : dstColor, Vec4(0.0f), Vec4(1.0f)));
						}
					}

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

				// 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
