/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Imagination Technologies Ltd.
 *
 * 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 Blend Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineBlendTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineUniqueRandomIterator.hpp"
#include "vktPipelineReferenceRenderer.hpp"
#include "vktTestCase.hpp"
#include "vkImageUtil.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuPlatform.hpp"
#include "tcuTextureUtil.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include <cstring>
#include <set>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{

bool isSupportedBlendFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
{
	VkFormatProperties formatProps;

	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);

	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) &&
		   (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
}

class BlendStateUniqueRandomIterator : public UniqueRandomIterator<VkPipelineColorBlendAttachmentState>
{
public:
											BlendStateUniqueRandomIterator		(deUint32 numberOfCombinations, int seed);
	virtual									~BlendStateUniqueRandomIterator		(void) {}
	VkPipelineColorBlendAttachmentState		getIndexedValue	(deUint32 index);

private:
	const static VkBlendFactor				m_blendFactors[];
	const static VkBlendOp					m_blendOps[];

	// Pre-calculated constants
	const static deUint32					m_blendFactorsLength;
	const static deUint32					m_blendFactorsLength2;
	const static deUint32					m_blendFactorsLength3;
	const static deUint32					m_blendFactorsLength4;
	const static deUint32					m_blendOpsLength;

	// Total number of cross-combinations of (srcBlendColor x destBlendColor x blendOpColor x srcBlendAlpha x destBlendAlpha x blendOpAlpha)
	const static deUint32					m_totalBlendStates;
};

class BlendStateUniqueRandomIteratorDualSource : public UniqueRandomIterator<VkPipelineColorBlendAttachmentState>
{
public:
											BlendStateUniqueRandomIteratorDualSource		(deUint32 numberOfCombinations, int seed);
	virtual									~BlendStateUniqueRandomIteratorDualSource		(void) {}
	VkPipelineColorBlendAttachmentState		getIndexedValue	(deUint32 index);

private:
	const static VkBlendFactor				m_blendFactors[];
	const static VkBlendOp					m_blendOps[];

	// Pre-calculated constants
	const static deUint32					m_blendFactorsLength;
	const static deUint32					m_blendFactorsLength2;
	const static deUint32					m_blendFactorsLength3;
	const static deUint32					m_blendFactorsLength4;
	const static deUint32					m_blendOpsLength;

	// Total number of cross-combinations of (srcBlendColor x destBlendColor x blendOpColor x srcBlendAlpha x destBlendAlpha x blendOpAlpha)
	const static deUint32					m_totalBlendStates;
};

class BlendTest : public vkt::TestCase
{
public:
	enum
	{
		QUAD_COUNT = 4
	};

	const static VkColorComponentFlags	s_colorWriteMasks[QUAD_COUNT];
	const static tcu::Vec4				s_blendConst;

										BlendTest				(tcu::TestContext&							testContext,
																 const std::string&							name,
																 const std::string&							description,
																 const VkFormat								colorFormat,
																 const VkPipelineColorBlendAttachmentState	blendStates[QUAD_COUNT]);
	virtual								~BlendTest				(void);
	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
	virtual void						checkSupport			(Context& context) const;
	virtual TestInstance*				createInstance			(Context& context) const;

private:
	const VkFormat						m_colorFormat;
	VkPipelineColorBlendAttachmentState	m_blendStates[QUAD_COUNT];
};

class DualSourceBlendTest : public vkt::TestCase
{
public:
	enum
	{
		QUAD_COUNT = 4
	};

	const static VkColorComponentFlags	s_colorWriteMasks[QUAD_COUNT];
	const static tcu::Vec4				s_blendConst;

										DualSourceBlendTest		(tcu::TestContext&							testContext,
																 const std::string&							name,
																 const std::string&							description,
																 const VkFormat								colorFormat,
																 const VkPipelineColorBlendAttachmentState	blendStates[QUAD_COUNT]);
	virtual								~DualSourceBlendTest	(void);
	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
	virtual void						checkSupport			(Context& context) const;
	virtual TestInstance*				createInstance			(Context& context) const;

private:
	const VkFormat						m_colorFormat;
	VkPipelineColorBlendAttachmentState	m_blendStates[QUAD_COUNT];
};

class BlendTestInstance : public vkt::TestInstance
{
public:
										BlendTestInstance		(Context& context, const VkFormat colorFormat, const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]);
	virtual								~BlendTestInstance		(void);
	virtual tcu::TestStatus				iterate					(void);

private:
	tcu::TestStatus						verifyImage				(void);

	VkPipelineColorBlendAttachmentState	m_blendStates[BlendTest::QUAD_COUNT];

	const tcu::UVec2					m_renderSize;
	const VkFormat						m_colorFormat;

	VkImageCreateInfo					m_colorImageCreateInfo;
	Move<VkImage>						m_colorImage;
	de::MovePtr<Allocation>				m_colorImageAlloc;
	Move<VkImageView>					m_colorAttachmentView;
	Move<VkRenderPass>					m_renderPass;
	Move<VkFramebuffer>					m_framebuffer;

	Move<VkShaderModule>				m_vertexShaderModule;
	Move<VkShaderModule>				m_fragmentShaderModule;

	Move<VkBuffer>						m_vertexBuffer;
	std::vector<Vertex4RGBA>			m_vertices;
	de::MovePtr<Allocation>				m_vertexBufferAlloc;

	Move<VkPipelineLayout>				m_pipelineLayout;
	Move<VkPipeline>					m_graphicsPipelines[BlendTest::QUAD_COUNT];

	Move<VkCommandPool>					m_cmdPool;
	Move<VkCommandBuffer>				m_cmdBuffer;
};

// Blend test dual source blending
class DualSourceBlendTestInstance : public vkt::TestInstance
{
public:
										DualSourceBlendTestInstance		(Context& context, const VkFormat colorFormat, const VkPipelineColorBlendAttachmentState blendStates[DualSourceBlendTest::QUAD_COUNT]);
	virtual								~DualSourceBlendTestInstance	(void);
	virtual tcu::TestStatus				iterate					(void);

private:
	tcu::TestStatus						verifyImage				(void);

	VkPipelineColorBlendAttachmentState	m_blendStates[DualSourceBlendTest::QUAD_COUNT];

	const tcu::UVec2					m_renderSize;
	const VkFormat						m_colorFormat;

	VkImageCreateInfo					m_colorImageCreateInfo;
	Move<VkImage>						m_colorImage;
	de::MovePtr<Allocation>				m_colorImageAlloc;
	Move<VkImageView>					m_colorAttachmentView;
	Move<VkRenderPass>					m_renderPass;
	Move<VkFramebuffer>					m_framebuffer;

	Move<VkShaderModule>				m_vertexShaderModule;
	Move<VkShaderModule>				m_fragmentShaderModule;

	Move<VkBuffer>						m_vertexBuffer;
	std::vector<Vertex4RGBARGBA>		m_vertices;
	de::MovePtr<Allocation>				m_vertexBufferAlloc;

	Move<VkPipelineLayout>				m_pipelineLayout;
	Move<VkPipeline>					m_graphicsPipelines[DualSourceBlendTest::QUAD_COUNT];

	Move<VkCommandPool>					m_cmdPool;
	Move<VkCommandBuffer>				m_cmdBuffer;
};

// BlendStateUniqueRandomIterator

const VkBlendFactor BlendStateUniqueRandomIterator::m_blendFactors[] =
{
	VK_BLEND_FACTOR_ZERO,
	VK_BLEND_FACTOR_ONE,
	VK_BLEND_FACTOR_SRC_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
	VK_BLEND_FACTOR_DST_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
	VK_BLEND_FACTOR_SRC_ALPHA,
	VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
	VK_BLEND_FACTOR_DST_ALPHA,
	VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
	VK_BLEND_FACTOR_CONSTANT_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
	VK_BLEND_FACTOR_CONSTANT_ALPHA,
	VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
	VK_BLEND_FACTOR_SRC_ALPHA_SATURATE,
};

const VkBlendOp BlendStateUniqueRandomIterator::m_blendOps[] =
{
	VK_BLEND_OP_ADD,
	VK_BLEND_OP_SUBTRACT,
	VK_BLEND_OP_REVERSE_SUBTRACT,
	VK_BLEND_OP_MIN,
	VK_BLEND_OP_MAX
};

const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength		= DE_LENGTH_OF_ARRAY(m_blendFactors);
const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength2	= m_blendFactorsLength * m_blendFactorsLength;
const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength3	= m_blendFactorsLength2 * m_blendFactorsLength;
const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength4	= m_blendFactorsLength3 * m_blendFactorsLength;
const deUint32 BlendStateUniqueRandomIterator::m_blendOpsLength			= DE_LENGTH_OF_ARRAY(m_blendOps);
const deUint32 BlendStateUniqueRandomIterator::m_totalBlendStates		= m_blendFactorsLength4 * m_blendOpsLength * m_blendOpsLength;


BlendStateUniqueRandomIterator::BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed)
	: UniqueRandomIterator<VkPipelineColorBlendAttachmentState>(numberOfCombinations, m_totalBlendStates, seed)
{
}

VkPipelineColorBlendAttachmentState BlendStateUniqueRandomIterator::getIndexedValue (deUint32 index)
{
	const deUint32		blendOpAlphaIndex			= index / (m_blendFactorsLength4 * m_blendOpsLength);
	const deUint32		blendOpAlphaSeqIndex		= blendOpAlphaIndex * (m_blendFactorsLength4 * m_blendOpsLength);

	const deUint32		destBlendAlphaIndex			= (index - blendOpAlphaSeqIndex) / (m_blendFactorsLength3 * m_blendOpsLength);
	const deUint32		destBlendAlphaSeqIndex		= destBlendAlphaIndex * (m_blendFactorsLength3 * m_blendOpsLength);

	const deUint32		srcBlendAlphaIndex			= (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex) / (m_blendFactorsLength2 * m_blendOpsLength);
	const deUint32		srcBlendAlphaSeqIndex		= srcBlendAlphaIndex * (m_blendFactorsLength2 * m_blendOpsLength);

	const deUint32		blendOpColorIndex			= (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex) / m_blendFactorsLength2;
	const deUint32		blendOpColorSeqIndex		= blendOpColorIndex * m_blendFactorsLength2;

	const deUint32		destBlendColorIndex			= (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex) / m_blendFactorsLength;
	const deUint32		destBlendColorSeqIndex		= destBlendColorIndex * m_blendFactorsLength;

	const deUint32		srcBlendColorIndex			= index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex - destBlendColorSeqIndex;

	const VkPipelineColorBlendAttachmentState blendAttachmentState =
	{
		true,														// VkBool32					blendEnable;
		m_blendFactors[srcBlendColorIndex],							// VkBlendFactor			srcColorBlendFactor;
		m_blendFactors[destBlendColorIndex],						// VkBlendFactor			dstColorBlendFactor;
		m_blendOps[blendOpColorIndex],								// VkBlendOp				colorBlendOp;
		m_blendFactors[srcBlendAlphaIndex],							// VkBlendFactor			srcAlphaBlendFactor;
		m_blendFactors[destBlendAlphaIndex],						// VkBlendFactor			dstAlphaBlendFactor;
		m_blendOps[blendOpAlphaIndex],								// VkBlendOp				alphaBlendOp;
		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
	};

	return blendAttachmentState;
}

// BlendStateUniqueRandomIteratorDualSource

const VkBlendFactor BlendStateUniqueRandomIteratorDualSource::m_blendFactors[] =
{
	VK_BLEND_FACTOR_ZERO,
	VK_BLEND_FACTOR_ONE,
	VK_BLEND_FACTOR_SRC_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
	VK_BLEND_FACTOR_DST_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
	VK_BLEND_FACTOR_SRC_ALPHA,
	VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
	VK_BLEND_FACTOR_DST_ALPHA,
	VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
	VK_BLEND_FACTOR_CONSTANT_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
	VK_BLEND_FACTOR_CONSTANT_ALPHA,
	VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
	VK_BLEND_FACTOR_SRC_ALPHA_SATURATE,
	VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
	VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA,
	VK_BLEND_FACTOR_SRC1_COLOR,
	VK_BLEND_FACTOR_SRC1_ALPHA
};

const VkBlendOp BlendStateUniqueRandomIteratorDualSource::m_blendOps[] =
{
	VK_BLEND_OP_ADD,
	VK_BLEND_OP_SUBTRACT,
	VK_BLEND_OP_REVERSE_SUBTRACT,
	VK_BLEND_OP_MIN,
	VK_BLEND_OP_MAX
};

const deUint32 BlendStateUniqueRandomIteratorDualSource::m_blendFactorsLength	= DE_LENGTH_OF_ARRAY(m_blendFactors);
const deUint32 BlendStateUniqueRandomIteratorDualSource::m_blendFactorsLength2	= m_blendFactorsLength * m_blendFactorsLength;
const deUint32 BlendStateUniqueRandomIteratorDualSource::m_blendFactorsLength3	= m_blendFactorsLength2 * m_blendFactorsLength;
const deUint32 BlendStateUniqueRandomIteratorDualSource::m_blendFactorsLength4	= m_blendFactorsLength3 * m_blendFactorsLength;
const deUint32 BlendStateUniqueRandomIteratorDualSource::m_blendOpsLength		= DE_LENGTH_OF_ARRAY(m_blendOps);
const deUint32 BlendStateUniqueRandomIteratorDualSource::m_totalBlendStates		= m_blendFactorsLength4 * m_blendOpsLength * m_blendOpsLength;


BlendStateUniqueRandomIteratorDualSource::BlendStateUniqueRandomIteratorDualSource (deUint32 numberOfCombinations, int seed)
	: UniqueRandomIterator<VkPipelineColorBlendAttachmentState>(numberOfCombinations, m_totalBlendStates, seed)
{
}

VkPipelineColorBlendAttachmentState BlendStateUniqueRandomIteratorDualSource::getIndexedValue (deUint32 index)
{
	const deUint32		blendOpAlphaIndex			= index / (m_blendFactorsLength4 * m_blendOpsLength);
	const deUint32		blendOpAlphaSeqIndex		= blendOpAlphaIndex * (m_blendFactorsLength4 * m_blendOpsLength);

	const deUint32		destBlendAlphaIndex			= (index - blendOpAlphaSeqIndex) / (m_blendFactorsLength3 * m_blendOpsLength);
	const deUint32		destBlendAlphaSeqIndex		= destBlendAlphaIndex * (m_blendFactorsLength3 * m_blendOpsLength);

	const deUint32		srcBlendAlphaIndex			= (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex) / (m_blendFactorsLength2 * m_blendOpsLength);
	const deUint32		srcBlendAlphaSeqIndex		= srcBlendAlphaIndex * (m_blendFactorsLength2 * m_blendOpsLength);

	const deUint32		blendOpColorIndex			= (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex) / m_blendFactorsLength2;
	const deUint32		blendOpColorSeqIndex		= blendOpColorIndex * m_blendFactorsLength2;

	const deUint32		destBlendColorIndex			= (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex) / m_blendFactorsLength;
	const deUint32		destBlendColorSeqIndex		= destBlendColorIndex * m_blendFactorsLength;

	const deUint32		srcBlendColorIndex			= index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex - destBlendColorSeqIndex;

	const VkPipelineColorBlendAttachmentState blendAttachmentState =
	{
		true,														// VkBool32					blendEnable;
		m_blendFactors[srcBlendColorIndex],							// VkBlendFactor			srcColorBlendFactor;
		m_blendFactors[destBlendColorIndex],						// VkBlendFactor			dstColorBlendFactor;
		m_blendOps[blendOpColorIndex],								// VkBlendOp				colorBlendOp;
		m_blendFactors[srcBlendAlphaIndex],							// VkBlendFactor			srcAlphaBlendFactor;
		m_blendFactors[destBlendAlphaIndex],						// VkBlendFactor			dstAlphaBlendFactor;
		m_blendOps[blendOpAlphaIndex],								// VkBlendOp				alphaBlendOp;
		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
	};

	return blendAttachmentState;
}


// BlendTest

const VkColorComponentFlags BlendTest::s_colorWriteMasks[BlendTest::QUAD_COUNT] = { VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT,	// Pair of channels: R & G
																					VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT,	// Pair of channels: G & B
																					VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,	// Pair of channels: B & A
																					VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT };	// All channels

const tcu::Vec4 BlendTest::s_blendConst = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f);

BlendTest::BlendTest (tcu::TestContext&								testContext,
					  const std::string&							name,
					  const std::string&							description,
					  const VkFormat								colorFormat,
					  const VkPipelineColorBlendAttachmentState		blendStates[QUAD_COUNT])
	: vkt::TestCase	(testContext, name, description)
	, m_colorFormat(colorFormat)
{
	deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * QUAD_COUNT);
}

BlendTest::~BlendTest (void)
{
}

TestInstance* BlendTest::createInstance(Context& context) const
{
	return new BlendTestInstance(context, m_colorFormat, m_blendStates);
}

void BlendTest::checkSupport (Context& context) const
{
	if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_colorFormat))
		throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_colorFormat));
}

void BlendTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream fragmentSource;

	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 color;\n"
		"layout(location = 0) out highp vec4 vtxColor;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = position;\n"
		"	vtxColor = color;\n"
		"}\n");

	fragmentSource << "#version 310 es\n"
		"layout(location = 0) in highp vec4 vtxColor;\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = vtxColor;\n"
		"}\n";

	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
}

// DualSourceBlendTest

const VkColorComponentFlags DualSourceBlendTest::s_colorWriteMasks[BlendTest::QUAD_COUNT] = { VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT,	// Pair of channels: R & G
																							  VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT,	// Pair of channels: G & B
																							  VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,	// Pair of channels: B & A
																							  VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT };	// All channels

const tcu::Vec4 DualSourceBlendTest::s_blendConst = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f);

DualSourceBlendTest::DualSourceBlendTest (tcu::TestContext&								testContext,
										  const std::string&							name,
										  const std::string&							description,
										  const VkFormat								colorFormat,
										  const VkPipelineColorBlendAttachmentState		blendStates[QUAD_COUNT])
	: vkt::TestCase	(testContext, name, description)
	, m_colorFormat(colorFormat)
{
	deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * QUAD_COUNT);
}

DualSourceBlendTest::~DualSourceBlendTest (void)
{
}

deBool isSrc1BlendFactor(vk::VkBlendFactor blendFactor)
{
	switch(blendFactor)
	{
		case vk::VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR:
		case vk::VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA:
		case vk::VK_BLEND_FACTOR_SRC1_ALPHA:
		case vk::VK_BLEND_FACTOR_SRC1_COLOR:
			return DE_TRUE;
		default:
			return DE_FALSE;
	}
}

TestInstance* DualSourceBlendTest::createInstance(Context& context) const
{
	return new DualSourceBlendTestInstance(context, m_colorFormat, m_blendStates);
}

void DualSourceBlendTest::checkSupport (Context& context) const
{
	const vk::VkPhysicalDeviceFeatures features = context.getDeviceFeatures();

	deBool	isDualSourceTest = DE_FALSE;
	for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
	{
		isDualSourceTest =
			isSrc1BlendFactor(this->m_blendStates[quadNdx].srcColorBlendFactor) ||
			isSrc1BlendFactor(this->m_blendStates[quadNdx].dstColorBlendFactor) ||
			isSrc1BlendFactor(this->m_blendStates[quadNdx].srcAlphaBlendFactor) ||
			isSrc1BlendFactor(this->m_blendStates[quadNdx].dstAlphaBlendFactor);
		if (isDualSourceTest)
			break;
	}
	if (isDualSourceTest && !features.dualSrcBlend)
		throw tcu::NotSupportedError("Dual-Source blending not supported");

	if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_colorFormat))
		throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_colorFormat));
}

void DualSourceBlendTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream fragmentSource;

	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
		"#version 450\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 color0;\n"
		"layout(location = 2) in highp vec4 color1;\n"
		"layout(location = 0) out highp vec4 vtxColor0;\n"
		"layout(location = 1) out highp vec4 vtxColor1;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = position;\n"
		"	vtxColor0 = color0;\n"
		"	vtxColor1 = color1;\n"
		"}\n");

	fragmentSource << "#version 450\n"
		"layout(location = 0) in highp vec4 vtxColor0;\n"
		"layout(location = 1) in highp vec4 vtxColor1;\n"
		"layout(location = 0, index = 0) out highp vec4 fragColor0;\n"
		"layout(location = 0, index = 1) out highp vec4 fragColor1;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor0 = vtxColor0;\n"
		"	fragColor1 = vtxColor1;\n"
		"}\n";

	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
}

// BlendTestInstance

BlendTestInstance::BlendTestInstance (Context&									context,
									  const VkFormat							colorFormat,
									  const VkPipelineColorBlendAttachmentState	blendStates[BlendTest::QUAD_COUNT])
	: vkt::TestInstance	(context)
	, m_renderSize		(32, 32)
	, m_colorFormat		(colorFormat)
{
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	SimpleAllocator				memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));

	// Copy depth operators
	deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * BlendTest::QUAD_COUNT);

	// Create color image
	{
		const VkImageCreateInfo	colorImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
			DE_NULL,																	// const void*				pNext;
			0u,																			// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
			m_colorFormat,																// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
			1u,																			// deUint32					mipLevels;
			1u,																			// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
			1u,																			// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
		};

		m_colorImageCreateInfo	= colorImageParams;
		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkImageViewCreateFlags	flags;
			*m_colorImage,										// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
			m_colorFormat,										// VkFormat					format;
			{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);

	// Create framebuffer
	{
		const VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkFramebufferCreateFlags	flags;
			*m_renderPass,										// VkRenderPass				renderPass;
			1u,													// deUint32					attachmentCount;
			&m_colorAttachmentView.get(),						// const VkImageView*		pAttachments;
			(deUint32)m_renderSize.x(),							// deUint32					width;
			(deUint32)m_renderSize.y(),							// deUint32					height;
			1u													// deUint32					layers;
		};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkPipelineLayoutCreateFlags		flags;
			0u,													// deUint32							setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
			0u,													// deUint32							pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);

	// Create pipeline
	{
		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,									// deUint32					binding;
			sizeof(Vertex4RGBA),				// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	inputRate;
		};

		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[2]	=
		{
			{
				0u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				0u								// deUint32	offset;
			},
			{
				1u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				(deUint32)(sizeof(float) * 4),	// deUint32	offset;
			}
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
			1u,																// deUint32									vertexBindingDescriptionCount;
			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,																// deUint32									vertexAttributeDescriptionCount;
			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const std::vector<VkViewport>				viewports							(1, makeViewport(m_renderSize));
		const std::vector<VkRect2D>					scissors							(1, makeRect2D(m_renderSize));

		// The color blend attachment will be set up before creating the graphics pipeline.
		VkPipelineColorBlendStateCreateInfo			colorBlendStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
			DE_NULL,													// const void*									pNext;
			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
			false,														// VkBool32										logicOpEnable;
			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
			0u,															// deUint32										attachmentCount;
			DE_NULL,													// const VkPipelineColorBlendAttachmentState*	pAttachments;
			{															// float										blendConstants[4];
				BlendTest::s_blendConst.x(),
				BlendTest::s_blendConst.y(),
				BlendTest::s_blendConst.z(),
				BlendTest::s_blendConst.w()
			}
		};

		for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
		{
			colorBlendStateParams.attachmentCount	= 1u;
			colorBlendStateParams.pAttachments		= &m_blendStates[quadNdx];
			m_graphicsPipelines[quadNdx]			= makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
																		   vkDevice,							// const VkDevice                                device
																		   *m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
																		   *m_vertexShaderModule,				// const VkShaderModule                          vertexShaderModule
																		   DE_NULL,								// const VkShaderModule                          tessellationControlModule
																		   DE_NULL,								// const VkShaderModule                          tessellationEvalModule
																		   DE_NULL,								// const VkShaderModule                          geometryShaderModule
																		   *m_fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
																		   *m_renderPass,						// const VkRenderPass                            renderPass
																		   viewports,							// const std::vector<VkViewport>&                viewports
																		   scissors,							// const std::vector<VkRect2D>&                  scissors
																		   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
																		   0u,									// const deUint32                                subpass
																		   0u,									// const deUint32                                patchControlPoints
																		   &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
																		   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
																		   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
																		   DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
																		   &colorBlendStateParams);				// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
		}
	}

	// Create vertex buffer
	{
		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			1024u,										// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		m_vertices			= createOverlappingQuads();
		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Adjust vertex colors
		if (!isFloatFormat(m_colorFormat))
		{
			const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(mapVkFormat(m_colorFormat));
			for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
				m_vertices[vertexNdx].color = (m_vertices[vertexNdx].color - formatInfo.lookupBias) / formatInfo.lookupScale;
		}

		// Upload vertex data
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));

		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);

		// Color image layout transition
		const VkImageMemoryBarrier imageLayoutBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
			DE_NULL,																// const void*                pNext;
			(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,								// VkImageLayout              newLayout;
			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
			*m_colorImage,															// VkImage                    image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange    subresourceRange;
		};

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
			0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutBarrier);

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);

		const VkDeviceSize quadOffset = (m_vertices.size() / BlendTest::QUAD_COUNT) * sizeof(Vertex4RGBA);

		for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
		{
			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;

			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / BlendTest::QUAD_COUNT), 1, 0, 0);
		}

		endRenderPass(vk, *m_cmdBuffer);
		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

BlendTestInstance::~BlendTestInstance (void)
{
}

tcu::TestStatus BlendTestInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	return verifyImage();
}

float getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
{
	switch (tcu::getTextureChannelClass(format.type))
	{
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:	return static_cast<float>(BlendTest::QUAD_COUNT) / static_cast<float>((1 << numBits) - 1);
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:	return static_cast<float>(BlendTest::QUAD_COUNT) / static_cast<float>((1 << (numBits - 1)) - 1);
		default:
			break;
	}

	DE_ASSERT(false);
	return 0.0f;
}

tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
{
	using tcu::Vec4;
	using tcu::TextureFormat;

	Vec4 threshold(0.01f);

	switch (format.type)
	{
		case TextureFormat::UNORM_BYTE_44:
			threshold = Vec4(getNormChannelThreshold(format, 4), getNormChannelThreshold(format, 4), 1.0f, 1.0f);
			break;

		case TextureFormat::UNORM_SHORT_565:
			threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 6), getNormChannelThreshold(format, 5), 1.0f);
			break;

		case TextureFormat::UNORM_SHORT_555:
			threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 1.0f);
			break;

		case TextureFormat::UNORM_SHORT_4444:
			threshold = Vec4(getNormChannelThreshold(format, 4));
			break;

		case TextureFormat::UNORM_SHORT_5551:
			threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 0.1f);
			break;

		case TextureFormat::UNORM_INT_1010102_REV:
		case TextureFormat::SNORM_INT_1010102_REV:
			threshold = Vec4(getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), 0.34f);
			break;

		case TextureFormat::UNORM_INT8:
		case TextureFormat::SNORM_INT8:
			threshold = Vec4(getNormChannelThreshold(format, 8));
			break;

		case TextureFormat::UNORM_INT16:
		case TextureFormat::SNORM_INT16:
			threshold = Vec4(getNormChannelThreshold(format, 16));
			break;

		case TextureFormat::UNORM_INT32:
		case TextureFormat::SNORM_INT32:
			threshold = Vec4(getNormChannelThreshold(format, 32));
			break;

		case TextureFormat::HALF_FLOAT:
			threshold = Vec4(0.005f);
			break;

		case TextureFormat::FLOAT:
			threshold = Vec4(0.00001f);
			break;

		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
			threshold = Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
			break;

		case TextureFormat::UNSIGNED_INT_999_E5_REV:
			threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f);
			break;

		case TextureFormat::UNORM_SHORT_1555:
			threshold = Vec4(0.1f, getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5));
			break;

		default:
			DE_ASSERT(false);
	}

	// Return value matching the channel order specified by the format
	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
		return threshold.swizzle(2, 1, 0, 3);
	else
		return threshold;
}

bool isLegalExpandableFormat (tcu::TextureFormat::ChannelType channeltype)
{
	using tcu::TextureFormat;

	switch (channeltype)
	{
		case TextureFormat::UNORM_INT24:
		case TextureFormat::UNORM_BYTE_44:
		case TextureFormat::UNORM_SHORT_565:
		case TextureFormat::UNORM_SHORT_555:
		case TextureFormat::UNORM_SHORT_4444:
		case TextureFormat::UNORM_SHORT_5551:
		case TextureFormat::UNORM_SHORT_1555:
		case TextureFormat::UNORM_INT_101010:
		case TextureFormat::SNORM_INT_1010102_REV:
		case TextureFormat::UNORM_INT_1010102_REV:
		case TextureFormat::UNSIGNED_BYTE_44:
		case TextureFormat::UNSIGNED_SHORT_565:
		case TextureFormat::UNSIGNED_SHORT_4444:
		case TextureFormat::UNSIGNED_SHORT_5551:
		case TextureFormat::SIGNED_INT_1010102_REV:
		case TextureFormat::UNSIGNED_INT_1010102_REV:
		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
		case TextureFormat::UNSIGNED_INT_999_E5_REV:
		case TextureFormat::UNSIGNED_INT_24_8:
		case TextureFormat::UNSIGNED_INT_24_8_REV:
		case TextureFormat::UNSIGNED_INT24:
		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
			return true;

		case TextureFormat::SNORM_INT8:
		case TextureFormat::SNORM_INT16:
		case TextureFormat::SNORM_INT32:
		case TextureFormat::UNORM_INT8:
		case TextureFormat::UNORM_INT16:
		case TextureFormat::UNORM_INT32:
		case TextureFormat::UNSIGNED_INT_16_8_8:
		case TextureFormat::SIGNED_INT8:
		case TextureFormat::SIGNED_INT16:
		case TextureFormat::SIGNED_INT32:
		case TextureFormat::UNSIGNED_INT8:
		case TextureFormat::UNSIGNED_INT16:
		case TextureFormat::UNSIGNED_INT32:
		case TextureFormat::HALF_FLOAT:
		case TextureFormat::FLOAT:
		case TextureFormat::FLOAT64:
			return false;

		default:
			DE_FATAL("Unknown texture format");
	}
	return false;
}

bool isSmallerThan8BitFormat (tcu::TextureFormat::ChannelType channeltype)
{
	using tcu::TextureFormat;

	// Note: only checks the legal expandable formats
	// (i.e, formats that have channels that fall outside
	// the 8, 16 and 32 bit width)
	switch (channeltype)
	{
		case TextureFormat::UNORM_BYTE_44:
		case TextureFormat::UNORM_SHORT_565:
		case TextureFormat::UNORM_SHORT_555:
		case TextureFormat::UNORM_SHORT_4444:
		case TextureFormat::UNORM_SHORT_5551:
		case TextureFormat::UNORM_SHORT_1555:
		case TextureFormat::UNSIGNED_BYTE_44:
		case TextureFormat::UNSIGNED_SHORT_565:
		case TextureFormat::UNSIGNED_SHORT_4444:
		case TextureFormat::UNSIGNED_SHORT_5551:
			return true;

		case TextureFormat::UNORM_INT24:
		case TextureFormat::UNORM_INT_101010:
		case TextureFormat::SNORM_INT_1010102_REV:
		case TextureFormat::UNORM_INT_1010102_REV:
		case TextureFormat::SIGNED_INT_1010102_REV:
		case TextureFormat::UNSIGNED_INT_1010102_REV:
		case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
		case TextureFormat::UNSIGNED_INT_999_E5_REV:
		case TextureFormat::UNSIGNED_INT_24_8:
		case TextureFormat::UNSIGNED_INT_24_8_REV:
		case TextureFormat::UNSIGNED_INT24:
		case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
			return false;

		default:
			DE_FATAL("Unknown texture format");
	}

	return false;
}

tcu::TestStatus BlendTestInstance::verifyImage (void)
{
	const tcu::TextureFormat	tcuColorFormat		= mapVkFormat(m_colorFormat);
	const tcu::TextureFormat	tcuColorFormat64	= mapVkFormat(VK_FORMAT_R64G64B64A64_SFLOAT);
	const tcu::TextureFormat	tcuColorFormat8		= mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
	const tcu::TextureFormat	tcuDepthFormat		= tcu::TextureFormat(); // Undefined depth/stencil format
	const ColorVertexShader		vertexShader;
	const ColorFragmentShader	fragmentShader		(tcuColorFormat, tcuDepthFormat);
	const rr::Program			program				(&vertexShader, &fragmentShader);
	ReferenceRenderer			refRenderer			(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
	ReferenceRenderer			refRenderer64		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat64, tcuDepthFormat, &program);
	ReferenceRenderer			refRenderer8		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat8, tcuDepthFormat, &program);
	bool						compareOk			= false;

	// Render reference image
	{
		for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
		{
			const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx];

			// Set blend state
			rr::RenderState renderState					(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
			renderState.fragOps.blendMode				= rr::BLENDMODE_STANDARD;
			renderState.fragOps.blendRGBState.srcFunc	= mapVkBlendFactor(blendState.srcColorBlendFactor);
			renderState.fragOps.blendRGBState.dstFunc	= mapVkBlendFactor(blendState.dstColorBlendFactor);
			renderState.fragOps.blendRGBState.equation	= mapVkBlendOp(blendState.colorBlendOp);
			renderState.fragOps.blendAState.srcFunc		= mapVkBlendFactor(blendState.srcAlphaBlendFactor);
			renderState.fragOps.blendAState.dstFunc		= mapVkBlendFactor(blendState.dstAlphaBlendFactor);
			renderState.fragOps.blendAState.equation	= mapVkBlendOp(blendState.alphaBlendOp);
			renderState.fragOps.blendColor				= BlendTest::s_blendConst;
			renderState.fragOps.colorMask				= mapVkColorComponentFlags(BlendTest::s_colorWriteMasks[quadNdx]);

			refRenderer.draw(renderState,
							rr::PRIMITIVETYPE_TRIANGLES,
							std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
													 m_vertices.begin() + (quadNdx + 1) * 6));

			if (isLegalExpandableFormat(tcuColorFormat.type))
			{
				refRenderer64.draw(renderState,
								   rr::PRIMITIVETYPE_TRIANGLES,
								   std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
								   m_vertices.begin() + (quadNdx + 1) * 6));

				if (isSmallerThan8BitFormat(tcuColorFormat.type))
					refRenderer8.draw(renderState,
									  rr::PRIMITIVETYPE_TRIANGLES,
									  std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
									  m_vertices.begin() + (quadNdx + 1) * 6));
			}
		}
	}

	// Compare result with reference image
	{
		const DeviceInterface&				vk							= m_context.getDeviceInterface();
		const VkDevice						vkDevice					= m_context.getDevice();
		const VkQueue						queue						= m_context.getUniversalQueue();
		const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator						allocator					(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::UniquePtr<tcu::TextureLevel>	result						(readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
		const tcu::Vec4						threshold					(getFormatThreshold(tcuColorFormat));
		tcu::TextureLevel					refLevel;

		refLevel.setStorage(tcuColorFormat, m_renderSize.x(), m_renderSize.y(), 1);

		compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
											   "FloatImageCompare",
											   "Image comparison",
											   refRenderer.getAccess(),
											   result->getAccess(),
											   threshold,
											   tcu::COMPARE_LOG_RESULT);

		if (isLegalExpandableFormat(tcuColorFormat.type))
		{
			if (!compareOk && isSmallerThan8BitFormat(tcuColorFormat.type))
			{
				// Convert to target format
				tcu::copy(refLevel.getAccess(), refRenderer8.getAccess());

				compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
													   "FloatImageCompare",
													   "Image comparison, 8 bit intermediate format",
													   refLevel.getAccess(),
													   result->getAccess(),
													   threshold,
													   tcu::COMPARE_LOG_RESULT);
			}

			if (!compareOk)
			{
				// Convert to target format
				tcu::copy(refLevel.getAccess(), refRenderer64.getAccess());

				compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
													   "FloatImageCompare",
													   "Image comparison, 64 bit intermediate format",
													   refLevel.getAccess(),
													   result->getAccess(),
													   threshold,
													   tcu::COMPARE_LOG_RESULT);
			}
		}
	}

	if (compareOk)
		return tcu::TestStatus::pass("Result image matches reference");
	else
		return tcu::TestStatus::fail("Image mismatch");
}

// DualSourceBlendTestInstance

DualSourceBlendTestInstance::DualSourceBlendTestInstance (Context&									context,
														  const VkFormat							colorFormat,
														  const VkPipelineColorBlendAttachmentState	blendStates[DualSourceBlendTest::QUAD_COUNT])
	: vkt::TestInstance	(context)
	, m_renderSize		(32, 32)
	, m_colorFormat		(colorFormat)
{
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	SimpleAllocator				memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));

	// Copy depth operators
	deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * DualSourceBlendTest::QUAD_COUNT);

	// Create color image
	{
		const VkImageCreateInfo	colorImageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
			DE_NULL,																	// const void*				pNext;
			0u,																			// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
			m_colorFormat,																// VkFormat					format;
			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
			1u,																			// deUint32					mipLevels;
			1u,																			// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
			1u,																			// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
		};

		m_colorImageCreateInfo	= colorImageParams;
		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);

		// Allocate and bind color image memory
		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkImageViewCreateFlags	flags;
			*m_colorImage,										// VkImage					image;
			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
			m_colorFormat,										// VkFormat					format;
			{VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
		};

		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);

	// Create framebuffer
	{
		const VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkFramebufferCreateFlags	flags;
			*m_renderPass,										// VkRenderPass				renderPass;
			1u,													// deUint32					attachmentCount;
			&m_colorAttachmentView.get(),						// const VkImageView*		pAttachments;
			(deUint32)m_renderSize.x(),							// deUint32					width;
			(deUint32)m_renderSize.y(),							// deUint32					height;
			1u													// deUint32					layers;
		};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkPipelineLayoutCreateFlags		flags;
			0u,													// deUint32							setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
			0u,													// deUint32							pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);

	// Create pipeline
	{
		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,									// deUint32					binding;
			sizeof(Vertex4RGBARGBA),			// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	inputRate;
		};

		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[3]	=
		{
			{
				0u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				0u								// deUint32	offset;
			},
			{
				1u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				(deUint32)(sizeof(float) * 4),	// deUint32	offset;
			},
			{
				2u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				(deUint32)(sizeof(float) * 8),	// deUint32	offset;
			}
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
			1u,																// deUint32									vertexBindingDescriptionCount;
			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			3u,																// deUint32									vertexAttributeDescriptionCount;
			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const std::vector<VkViewport>				viewports							(1, makeViewport(m_renderSize));
		const std::vector<VkRect2D>					scissors							(1, makeRect2D(m_renderSize));

		// The color blend attachment will be set up before creating the graphics pipeline.
		VkPipelineColorBlendStateCreateInfo			colorBlendStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
			DE_NULL,													// const void*									pNext;
			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
			false,														// VkBool32										logicOpEnable;
			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
			0u,															// deUint32										attachmentCount;
			DE_NULL,													// const VkPipelineColorBlendAttachmentState*	pAttachments;
			{															// float										blendConstants[4];
				DualSourceBlendTest::s_blendConst.x(),
				DualSourceBlendTest::s_blendConst.y(),
				DualSourceBlendTest::s_blendConst.z(),
				DualSourceBlendTest::s_blendConst.w()
			}
		};

		for (int quadNdx = 0; quadNdx < DualSourceBlendTest::QUAD_COUNT; quadNdx++)
		{
			colorBlendStateParams.attachmentCount	= 1u;
			colorBlendStateParams.pAttachments		= &m_blendStates[quadNdx];
			m_graphicsPipelines[quadNdx]			= makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
																		   vkDevice,							// const VkDevice                                device
																		   *m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
																		   *m_vertexShaderModule,				// const VkShaderModule                          vertexShaderModule
																		   DE_NULL,								// const VkShaderModule                          tessellationControlModule
																		   DE_NULL,								// const VkShaderModule                          tessellationEvalModule
																		   DE_NULL,								// const VkShaderModule                          geometryShaderModule
																		   *m_fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
																		   *m_renderPass,						// const VkRenderPass                            renderPass
																		   viewports,							// const std::vector<VkViewport>&                viewports
																		   scissors,							// const std::vector<VkRect2D>&                  scissors
																		   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
																		   0u,									// const deUint32                                subpass
																		   0u,									// const deUint32                                patchControlPoints
																		   &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
																		   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
																		   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
																		   DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
																		   &colorBlendStateParams);				// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
		}
	}

	// Create vertex buffer
	{
		const VkBufferCreateInfo vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			1152u,										// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		m_vertices			= createOverlappingQuadsDualSource();
		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));

		// Adjust vertex colors
		if (!isFloatFormat(m_colorFormat))
		{
			const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(mapVkFormat(m_colorFormat));
			for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
			{
				m_vertices[vertexNdx].color0 = (m_vertices[vertexNdx].color0 - formatInfo.lookupBias) / formatInfo.lookupScale;
				m_vertices[vertexNdx].color1 = (m_vertices[vertexNdx].color1 - formatInfo.lookupBias) / formatInfo.lookupScale;
			}
		}

		// Upload vertex data
		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBARGBA));

		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
	}

	// Create command pool
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	{
		const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);

		// Color image layout transition
		const VkImageMemoryBarrier imageLayoutBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType            sType;
			DE_NULL,																// const void*                pNext;
			(VkAccessFlags)0,														// VkAccessFlags              srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,									// VkAccessFlags              dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout              oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,								// VkImageLayout              newLayout;
			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,												// uint32_t                   dstQueueFamilyIndex;
			*m_colorImage,															// VkImage                    image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }							// VkImageSubresourceRange    subresourceRange;
		};

		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vk, *m_cmdBuffer, 0u);

		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
			0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutBarrier);

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);

		const VkDeviceSize quadOffset = (m_vertices.size() / DualSourceBlendTest::QUAD_COUNT) * sizeof(Vertex4RGBARGBA);

		for (int quadNdx = 0; quadNdx < DualSourceBlendTest::QUAD_COUNT; quadNdx++)
		{
			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;

			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DualSourceBlendTest::QUAD_COUNT), 1, 0, 0);
		}

		endRenderPass(vk, *m_cmdBuffer);
		endCommandBuffer(vk, *m_cmdBuffer);
	}
}

DualSourceBlendTestInstance::~DualSourceBlendTestInstance (void)
{
}

tcu::TestStatus DualSourceBlendTestInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	return verifyImage();
}

tcu::TestStatus DualSourceBlendTestInstance::verifyImage (void)
{
	const tcu::TextureFormat			tcuColorFormat		= mapVkFormat(m_colorFormat);
	const tcu::TextureFormat			tcuColorFormat64	= mapVkFormat(VK_FORMAT_R64G64B64A64_SFLOAT);
	const tcu::TextureFormat			tcuColorFormat8		= mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
	const tcu::TextureFormat			tcuDepthFormat		= tcu::TextureFormat(); // Undefined depth/stencil format
	const ColorVertexShaderDualSource	vertexShader;
	const ColorFragmentShaderDualSource	fragmentShader		(tcuColorFormat, tcuDepthFormat);
	const rr::Program					program				(&vertexShader, &fragmentShader);
	ReferenceRenderer					refRenderer			(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
	ReferenceRenderer					refRenderer64		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat64, tcuDepthFormat, &program);
	ReferenceRenderer					refRenderer8		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat8, tcuDepthFormat, &program);
	bool								compareOk			= false;

	// Render reference image
	{
		for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
		{
			const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx];

			// Set blend state
			rr::RenderState renderState					(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
			renderState.fragOps.blendMode				= rr::BLENDMODE_STANDARD;
			renderState.fragOps.blendRGBState.srcFunc	= mapVkBlendFactor(blendState.srcColorBlendFactor);
			renderState.fragOps.blendRGBState.dstFunc	= mapVkBlendFactor(blendState.dstColorBlendFactor);
			renderState.fragOps.blendRGBState.equation	= mapVkBlendOp(blendState.colorBlendOp);
			renderState.fragOps.blendAState.srcFunc		= mapVkBlendFactor(blendState.srcAlphaBlendFactor);
			renderState.fragOps.blendAState.dstFunc		= mapVkBlendFactor(blendState.dstAlphaBlendFactor);
			renderState.fragOps.blendAState.equation	= mapVkBlendOp(blendState.alphaBlendOp);
			renderState.fragOps.blendColor				= DualSourceBlendTest::s_blendConst;
			renderState.fragOps.colorMask				= mapVkColorComponentFlags(DualSourceBlendTest::s_colorWriteMasks[quadNdx]);

			refRenderer.draw(renderState,
							rr::PRIMITIVETYPE_TRIANGLES,
							std::vector<Vertex4RGBARGBA>(m_vertices.begin() + quadNdx * 6,
													 m_vertices.begin() + (quadNdx + 1) * 6));

			if (isLegalExpandableFormat(tcuColorFormat.type))
			{
				refRenderer64.draw(renderState,
								   rr::PRIMITIVETYPE_TRIANGLES,
								   std::vector<Vertex4RGBARGBA>(m_vertices.begin() + quadNdx * 6,
								   m_vertices.begin() + (quadNdx + 1) * 6));

				if (isSmallerThan8BitFormat(tcuColorFormat.type))
					refRenderer8.draw(renderState,
									  rr::PRIMITIVETYPE_TRIANGLES,
									  std::vector<Vertex4RGBARGBA>(m_vertices.begin() + quadNdx * 6,
									  m_vertices.begin() + (quadNdx + 1) * 6));
			}
		}
	}

	// Compare result with reference image
	{
		const DeviceInterface&				vk							= m_context.getDeviceInterface();
		const VkDevice						vkDevice					= m_context.getDevice();
		const VkQueue						queue						= m_context.getUniversalQueue();
		const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
		SimpleAllocator						allocator					(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
		de::UniquePtr<tcu::TextureLevel>	result						(readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
		const tcu::Vec4						threshold					(getFormatThreshold(tcuColorFormat));
		tcu::TextureLevel					refLevel;

		refLevel.setStorage(tcuColorFormat, m_renderSize.x(), m_renderSize.y(), 1);

		compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
											   "FloatImageCompare",
											   "Image comparison",
											   refRenderer.getAccess(),
											   result->getAccess(),
											   threshold,
											   tcu::COMPARE_LOG_RESULT);

		if (isLegalExpandableFormat(tcuColorFormat.type))
		{
			if (!compareOk && isSmallerThan8BitFormat(tcuColorFormat.type))
			{
				// Convert to target format
				tcu::copy(refLevel.getAccess(), refRenderer8.getAccess());

				compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
													   "FloatImageCompare",
													   "Image comparison, 8 bit intermediate format",
													   refLevel.getAccess(),
													   result->getAccess(),
													   threshold,
													   tcu::COMPARE_LOG_RESULT);
			}

			if (!compareOk)
			{
				// Convert to target format
				tcu::copy(refLevel.getAccess(), refRenderer64.getAccess());

				compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
													   "FloatImageCompare",
													   "Image comparison, 64 bit intermediate format",
													   refLevel.getAccess(),
													   result->getAccess(),
													   threshold,
													   tcu::COMPARE_LOG_RESULT);
			}
		}
	}

	if (compareOk)
		return tcu::TestStatus::pass("Result image matches reference");
	else
		return tcu::TestStatus::fail("Image mismatch");
}

// Clamping tests for colors and constants.

struct ClampTestParams
{
	vk::VkFormat	colorFormat;
	tcu::Vec4		quadColor;
	tcu::Vec4		blendConstants;
};

class ClampTest : public vkt::TestCase
{
public:
										ClampTest				(tcu::TestContext&							testContext,
																 const std::string&							name,
																 const std::string&							description,
																 const ClampTestParams&						testParams);
	virtual								~ClampTest				(void) {}
	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
	virtual void						checkSupport			(Context& context) const;
	virtual TestInstance*				createInstance			(Context& context) const;

private:
	const ClampTestParams				m_params;
};

class ClampTestInstance : public vkt::TestInstance
{
public:
								ClampTestInstance		(Context& context, const ClampTestParams& testParams)
									: vkt::TestInstance(context), m_params(testParams)
									{}
	virtual						~ClampTestInstance		(void) {}
	virtual tcu::TestStatus		iterate					(void);

private:
	const ClampTestParams		m_params;
};

ClampTest::ClampTest (tcu::TestContext&			testContext,
					  const std::string&		name,
					  const std::string&		description,
					  const ClampTestParams&	testParams)
	: vkt::TestCase (testContext, name, description)
	, m_params(testParams)
{
	// As per the spec:
	//
	//  If the color attachment is fixed-point, the components of the source and destination values and blend factors are each
	//  clamped to [0,1] or [-1,1] respectively for an unsigned normalized or signed normalized color attachment prior to evaluating
	//  the blend operations. If the color attachment is floating-point, no clamping occurs.
	//
	// We will only test signed and unsigned normalized formats, and avoid precision problems by having all channels have the same
	// bit depth.
	//
	DE_ASSERT(isSnormFormat(m_params.colorFormat) || isUnormFormat(m_params.colorFormat));

	const auto bitDepth = tcu::getTextureFormatBitDepth(mapVkFormat(m_params.colorFormat));
	DE_UNREF(bitDepth); // For release builds.
	DE_ASSERT(bitDepth[0] == bitDepth[1] && bitDepth[0] == bitDepth[2] && bitDepth[0] == bitDepth[3]);
}

void ClampTest::initPrograms (SourceCollections& sourceCollections) const
{
	std::ostringstream fragmentSource;

	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
		"#version 310 es\n"
		"layout(location = 0) in highp vec4 position;\n"
		"layout(location = 1) in highp vec4 color;\n"
		"layout(location = 0) out highp vec4 vtxColor;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = position;\n"
		"	vtxColor = color;\n"
		"}\n");

	fragmentSource << "#version 310 es\n"
		"layout(location = 0) in highp vec4 vtxColor;\n"
		"layout(location = 0) out highp vec4 fragColor;\n"
		"void main (void)\n"
		"{\n"
		"	fragColor = vtxColor;\n"
		"}\n";

	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
}

void ClampTest::checkSupport (Context& context) const
{
	if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.colorFormat))
		throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_params.colorFormat));
}

TestInstance* ClampTest::createInstance(Context& context) const
{
	return new ClampTestInstance(context, m_params);
}

tcu::TestStatus ClampTestInstance::iterate (void)
{
	const vk::DeviceInterface&	vkd					= m_context.getDeviceInterface();
	const vk::VkDevice			device				= m_context.getDevice();
	vk::Allocator&				allocator			= m_context.getDefaultAllocator();
	const vk::VkQueue			queue				= m_context.getUniversalQueue();
	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const vk::VkExtent3D		renderSize			= { 32u, 32u, 1u };

	// Image.
	const vk::VkImageCreateInfo	imageCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
		nullptr,																		// const void*				pNext;
		0u,																				// VkImageCreateFlags		flags;
		vk::VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
		m_params.colorFormat,															// VkFormat					format;
		renderSize,																		// VkExtent3D				extent;
		1u,																				// deUint32					mipLevels;
		1u,																				// deUint32					arrayLayers;
		vk::VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
		vk::VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
		1u,																				// deUint32					queueFamilyIndexCount;
		&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
	};

	vk::ImageWithMemory colorImage (vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any);

	// Image view.
	const vk::VkImageViewCreateInfo imageViewCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
		nullptr,											// const void*				pNext;
		0u,													// VkImageViewCreateFlags	flags;
		colorImage.get(),									// VkImage					image;
		vk::VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
		m_params.colorFormat,								// VkFormat					format;
		{													// VkComponentMapping		components;
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
		},
		{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
	};

	auto colorImageView = createImageView(vkd, device, &imageViewCreateInfo);

	// Render pass.
	auto renderPass = makeRenderPass(vkd, device, m_params.colorFormat);

	// Frame buffer.
	const vk::VkFramebufferCreateInfo framebufferParams =
	{
		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType			sType;
		nullptr,											// const void*				pNext;
		0u,													// VkFramebufferCreateFlags	flags;
		renderPass.get(),									// VkRenderPass				renderPass;
		1u,													// deUint32					attachmentCount;
		&colorImageView.get(),								// const VkImageView*		pAttachments;
		renderSize.width,									// deUint32					width;
		renderSize.height,									// deUint32					height;
		1u,													// deUint32					layers;
	};

	auto framebuffer = createFramebuffer(vkd, device, &framebufferParams);

	// Pipeline layout.
	const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
		nullptr,											// const void*						pNext;
		0u,													// VkPipelineLayoutCreateFlags		flags;
		0u,													// deUint32							setLayoutCount;
		nullptr,											// const VkDescriptorSetLayout*		pSetLayouts;
		0u,													// deUint32							pushConstantRangeCount;
		nullptr,											// const VkPushConstantRange*		pPushConstantRanges;
	};

	auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);

	// Shader modules.
	auto vertexShaderModule		= createShaderModule(vkd, device, m_context.getBinaryCollection().get("color_vert"), 0);
	auto fragmentShaderModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("color_frag"), 0);

	// Graphics pipeline.
	const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
	{
		0u,									// deUint32					binding;
		sizeof(Vertex4RGBA),				// deUint32					strideInBytes;
		vk::VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	inputRate;
	};

	const vk::VkVertexInputAttributeDescription	vertexInputAttributeDescriptions[2]	=
	{
		{
			0u,									// deUint32	location;
			0u,									// deUint32	binding;
			vk::VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
			0u									// deUint32	offset;
		},
		{
			1u,														// deUint32	location;
			0u,														// deUint32	binding;
			vk::VK_FORMAT_R32G32B32A32_SFLOAT,						// VkFormat	format;
			static_cast<deUint32>(offsetof(Vertex4RGBA, color)),	// deUint32	offset;
		},
	};

	const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,					// VkStructureType							sType;
		nullptr,																		// const void*								pNext;
		0u,																				// VkPipelineVertexInputStateCreateFlags	flags;
		1u,																				// deUint32									vertexBindingDescriptionCount;
		&vertexInputBindingDescription,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
		static_cast<deUint32>(DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions)),	// deUint32									vertexAttributeDescriptionCount;
		vertexInputAttributeDescriptions,												// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	const std::vector<vk::VkViewport>	viewports	(1, makeViewport(renderSize));
	const std::vector<vk::VkRect2D>		scissors	(1, makeRect2D(renderSize));

	const vk::VkColorComponentFlags colorComponentFlags = (0u
		| vk::VK_COLOR_COMPONENT_R_BIT
		| vk::VK_COLOR_COMPONENT_G_BIT
		| vk::VK_COLOR_COMPONENT_B_BIT
		| vk::VK_COLOR_COMPONENT_A_BIT
	);

	// Color blend attachment state. Central aspect of the test.
	const vk::VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
	{
		VK_TRUE,							// VkBool32					blendEnable;
		vk::VK_BLEND_FACTOR_CONSTANT_COLOR,	// VkBlendFactor			srcColorBlendFactor;
		vk::VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
		vk::VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
		vk::VK_BLEND_FACTOR_CONSTANT_ALPHA,	// VkBlendFactor			srcAlphaBlendFactor;
		vk::VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
		vk::VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
		colorComponentFlags,				// VkColorComponentFlags	colorWriteMask;
	};

	const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		nullptr,														// const void*									pNext;
		0u,																// VkPipelineColorBlendStateCreateFlags			flags;
		false,															// VkBool32										logicOpEnable;
		vk::VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		1u,																// deUint32										attachmentCount;
		&colorBlendAttachmentState,										// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{																// float										blendConstants[4];
			m_params.blendConstants[0],
			m_params.blendConstants[1],
			m_params.blendConstants[2],
			m_params.blendConstants[3],
		},
	};

	auto graphicsPipeline = makeGraphicsPipeline(
		vkd,										// const DeviceInterface&                        vk
		device,										// const VkDevice                                device
		pipelineLayout.get(),						// const VkPipelineLayout                        pipelineLayout
		vertexShaderModule.get(),					// const VkShaderModule                          vertexShaderModule
		DE_NULL,									// const VkShaderModule                          tessellationControlModule
		DE_NULL,									// const VkShaderModule                          tessellationEvalModule
		DE_NULL,									// const VkShaderModule                          geometryShaderModule
		fragmentShaderModule.get(),					// const VkShaderModule                          fragmentShaderModule
		renderPass.get(),							// const VkRenderPass                            renderPass
		viewports,									// const std::vector<VkViewport>&                viewports
		scissors,									// const std::vector<VkRect2D>&                  scissors
		vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
		0u,											// const deUint32                                subpass
		0u,											// const deUint32                                patchControlPoints
		&vertexInputStateParams,					// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
		nullptr,									// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
		nullptr,									// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
		nullptr,									// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
		&colorBlendStateParams);					// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo

	// Vertex buffer
	auto						quadTexture = createFullscreenQuad();
	std::vector<Vertex4RGBA>	vertices;

	// Keep position but replace texture coordinates with our own color.
	vertices.reserve(quadTexture.size());
	std::transform(begin(quadTexture), end(quadTexture), std::back_inserter(vertices),
		[this](const decltype(quadTexture)::value_type& v) { return Vertex4RGBA{ v.position, this->m_params.quadColor }; });

	const vk::VkDeviceSize			vtxBufferSize		= static_cast<vk::VkDeviceSize>(vertices.size() * sizeof(decltype(vertices)::value_type));
	const vk::VkBufferCreateInfo	bufferCreateInfo	=
	{
		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
		nullptr,									// const void*			pNext;
		0u,											// VkBufferCreateFlags	flags;
		vtxBufferSize,								// VkDeviceSize			size;
		vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
		1u,											// deUint32				queueFamilyIndexCount;
		&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
	};

	vk::BufferWithMemory vertexBuffer(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible);

	// Upload vertex data
	deMemcpy(vertexBuffer.getAllocation().getHostPtr(), vertices.data(), static_cast<size_t>(vtxBufferSize));
	flushAlloc(vkd, device, vertexBuffer.getAllocation());

	// Create command pool
	auto cmdPool = createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create and record command buffer
	auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	auto cmdBuffer		= cmdBufferPtr.get();

	vk::VkClearValue clearValue;
	clearValue.color.float32[0] = 0.0f;
	clearValue.color.float32[1] = 0.0f;
	clearValue.color.float32[2] = 0.0f;
	clearValue.color.float32[3] = 1.0f;

	const vk::VkDeviceSize vertexOffets[] = { 0u };

	beginCommandBuffer(vkd, cmdBuffer, 0u);
		beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(renderSize), clearValue);
			vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
			vkd.cmdBindVertexBuffers(cmdBuffer, 0, 1u, &vertexBuffer.get(), vertexOffets);
			vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1, 0, 0);
		endRenderPass(vkd, cmdBuffer);
	endCommandBuffer(vkd, cmdBuffer);

	// Submit commands.
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Calculate reference final color.
	const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_params.colorFormat);
	const auto					formatInfo		= tcu::getTextureFormatInfo(tcuColorFormat);

	tcu::Vec4 clampedBlendConstants	= m_params.blendConstants;
	tcu::Vec4 clampedQuadColor		= m_params.quadColor;

	for (int i = 0; i < tcu::Vec4::SIZE; ++i)
	{
		clampedBlendConstants[i]	= de::clamp(clampedBlendConstants[i],	formatInfo.valueMin[i], formatInfo.valueMax[i]);
		clampedQuadColor[i]			= de::clamp(clampedQuadColor[i],		formatInfo.valueMin[i], formatInfo.valueMax[i]);
	}

	tcu::Vec4 referenceColor;
	for (int i = 0; i < tcu::Vec4::SIZE; ++i)
		referenceColor[i] = clampedBlendConstants[i] * clampedQuadColor[i];

	// Compare result with reference color
	const tcu::UVec2					renderSizeUV2		(renderSize.width, renderSize.height);
	de::UniquePtr<tcu::TextureLevel>	result				(readColorAttachment(vkd, device, queue, queueFamilyIndex, allocator, colorImage.get(), m_params.colorFormat, renderSizeUV2).release());
	const tcu::Vec4						threshold			(getFormatThreshold(tcuColorFormat));
	const tcu::ConstPixelBufferAccess	pixelBufferAccess	= result->getAccess();

	const bool compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "BlendClampCompare", "Blend clamping pixel comparison", referenceColor, pixelBufferAccess, threshold, tcu::COMPARE_LOG_ON_ERROR);

	if (compareOk)
		return tcu::TestStatus::pass("Pass");
	else
		return tcu::TestStatus::fail("Pixel mismatch");
}

} // anonymous

std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState)
{
	const char* shortBlendFactorNames[] =
	{
		"z",		// VK_BLEND_ZERO
		"o",		// VK_BLEND_ONE
		"sc",		// VK_BLEND_SRC_COLOR
		"1msc",		// VK_BLEND_ONE_MINUS_SRC_COLOR
		"dc",		// VK_BLEND_DEST_COLOR
		"1mdc",		// VK_BLEND_ONE_MINUS_DEST_COLOR
		"sa",		// VK_BLEND_SRC_ALPHA
		"1msa",		// VK_BLEND_ONE_MINUS_SRC_ALPHA
		"da",		// VK_BLEND_DEST_ALPHA
		"1mda",		// VK_BLEND_ONE_MINUS_DEST_ALPHA
		"cc",		// VK_BLEND_CONSTANT_COLOR
		"1mcc",		// VK_BLEND_ONE_MINUS_CONSTANT_COLOR
		"ca",		// VK_BLEND_CONSTANT_ALPHA
		"1mca",		// VK_BLEND_ONE_MINUS_CONSTANT_ALPHA
		"sas",		// VK_BLEND_SRC_ALPHA_SATURATE
		"1ms1c",	// VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR
		"1ms1a",	// VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
		"s1c",		// VK_BLEND_FACTOR_SRC1_COLOR
		"s1a"		// VK_BLEND_FACTOR_SRC1_ALPHA
	};

	const char* blendOpNames[] =
	{
		"add",		// VK_BLEND_OP_ADD
		"sub",		// VK_BLEND_OP_SUBTRACT
		"rsub",		// VK_BLEND_OP_REVERSE_SUBTRACT
		"min",		// VK_BLEND_OP_MIN
		"max",		// VK_BLEND_OP_MAX
	};

	std::ostringstream shortName;

	shortName << "color_" << shortBlendFactorNames[blendState.srcColorBlendFactor] << "_" << shortBlendFactorNames[blendState.dstColorBlendFactor] << "_" << blendOpNames[blendState.colorBlendOp];
	shortName << "_alpha_" << shortBlendFactorNames[blendState.srcAlphaBlendFactor] << "_" << shortBlendFactorNames[blendState.dstAlphaBlendFactor] << "_" << blendOpNames[blendState.alphaBlendOp];

	return shortName.str();
}

std::string getBlendStateSetName (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
{
	std::ostringstream name;

	for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
	{
		name << getBlendStateName(blendStates[quadNdx]);

		if (quadNdx < BlendTest::QUAD_COUNT - 1)
			name << "-";
	}

	return name.str();
}

std::string getBlendStateSetDescription (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
{
	std::ostringstream description;

	description << "Draws " << BlendTest::QUAD_COUNT << " quads with the following blend states:\n";

	for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
		description << blendStates[quadNdx] << "\n";

	return description.str();
}

std::string getFormatCaseName (VkFormat format)
{
	const std::string fullName = getFormatName(format);

	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));

	return de::toLower(fullName.substr(10));
}

tcu::TestCaseGroup* createBlendTests (tcu::TestContext& testCtx)
{
	const deUint32 blendStatesPerFormat = 100 * BlendTest::QUAD_COUNT;

	// Formats that are dEQP-compatible, non-integer and uncompressed
	const VkFormat blendFormats[] =
	{
		VK_FORMAT_R4G4_UNORM_PACK8,
		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_SRGB,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_SRGB,
		VK_FORMAT_R8G8B8_UNORM,
		VK_FORMAT_R8G8B8_SNORM,
		VK_FORMAT_R8G8B8_SRGB,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_R16_UNORM,
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UNORM,
		VK_FORMAT_R16G16_SNORM,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16_UNORM,
		VK_FORMAT_R16G16B16_SNORM,
		VK_FORMAT_R16G16B16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UNORM,
		VK_FORMAT_R16G16B16A16_SNORM,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32_SFLOAT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
	};

	de::MovePtr<tcu::TestCaseGroup>				blendTests				(new tcu::TestCaseGroup(testCtx, "blend", "Blend tests"));
	de::MovePtr<tcu::TestCaseGroup>				formatTests				(new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats"));
	de::MovePtr<tcu::TestCaseGroup>				clampTests				(new tcu::TestCaseGroup(testCtx, "clamp", "Verifies clamping for normalized formats"));
	de::MovePtr<tcu::TestCaseGroup>				dualSourceBlendTests	(new tcu::TestCaseGroup(testCtx, "dual_source", "Blend tests taking into account dual-source blend factors"));
	de::MovePtr<tcu::TestCaseGroup>				dualSourceFormatTests	(new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats"));


	BlendStateUniqueRandomIterator				blendStateItr			(blendStatesPerFormat, 123);
	BlendStateUniqueRandomIteratorDualSource	dualSourceBlendStateItr	(blendStatesPerFormat, 123);

	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++)
	{
		const VkFormat					format			= blendFormats[formatNdx];

		// Blend tests
		{
			de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
																					getFormatCaseName(format).c_str(),
																					(std::string("Uses format ") + getFormatName(format)).c_str()));
			de::MovePtr<tcu::TestCaseGroup>	blendStateTests;
			{
				std::ostringstream blendStateDescription;
				blendStateDescription << "Combines blend factors, operators and channel write masks. The constant color used in all tests is " << BlendTest::s_blendConst;
				blendStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", blendStateDescription.str().c_str()));
			}

			blendStateItr.reset();

			while (blendStateItr.hasNext())
			{
				VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT];

				for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
				{
					quadBlendConfigs[quadNdx]					= blendStateItr.next();
					quadBlendConfigs[quadNdx].colorWriteMask	= BlendTest::s_colorWriteMasks[quadNdx];
				}

				blendStateTests->addChild(new BlendTest(testCtx,
														getBlendStateSetName(quadBlendConfigs),
														getBlendStateSetDescription(quadBlendConfigs),
														format,
														quadBlendConfigs));
			}
			formatTest->addChild(blendStateTests.release());
			formatTests->addChild(formatTest.release());
		}

		// Dual-Source blending tests
		{
			de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
																					getFormatCaseName(format).c_str(),
																					(std::string("Uses format ") + getFormatName(format)).c_str()));
			de::MovePtr<tcu::TestCaseGroup>	blendStateTests;
			{
				std::ostringstream blendStateDescription;
				blendStateDescription << "Combines blend factors, operators and channel write masks. The constant color used in all tests is " << BlendTest::s_blendConst;
				blendStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", blendStateDescription.str().c_str()));
			}

			dualSourceBlendStateItr.reset();

			while (dualSourceBlendStateItr.hasNext())
			{
				VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT];
				deBool isDualSourceBlendTest = DE_FALSE;
				for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
				{
					quadBlendConfigs[quadNdx]					= dualSourceBlendStateItr.next();
					quadBlendConfigs[quadNdx].colorWriteMask	= BlendTest::s_colorWriteMasks[quadNdx];
					isDualSourceBlendTest =
						isDualSourceBlendTest ||
						isSrc1BlendFactor(quadBlendConfigs[quadNdx].srcColorBlendFactor) ||
						isSrc1BlendFactor(quadBlendConfigs[quadNdx].dstColorBlendFactor) ||
						isSrc1BlendFactor(quadBlendConfigs[quadNdx].srcAlphaBlendFactor) ||
						isSrc1BlendFactor(quadBlendConfigs[quadNdx].dstAlphaBlendFactor);
				}

				// Skip tests that don't have dual-source blend factors as they are already tested.
				if (!isDualSourceBlendTest)
					continue;

				blendStateTests->addChild(new DualSourceBlendTest(testCtx,
																  getBlendStateSetName(quadBlendConfigs),
																  getBlendStateSetDescription(quadBlendConfigs),
																  format,
																  quadBlendConfigs));
			}
			formatTest->addChild(blendStateTests.release());
			dualSourceFormatTests->addChild(formatTest.release());
		}
	}

	// Subselection of formats that are easy to test for clamping.
	const vk::VkFormat clampFormats[] =
	{
		vk::VK_FORMAT_R8G8B8A8_UNORM,
		vk::VK_FORMAT_R8G8B8A8_SNORM,
		vk::VK_FORMAT_B8G8R8A8_UNORM,
		vk::VK_FORMAT_B8G8R8A8_SNORM,
		vk::VK_FORMAT_R16G16B16A16_UNORM,
		vk::VK_FORMAT_R16G16B16A16_SNORM,
	};

	for (int formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(clampFormats); ++formatIdx)
	{
		const auto& format = clampFormats[formatIdx];
		ClampTestParams testParams;

		testParams.colorFormat = format;

		if (isUnormFormat(format))
		{
			testParams.quadColor[0] = 2.0f;
			testParams.quadColor[1] = 0.5f;
			testParams.quadColor[2] = 1.0f;
			testParams.quadColor[3] = -1.0f;

			testParams.blendConstants[0] = 0.5f;
			testParams.blendConstants[1] = 2.0f;
			testParams.blendConstants[2] = -1.0f;
			testParams.blendConstants[3] = 1.0f;
		}
		else
		{
			testParams.quadColor[0] = 2.0f;
			testParams.quadColor[1] = 0.5f;
			testParams.quadColor[2] = 1.0f;
			testParams.quadColor[3] = -2.0f;

			testParams.blendConstants[0] = 0.5f;
			testParams.blendConstants[1] = 2.0f;
			testParams.blendConstants[2] = -2.0f;
			testParams.blendConstants[3] = 1.0f;
		}

		clampTests->addChild(new ClampTest(testCtx, getFormatCaseName(format), std::string("Using format ") + getFormatName(format), testParams));
	}

	blendTests->addChild(formatTests.release());
	blendTests->addChild(clampTests.release());

	dualSourceBlendTests->addChild(dualSourceFormatTests.release());
	blendTests->addChild(dualSourceBlendTests.release());

	return blendTests.release();
}

} // pipeline
} // vkt
