/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 Valve Corporation.
 * Copyright (c) 2019 The Khronos Group Inc.
 *
 * 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 VK_EXT_blend_operation_advanced tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineBlendOperationAdvancedTests.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineReferenceRenderer.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{
using tcu::Vec3;
using tcu::Vec4;

const deUint32 widthArea	= 32u;
const deUint32 heightArea	= 32u;

static const float A1 = 0.750f; // Between 1    and 0.5
static const float A2 = 0.375f; // Between 0.5  and 0.25
static const float A3 = 0.125f; // Between 0.25 and 0.0

const Vec4 srcColors[] = {
					   // Test that pre-multiplied is converted correctly.
					   // Should not test invalid premultiplied colours (1, 1, 1, 0).
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },

					   // Test clamping.
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },

					   // Combinations that test other branches of blend equations.
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },
					   { 1.000f, 0.750f, 0.500f, 1.00f },
					   { 0.250f, 0.125f, 0.000f, 1.00f },

					   // Above block with few different pre-multiplied alpha values.
					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},
					   { 1.000f * A1, 0.750f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.125f * A1, 0.000f * A1, 1.00f * A1},

					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},
					   { 1.000f * A2, 0.750f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.125f * A2, 0.000f * A2, 1.00f * A2},

					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},
					   { 1.000f * A3, 0.750f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.250f * A3, 0.125f * A3, 0.000f * A3, 1.00f * A3},

					   // Add some source colors with alpha component that is different than the respective destination color
					   { 0.750f, 0.750f, 0.500f, 0.750f },
					   { 0.250f, 0.500f, 0.500f, 0.750f },
					   { 0.250f, 0.125f, 0.000f, 0.500f },
					   { 0.250f, 0.250f, 0.500f, 0.500f },
					   { 0.250f, 0.125f, 0.000f, 0.250f },
					   { 0.125f, 0.125f, 0.125f, 0.250f }};

const Vec4 dstColors[] = {
					   // Test that pre-multiplied is converted correctly.
					   // Should not test invalid premultiplied colours (1, 1, 1, 0).
					   { 0.000f, 0.000f, 0.000f, 0.00f },
					   { 0.000f, 0.000f, 0.000f, 0.00f },

					   // Test clamping.
					   { -0.125f, -0.125f, -0.125f, 1.00f },
					   { -0.125f, -0.125f, -0.125f, 1.00f },
					   {  1.125f,  1.125f,  1.125f, 1.00f },
					   {  1.125f,  1.125f,  1.125f, 1.00f },

					   // Combinations that test other branches of blend equations.
					   { 1.000f, 1.000f, 1.000f, 1.00f },
					   { 1.000f, 1.000f, 1.000f, 1.00f },
					   { 0.500f, 0.500f, 0.500f, 1.00f },
					   { 0.500f, 0.500f, 0.500f, 1.00f },
					   { 0.250f, 0.250f, 0.250f, 1.00f },
					   { 0.250f, 0.250f, 0.250f, 1.00f },
					   { 0.125f, 0.125f, 0.125f, 1.00f },
					   { 0.125f, 0.125f, 0.125f, 1.00f },
					   { 0.000f, 0.000f, 0.000f, 1.00f },
					   { 0.000f, 0.000f, 0.000f, 1.00f },

					   // Above block with few different pre-multiplied alpha values.
					   { 1.000f * A1, 1.000f * A1, 1.000f * A1, 1.00f * A1},
					   { 1.000f * A1, 1.000f * A1, 1.000f * A1, 1.00f * A1},
					   { 0.500f * A1, 0.500f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.500f * A1, 0.500f * A1, 0.500f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.250f * A1, 0.250f * A1, 1.00f * A1},
					   { 0.250f * A1, 0.250f * A1, 0.250f * A1, 1.00f * A1},
					   { 0.125f * A1, 0.125f * A1, 0.125f * A1, 1.00f * A1},
					   { 0.125f * A1, 0.125f * A1, 0.125f * A1, 1.00f * A1},
					   { 0.000f * A1, 0.000f * A1, 0.000f * A1, 1.00f * A1},
					   { 0.000f * A1, 0.000f * A1, 0.000f * A1, 1.00f * A1},

					   { 1.000f * A2, 1.000f * A2, 1.000f * A2, 1.00f * A2},
					   { 1.000f * A2, 1.000f * A2, 1.000f * A2, 1.00f * A2},
					   { 0.500f * A2, 0.500f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.500f * A2, 0.500f * A2, 0.500f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.250f * A2, 0.250f * A2, 1.00f * A2},
					   { 0.250f * A2, 0.250f * A2, 0.250f * A2, 1.00f * A2},
					   { 0.125f * A2, 0.125f * A2, 0.125f * A2, 1.00f * A2},
					   { 0.125f * A2, 0.125f * A2, 0.125f * A2, 1.00f * A2},
					   { 0.000f * A2, 0.000f * A2, 0.000f * A2, 1.00f * A2},
					   { 0.000f * A2, 0.000f * A2, 0.000f * A2, 1.00f * A2},

					   { 1.000f * A3, 1.000f * A3, 1.000f * A3, 1.00f * A3},
					   { 1.000f * A3, 1.000f * A3, 1.000f * A3, 1.00f * A3},
					   { 0.500f * A3, 0.500f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.500f * A3, 0.500f * A3, 0.500f * A3, 1.00f * A3},
					   { 0.250f * A3, 0.250f * A3, 0.250f * A3, 1.00f * A3 },
					   { 0.250f * A3, 0.250f * A3, 0.250f * A3, 1.00f * A3 },
					   { 0.125f * A3, 0.125f * A3, 0.125f * A3, 1.00f * A3 },
					   { 0.125f * A3, 0.125f * A3, 0.125f * A3, 1.00f * A3 },
					   { 0.000f * A3, 0.000f * A3, 0.000f * A3, 1.00f * A3 },
					   { 0.000f * A3, 0.000f * A3, 0.000f * A3, 1.00f * A3 },

					   // Add some source colors with alpha component that is different than the respective source color
					   { 1.000f, 1.000f, 1.000f, 1.000f },
					   { 0.250f, 0.250f, 0.250f, 0.500f },
					   { 0.500f, 0.500f, 0.500f, 0.750f },
					   { 0.250f, 0.250f, 0.250f, 0.250f },
					   { 0.250f, 0.250f, 0.250f, 0.500f },
					   { 0.125f, 0.125f, 0.125f, 0.125f }};

const	Vec4	clearColorVec4  (1.0f, 1.0f, 1.0f, 1.0f);

enum TestMode
{
	TEST_MODE_GENERIC = 0,
	TEST_MODE_COHERENT = 1,
};

struct BlendOperationAdvancedParam
{
	TestMode						testMode;
	deUint32						testNumber;
	std::vector<VkBlendOp>			blendOps;
	deBool							coherentOperations;
	deBool							independentBlend;
	deUint32						colorAttachmentsCount;
	VkBool32						premultipliedSrcColor;
	VkBool32						premultipliedDstColor;
	VkBlendOverlapEXT				overlap;
};

// helper functions
const std::string generateTestName (struct BlendOperationAdvancedParam param)
{
	std::ostringstream result;

	result << ((param.testMode == TEST_MODE_COHERENT && !param.coherentOperations) ? "barrier_" : "");
	result << "color_attachments_" << param.colorAttachmentsCount;
	result << "_" << de::toLower(getBlendOverlapEXTStr(param.overlap).toString().substr(3));
	result << (!param.premultipliedSrcColor ? "_nonpremultipliedsrc" : "");
	result << (!param.premultipliedDstColor ? "_nonpremultiplieddst" : "");
	result << "_" << param.testNumber;
	return result.str();
}

const std::string generateTestDescription ()
{
	std::string result("Test advanced blend operations");
	return result;
}

Vec3 calculateWeightingFactors(BlendOperationAdvancedParam param,
									float alphaSrc, float alphaDst)
{
	Vec3 p = Vec3(0.0f, 0.0f, 0.0f);
	switch(param.overlap)
	{
	case VK_BLEND_OVERLAP_UNCORRELATED_EXT:
		p.x() = alphaSrc * alphaDst;
		p.y() = alphaSrc * (1.0f - alphaDst);
		p.z() = alphaDst * (1.0f - alphaSrc);
		break;
	case VK_BLEND_OVERLAP_CONJOINT_EXT:
		p.x() = deFloatMin(alphaSrc, alphaDst);
		p.y() = deFloatMax(alphaSrc - alphaDst, 0.0f);
		p.z() = deFloatMax(alphaDst - alphaSrc, 0.0f);
		break;
	case VK_BLEND_OVERLAP_DISJOINT_EXT:
		p.x() = deFloatMax(alphaSrc + alphaDst - 1.0f, 0.0f);
		p.y() = deFloatMin(alphaSrc, 1.0f - alphaDst);
		p.z() = deFloatMin(alphaDst, 1.0f - alphaSrc);
		break;
	default:
		DE_FATAL("Unsupported Advanced Blend Overlap Mode");
	};
	return p;
}

	Vec3 calculateXYZFactors(VkBlendOp op)
{
	Vec3 xyz = Vec3(0.0f, 0.0f, 0.0f);
	switch (op)
	{
	case VK_BLEND_OP_ZERO_EXT:
		xyz = Vec3(0.0f, 0.0f, 0.0f);
		break;

	case VK_BLEND_OP_DST_ATOP_EXT:
	case VK_BLEND_OP_SRC_EXT:
		xyz = Vec3(1.0f, 1.0f, 0.0f);
		break;

	case VK_BLEND_OP_DST_EXT:
		xyz = Vec3(1.0f, 0.0f, 1.0f);
		break;

	case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
	case VK_BLEND_OP_HSL_COLOR_EXT:
	case VK_BLEND_OP_HSL_SATURATION_EXT:
	case VK_BLEND_OP_HSL_HUE_EXT:
	case VK_BLEND_OP_HARDMIX_EXT:
	case VK_BLEND_OP_PINLIGHT_EXT:
	case VK_BLEND_OP_LINEARLIGHT_EXT:
	case VK_BLEND_OP_VIVIDLIGHT_EXT:
	case VK_BLEND_OP_LINEARBURN_EXT:
	case VK_BLEND_OP_LINEARDODGE_EXT:
	case VK_BLEND_OP_EXCLUSION_EXT:
	case VK_BLEND_OP_DIFFERENCE_EXT:
	case VK_BLEND_OP_SOFTLIGHT_EXT:
	case VK_BLEND_OP_HARDLIGHT_EXT:
	case VK_BLEND_OP_COLORBURN_EXT:
	case VK_BLEND_OP_COLORDODGE_EXT:
	case VK_BLEND_OP_LIGHTEN_EXT:
	case VK_BLEND_OP_DARKEN_EXT:
	case VK_BLEND_OP_OVERLAY_EXT:
	case VK_BLEND_OP_SCREEN_EXT:
	case VK_BLEND_OP_MULTIPLY_EXT:
	case VK_BLEND_OP_SRC_OVER_EXT:
	case VK_BLEND_OP_DST_OVER_EXT:
		xyz = Vec3(1.0f, 1.0f, 1.0f);
		break;

	case VK_BLEND_OP_SRC_IN_EXT:
	case VK_BLEND_OP_DST_IN_EXT:
		xyz = Vec3(1.0f, 0.0f, 0.0f);
		break;

	case VK_BLEND_OP_SRC_OUT_EXT:
		xyz = Vec3(0.0f, 1.0f, 0.0f);
		break;

	case VK_BLEND_OP_DST_OUT_EXT:
		xyz = Vec3(0.0f, 0.0f, 1.0f);
		break;

	case VK_BLEND_OP_INVERT_RGB_EXT:
	case VK_BLEND_OP_INVERT_EXT:
	case VK_BLEND_OP_SRC_ATOP_EXT:
		xyz = Vec3(1.0f, 0.0f, 1.0f);
		break;

	case VK_BLEND_OP_XOR_EXT:
		xyz = Vec3(0.0f, 1.0f, 1.0f);
		break;

	default:
		DE_FATAL("Unsupported f/X/Y/Z Advanced Blend Operations Mode");
	};

	return xyz;
}

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

float blendOpColorDodge(float src, float dst)
{
	if (dst <= 0.0f)
		return 0.0f;
	else if (src < 1.0f)
		return deFloatMin(1.0f, (dst / (1.0f - src)));
	else
		return 1.0f;
}

float blendOpColorBurn(float src, float dst)
{
	if (dst >= 1.0f)
		return 1.0f;
	else if (src > 0.0f)
		return 1.0f - deFloatMin(1.0f, (1.0f - dst) / src);
	else
		return 0.0f;
}

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

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

float blendOpLinearDodge(float src, float dst)
{
	if ((src + dst) <= 1.0f)
		return src + dst;
	else
		return 1.0f;
}

float blendOpLinearBurn(float src, float dst)
{
	if ((src + dst) > 1.0f)
		return src + dst - 1.0f;
	else
		return 0.0f;
}

float blendOpVividLight(float src, float dst)
{
	if (src <= 0.0f)
		return 0.0f;
	if (src < 0.5f)
		return 1.0f - (deFloatMin(1.0f, (1.0f - dst) / (2.0f * src)));
	if (src < 1.0f)
		return deFloatMin(1.0f, dst / (2.0f * (1.0f - src)));
	else
		return 1.0f;
}

float blendOpLinearLight(float src, float dst)
{
	if ((2.0f * src + dst) > 2.0f)
		return 1.0f;
	if ((2.0f * src + dst) <= 1.0f)
		return 0.0f;
	return (2.0f * src) + dst - 1.0f;
}

float blendOpPinLight(float src, float dst)
{
	if (((2.0f * src - 1.0f) > dst) && src < 0.5f)
		return 0.0f;
	if (((2.0f * src - 1.0f) > dst) && src >= 0.5f)
		return 2.0f * src - 1.0f;
	if (((2.0f * src - 1.0f) <= dst) && src < (0.5f * dst))
		return 2.0f * src;
	if (((2.0f * src - 1.0f) <= dst) && src >= (0.5f * dst))
		return dst;
	return 0.0f;
}

float blendOpHardmix(float src, float dst)
{
	if ((src + dst) < 1.0f)
		return 0.0f;
	else
		return 1.0f;
}

float minv3(Vec3 c)
{
	return deFloatMin(deFloatMin(c.x(), c.y()), c.z());
}

float maxv3(Vec3 c)
{
	return deFloatMax(deFloatMax(c.x(), c.y()), c.z());
}

float lumv3(Vec3 c)
{
	return dot(c, Vec3(0.3f, 0.59f, 0.11f));
}

float satv3(Vec3 c)
{
	return maxv3(c) - minv3(c);
}

// If any color components are outside [0,1], adjust the color to
// get the components in range.
Vec3 clipColor(Vec3 color)
{
	float lum = lumv3(color);
	float mincol = minv3(color);
	float maxcol = maxv3(color);

	if (mincol < 0.0)
	{
		color = lum + ((color - lum) * lum) / (lum - mincol);
	}
	if (maxcol > 1.0)
	{
		color = lum + ((color - lum) * (1.0f - lum)) / (maxcol - lum);
	}
	return color;
}

// Take the base RGB color <cbase> and override its luminosity
// with that of the RGB color <clum>.
Vec3 setLum(Vec3 cbase, Vec3 clum)
{
	float lbase = lumv3(cbase);
	float llum = lumv3(clum);
	float ldiff = llum - lbase;

	Vec3 color = cbase + Vec3(ldiff);
	return clipColor(color);
}

// Take the base RGB color <cbase> and override its saturation with
// that of the RGB color <csat>.  The override the luminosity of the
// result with that of the RGB color <clum>.
Vec3 setLumSat(Vec3 cbase, Vec3 csat, Vec3 clum)
{
	float minbase = minv3(cbase);
	float sbase = satv3(cbase);
	float ssat = satv3(csat);
	Vec3 color;

	if (sbase > 0)
	{
		// Equivalent (modulo rounding errors) to setting the
		// smallest (R,G,B) component to 0, the largest to <ssat>,
		// and interpolating the "middle" component based on its
		// original value relative to the smallest/largest.
		color = (cbase - minbase) * ssat / sbase;
	} else {
		color = Vec3(0.0f);
	}
	return setLum(color, clum);
}

Vec3 calculateFFunction(VkBlendOp op,
						Vec3 src, Vec3 dst)
{
	Vec3 f = Vec3(0.0f, 0.0f, 0.0f);

	switch (op)
	{
	case VK_BLEND_OP_XOR_EXT:
	case VK_BLEND_OP_SRC_OUT_EXT:
	case VK_BLEND_OP_DST_OUT_EXT:
	case VK_BLEND_OP_ZERO_EXT:
		f = Vec3(0.0f, 0.0f, 0.0f);
		break;

	case VK_BLEND_OP_SRC_ATOP_EXT:
	case VK_BLEND_OP_SRC_IN_EXT:
	case VK_BLEND_OP_SRC_OVER_EXT:
	case VK_BLEND_OP_SRC_EXT:
		f = src;
		break;

	case VK_BLEND_OP_DST_ATOP_EXT:
	case VK_BLEND_OP_DST_IN_EXT:
	case VK_BLEND_OP_DST_OVER_EXT:
	case VK_BLEND_OP_DST_EXT:
		f = dst;
		break;

	case VK_BLEND_OP_MULTIPLY_EXT:
		f = src * dst;
		break;

	case VK_BLEND_OP_SCREEN_EXT:
		f = src + dst - (src*dst);
		break;

	case VK_BLEND_OP_OVERLAY_EXT:
		f.x() = blendOpOverlay(src.x(), dst.x());
		f.y() = blendOpOverlay(src.y(), dst.y());
		f.z() = blendOpOverlay(src.z(), dst.z());
		break;

	case VK_BLEND_OP_DARKEN_EXT:
		f.x() = deFloatMin(src.x(), dst.x());
		f.y() = deFloatMin(src.y(), dst.y());
		f.z() = deFloatMin(src.z(), dst.z());
		break;

	case VK_BLEND_OP_LIGHTEN_EXT:
		f.x() = deFloatMax(src.x(), dst.x());
		f.y() = deFloatMax(src.y(), dst.y());
		f.z() = deFloatMax(src.z(), dst.z());
		break;

	case VK_BLEND_OP_COLORDODGE_EXT:
		f.x() = blendOpColorDodge(src.x(), dst.x());
		f.y() = blendOpColorDodge(src.y(), dst.y());
		f.z() = blendOpColorDodge(src.z(), dst.z());
		break;

	case VK_BLEND_OP_COLORBURN_EXT:
		f.x() = blendOpColorBurn(src.x(), dst.x());
		f.y() = blendOpColorBurn(src.y(), dst.y());
		f.z() = blendOpColorBurn(src.z(), dst.z());
		break;

	case VK_BLEND_OP_HARDLIGHT_EXT:
		f.x() = blendOpHardlight(src.x(), dst.x());
		f.y() = blendOpHardlight(src.y(), dst.y());
		f.z() = blendOpHardlight(src.z(), dst.z());
		break;

	case VK_BLEND_OP_SOFTLIGHT_EXT:
		f.x() = blendOpSoftlight(src.x(), dst.x());
		f.y() = blendOpSoftlight(src.y(), dst.y());
		f.z() = blendOpSoftlight(src.z(), dst.z());
		break;

	case VK_BLEND_OP_DIFFERENCE_EXT:
		f.x() = deFloatAbs(dst.x() - src.x());
		f.y() = deFloatAbs(dst.y() - src.y());
		f.z() = deFloatAbs(dst.z() - src.z());
		break;


	case VK_BLEND_OP_EXCLUSION_EXT:
		f = src + dst - (2.0f * src * dst);
		break;

	case VK_BLEND_OP_INVERT_EXT:
		f = 1.0f - dst;
		break;

	case VK_BLEND_OP_INVERT_RGB_EXT:
		f = src * (1.0f - dst);
		break;

	case VK_BLEND_OP_LINEARDODGE_EXT:
		f.x() = blendOpLinearDodge(src.x(), dst.x());
		f.y() = blendOpLinearDodge(src.y(), dst.y());
		f.z() = blendOpLinearDodge(src.z(), dst.z());
		break;

	case VK_BLEND_OP_LINEARBURN_EXT:
		f.x() = blendOpLinearBurn(src.x(), dst.x());
		f.y() = blendOpLinearBurn(src.y(), dst.y());
		f.z() = blendOpLinearBurn(src.z(), dst.z());
		break;

	case VK_BLEND_OP_VIVIDLIGHT_EXT:
		f.x() = blendOpVividLight(src.x(), dst.x());
		f.y() = blendOpVividLight(src.y(), dst.y());
		f.z() = blendOpVividLight(src.z(), dst.z());
		break;

	case VK_BLEND_OP_LINEARLIGHT_EXT:
		f.x() = blendOpLinearLight(src.x(), dst.x());
		f.y() = blendOpLinearLight(src.y(), dst.y());
		f.z() = blendOpLinearLight(src.z(), dst.z());
		break;

	case VK_BLEND_OP_PINLIGHT_EXT:
		f.x() = blendOpPinLight(src.x(), dst.x());
		f.y() = blendOpPinLight(src.y(), dst.y());
		f.z() = blendOpPinLight(src.z(), dst.z());
		break;

	case VK_BLEND_OP_HARDMIX_EXT:
		f.x() = blendOpHardmix(src.x(), dst.x());
		f.y() = blendOpHardmix(src.y(), dst.y());
		f.z() = blendOpHardmix(src.z(), dst.z());
		break;

	case VK_BLEND_OP_HSL_HUE_EXT:
		f = setLumSat(src, dst, dst);
		break;

	case VK_BLEND_OP_HSL_SATURATION_EXT:
		f = setLumSat(dst, src, dst);
		break;

	case VK_BLEND_OP_HSL_COLOR_EXT:
		f = setLum(src, dst);
		break;

	case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
		f = setLum(dst, src);
		break;

	default:
		DE_FATAL("Unsupported f/X/Y/Z Advanced Blend Operations Mode");
	};

	return f;
}

Vec4 additionalRGBBlendOperations(VkBlendOp op,
								  Vec4 src, Vec4 dst)
{
	Vec4 res = Vec4(0.0f, 0.0f, 0.0f, 1.0f);

	switch (op)
	{
	case VK_BLEND_OP_PLUS_EXT:
		res = src + dst;
		break;

	case VK_BLEND_OP_PLUS_CLAMPED_EXT:
		res.x() = deFloatMin(1.0f, src.x() + dst.x());
		res.y() = deFloatMin(1.0f, src.y() + dst.y());
		res.z() = deFloatMin(1.0f, src.z() + dst.z());
		res.w() = deFloatMin(1.0f, src.w() + dst.w());
		break;

	case VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT:
		res.x() = deFloatMin(deFloatMin(1.0f, src.w() + dst.w()), src.x() + dst.x());
		res.y() = deFloatMin(deFloatMin(1.0f, src.w() + dst.w()), src.y() + dst.y());
		res.z() = deFloatMin(deFloatMin(1.0f, src.w() + dst.w()), src.z() + dst.z());
		res.w() = deFloatMin(1.0f, src.w() + dst.w());
		break;

	case VK_BLEND_OP_PLUS_DARKER_EXT:
		res.x() = deFloatMax(0.0f, deFloatMin(1.0f, src.w() + dst.w()) - ((src.w() - src.x()) + (dst.w() - dst.x())));
		res.y() = deFloatMax(0.0f, deFloatMin(1.0f, src.w() + dst.w()) - ((src.w() - src.y()) + (dst.w() - dst.y())));
		res.z() = deFloatMax(0.0f, deFloatMin(1.0f, src.w() + dst.w()) - ((src.w() - src.z()) + (dst.w() - dst.z())));
		res.w() = deFloatMin(1.0f, src.w() + dst.w());
		break;

	case VK_BLEND_OP_MINUS_EXT:
		res = dst - src;
		break;

	case VK_BLEND_OP_MINUS_CLAMPED_EXT:
		res.x() = deFloatMax(0.0f, dst.x() - src.x());
		res.y() = deFloatMax(0.0f, dst.y() - src.y());
		res.z() = deFloatMax(0.0f, dst.z() - src.z());
		res.w() = deFloatMax(0.0f, dst.w() - src.w());
		break;

	case VK_BLEND_OP_CONTRAST_EXT:
		res.x() = (dst.w() / 2.0f) + 2.0f * (dst.x() - (dst.w() / 2.0f)) * (src.x() - (src.w() / 2.0f));
		res.y() = (dst.w() / 2.0f) + 2.0f * (dst.y() - (dst.w() / 2.0f)) * (src.y() - (src.w() / 2.0f));
		res.z() = (dst.w() / 2.0f) + 2.0f * (dst.z() - (dst.w() / 2.0f)) * (src.z() - (src.w() / 2.0f));
		res.w() = dst.w();
		break;

	case VK_BLEND_OP_INVERT_OVG_EXT:
		res.x() = src.w() * (1.0f - dst.x()) + (1.0f - src.w()) * dst.x();
		res.y() = src.w() * (1.0f - dst.y()) + (1.0f - src.w()) * dst.y();
		res.z() = src.w() * (1.0f - dst.z()) + (1.0f - src.w()) * dst.z();
		res.w() = src.w() + dst.w() - src.w() * dst.w();
		break;

	case VK_BLEND_OP_RED_EXT:
		res = dst;
		res.x() = src.x();
		break;

	case VK_BLEND_OP_GREEN_EXT:
		res = dst;
		res.y() = src.y();
		break;

	case VK_BLEND_OP_BLUE_EXT:
		res = dst;
		res.z() = src.z();
		break;

	default:
		DE_FATAL("Unsupported blend operation");
	};
	return res;
}

Vec4 calculateFinalColor(BlendOperationAdvancedParam param, VkBlendOp op,
						 Vec4 source, Vec4 destination)
{
	Vec4 result = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
	Vec3 srcColor = source.xyz();
	Vec3 dstColor = destination.xyz();

	// Calculate weighting factors
	Vec3 p = calculateWeightingFactors(param, source.w(), destination.w());

	if (op > VK_BLEND_OP_MAX && op < VK_BLEND_OP_PLUS_EXT)
	{
		{
			// If srcPremultiplied is set to VK_TRUE, the fragment color components
			// are considered to have been premultiplied by the A component prior to
			// blending. The base source color (Rs',Gs',Bs') is obtained by dividing
			// through by the A component.
			if (param.premultipliedSrcColor)
			{
				if (source.w() != 0.0f)
					srcColor = srcColor / source.w();
				else
					srcColor = Vec3(0.0f, 0.0f, 0.0f);
			}
			// If dstPremultiplied is set to VK_TRUE, the destination components are
			// considered to have been premultiplied by the A component prior to
			// blending. The base destination color (Rd',Gd',Bd') is obtained by dividing
			// through by the A component.
			if (param.premultipliedDstColor)
			{
				if (destination.w() != 0.0f)
					dstColor = dstColor / destination.w();
				else
					dstColor = Vec3(0.0f, 0.0f, 0.0f);
			}
		}

		// Calculate X, Y, Z terms of the equation
		Vec3 xyz = calculateXYZFactors(op);
		Vec3 fSrcDst = calculateFFunction(op, srcColor, dstColor);

		result.x() = fSrcDst.x() * p.x() + xyz.y() * srcColor.x() * p.y() + xyz.z() * dstColor.x() * p.z();
		result.y() = fSrcDst.y() * p.x() + xyz.y() * srcColor.y() * p.y() + xyz.z() * dstColor.y() * p.z();
		result.z() = fSrcDst.z() * p.x() + xyz.y() * srcColor.z() * p.y() + xyz.z() * dstColor.z() * p.z();
		result.w() = xyz.x() * p.x() + xyz.y() * p.y() + xyz.z() * p.z();
	}
	else if (op >= VK_BLEND_OP_PLUS_EXT && op < VK_BLEND_OP_MAX_ENUM)
	{
		// Premultiply colors for additional RGB blend operations. The formula is different than the rest of operations.
		{
			if (!param.premultipliedSrcColor)
			{
				srcColor = srcColor * source.w();
			}

			if (!param.premultipliedDstColor)
			{
				dstColor = dstColor * destination.w();
			}

		}
		Vec4 src = Vec4(srcColor.x(), srcColor.y(), srcColor.z(), source.w());
		Vec4 dst = Vec4(dstColor.x(), dstColor.y(), dstColor.z(), destination.w());
		result = additionalRGBBlendOperations(op, src, dst);
	}
	else
	{
		DE_FATAL("Unsupported Blend Operation");
	}
	return result;
}

static inline void getCoordinates (deUint32 index, deInt32 &x, deInt32 &y)
{
	x = index % widthArea;
	y = index / heightArea;
}

static inline std::vector<Vec4> createPoints (void)
{
	std::vector<Vec4> vertices;
	vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
	vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
	vertices.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
	vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
	vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
	vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
	return vertices;
}

template <class Test>
vkt::TestCase* newTestCase (tcu::TestContext&					testContext,
							const BlendOperationAdvancedParam	testParam)
{
	return new Test(testContext,
					generateTestName(testParam).c_str(),
					generateTestDescription().c_str(),
					testParam);
}

Move<VkRenderPass> makeTestRenderPass (BlendOperationAdvancedParam			param,
									   const DeviceInterface&				vk,
									   const VkDevice						device,
									   const VkFormat						colorFormat,
									   VkAttachmentLoadOp					colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR)
{
	const VkAttachmentDescription			colorAttachmentDescription			=
	{
		(VkAttachmentDescriptionFlags)0,				// VkAttachmentDescriptionFlags		flags
		colorFormat,									// VkFormat							format
		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits			samples
		colorLoadOp,									// VkAttachmentLoadOp				loadOp
		VK_ATTACHMENT_STORE_OP_STORE,					// VkAttachmentStoreOp				storeOp
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// VkAttachmentLoadOp				stencilLoadOp
		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// VkAttachmentStoreOp				stencilStoreOp
		(colorLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD) ?
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout					initialLayout
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL		// VkImageLayout					finalLayout
	};

	std::vector<VkAttachmentDescription>	attachmentDescriptions;
	std::vector<VkAttachmentReference>		colorAttachmentRefs;


	for (deUint32 i = 0; i < param.colorAttachmentsCount; i++)
	{
		attachmentDescriptions.push_back(colorAttachmentDescription);
		const VkAttachmentReference		colorAttachmentRef	=
		{
			i,											// deUint32		attachment
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
		};

		colorAttachmentRefs.push_back(colorAttachmentRef);
	}

	const VkSubpassDescription				subpassDescription					=
	{
		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags		flags
		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint				pipelineBindPoint
		0u,														// deUint32							inputAttachmentCount
		DE_NULL,												// const VkAttachmentReference*		pInputAttachments
		param.colorAttachmentsCount,							// deUint32							colorAttachmentCount
		colorAttachmentRefs.data(),								// const VkAttachmentReference*		pColorAttachments
		DE_NULL,												// const VkAttachmentReference*		pResolveAttachments
		DE_NULL,												// const VkAttachmentReference*		pDepthStencilAttachment
		0u,														// deUint32							preserveAttachmentCount
		DE_NULL													// const deUint32*					pPreserveAttachments
	};

	const VkRenderPassCreateInfo			renderPassInfo						=
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,									// VkStructureType					sType
		DE_NULL,																	// const void*						pNext
		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags			flags
		(deUint32)attachmentDescriptions.size(),									// deUint32							attachmentCount
		attachmentDescriptions.data(),												// const VkAttachmentDescription*	pAttachments
		1u,																			// deUint32							subpassCount
		&subpassDescription,														// const VkSubpassDescription*		pSubpasses
		0u,																			// deUint32							dependencyCount
		DE_NULL																		// const VkSubpassDependency*		pDependencies
	};

	return createRenderPass(vk, device, &renderPassInfo, DE_NULL);
}

Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
{
	const DeviceInterface&	vk				 = context.getDeviceInterface();
	const VkDevice			vkDevice		 = context.getDevice();
	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();

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

	Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);

	*pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));

	return vertexBuffer;
}

Move<VkImage> createImage2DAndBindMemory (Context&							context,
										  VkFormat							format,
										  deUint32							width,
										  deUint32							height,
										  VkImageUsageFlags					usage,
										  VkSampleCountFlagBits				sampleCount,
										  de::details::MovePtr<Allocation>* pAlloc)
{
	const DeviceInterface&	vk				 = context.getDeviceInterface();
	const VkDevice			vkDevice		 = context.getDevice();
	const deUint32			queueFamilyIndex = context.getUniversalQueueFamilyIndex();

	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;
		format,																		// VkFormat				format;
		{ width, height, 1u },														// VkExtent3D			extent;
		1u,																			// deUint32				mipLevels;
		1u,																			// deUint32				arraySize;
		sampleCount,																// deUint32				samples;
		VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling		tiling;
		usage,																		// VkImageUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode		sharingMode;
		1u,																			// deUint32				queueFamilyCount;
		&queueFamilyIndex,															// const deUint32*		pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout		initialLayout;
	};

	Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);

	*pAlloc = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
	VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));

	return image;
}

// Test Classes
class BlendOperationAdvancedTestInstance : public vkt::TestInstance
{
public:
								BlendOperationAdvancedTestInstance		(Context&				context,
																		 const BlendOperationAdvancedParam	param);
	virtual						~BlendOperationAdvancedTestInstance		(void);
	virtual tcu::TestStatus		iterate									(void);
protected:
			void				prepareRenderPass						(VkFramebuffer framebuffer, VkPipeline pipeline) const;
			void				prepareCommandBuffer					(void) const;
			void				buildPipeline							(VkBool32 premultiplySrc, VkBool32 premultiplyDst);
			void				bindShaderStage							(VkShaderStageFlagBits					stage,
																		 const char*							sourceName,
																		 const char*							entryName);
			deBool				verifyTestResult						(void);
protected:
	const BlendOperationAdvancedParam		m_param;
	const tcu::UVec2						m_renderSize;
	const VkFormat							m_colorFormat;
	Move<VkPipelineLayout>					m_pipelineLayout;

	Move<VkBuffer>							m_vertexBuffer;
	de::MovePtr<Allocation>					m_vertexBufferMemory;
	std::vector<Vec4>						m_vertices;

	Move<VkRenderPass>						m_renderPass;
	Move<VkCommandPool>						m_cmdPool;
	Move<VkCommandBuffer>					m_cmdBuffer;
	std::vector<Move<VkImage>>				m_colorImages;
	std::vector<Move<VkImageView>>			m_colorAttachmentViews;
	std::vector<de::MovePtr<Allocation>>	m_colorImageAllocs;
	std::vector<VkImageMemoryBarrier>		m_imageLayoutBarriers;
	Move<VkFramebuffer>						m_framebuffer;
	Move<VkPipeline>						m_pipeline;

	Move<VkShaderModule>					m_shaderModules[2];
	deUint32								m_shaderStageCount;
	VkPipelineShaderStageCreateInfo			m_shaderStageInfo[2];
};

void BlendOperationAdvancedTestInstance::bindShaderStage (VkShaderStageFlagBits	stage,
														  const char*			sourceName,
														  const char*			entryName)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create shader module
	deUint32*				code		= (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();

	const VkShaderModuleCreateInfo moduleCreateInfo =
	{
		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,				// VkStructureType				sType;
		DE_NULL,													// const void*					pNext;
		0u,															// VkShaderModuleCreateFlags	flags;
		codeSize,													// deUintptr					codeSize;
		code,														// const deUint32*				pCode;
	};

	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);

	// Prepare shader stage info
	m_shaderStageInfo[m_shaderStageCount].sType					= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
	m_shaderStageInfo[m_shaderStageCount].pNext					= DE_NULL;
	m_shaderStageInfo[m_shaderStageCount].flags					= 0u;
	m_shaderStageInfo[m_shaderStageCount].stage					= stage;
	m_shaderStageInfo[m_shaderStageCount].module				= *m_shaderModules[m_shaderStageCount];
	m_shaderStageInfo[m_shaderStageCount].pName					= entryName;
	m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo	= DE_NULL;

	m_shaderStageCount++;
}

void BlendOperationAdvancedTestInstance::buildPipeline (VkBool32 srcPremultiplied,
													   VkBool32 dstPremultiplied)
{
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();

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

	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
	{
		0u,									// deUint32 location;
		0u,									// deUint32 binding;
		VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
		0u									// deUint32 offsetInBytes;
	};

	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;
		1u,																// deUint32									vertexAttributeDescriptionCount;
		&vertexInputAttributeDescription,								// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
	};

	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
		VK_FALSE,														// VkBool32									primitiveRestartEnable;
	};

	const VkRect2D		scissor		= makeRect2D(m_renderSize);
	VkViewport			viewport	= makeViewport(m_renderSize);

	const VkPipelineViewportStateCreateInfo viewportStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineViewportStateCreateFlags		flags;
		1u,																// deUint32									viewportCount;
		&viewport,														// const VkViewport*						pViewports;
		1u,																// deUint32									scissorCount;
		&scissor														// const VkRect2D*							pScissors;
	};

	const VkPipelineRasterizationStateCreateInfo rasterStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,														// VkBool32									depthClampEnable;
		VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
		VK_FALSE,														// VkBool32									depthBiasEnable;
		0.0f,															// float									depthBiasConstantFactor;
		0.0f,															// float									depthBiasClamp;
		0.0f,															// float									depthBiasSlopeFactor;
		1.0f,															// float									lineWidth;
	};

	const VkPipelineColorBlendAdvancedStateCreateInfoEXT blendAdvancedStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT,	// VkStructureType		sType;
		DE_NULL,																// const void*			pNext;
		srcPremultiplied,														// VkBool32				srcPremultiplied;
		dstPremultiplied,														// VkBool32				dstPremultiplied;
		m_param.overlap,														// VkBlendOverlapEXT	blendOverlap;
	};

	std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;

	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
	{
		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
		{
			VK_TRUE,														// VkBool32									blendEnable;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcColorBlendFactor;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstColorBlendFactor;
			m_param.blendOps[i],											// VkBlendOp								colorBlendOp;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcAlphaBlendFactor;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstAlphaBlendFactor;
			m_param.blendOps[i],											// VkBlendOp								alphaBlendOp;
			VK_COLOR_COMPONENT_R_BIT |
			VK_COLOR_COMPONENT_G_BIT |
			VK_COLOR_COMPONENT_B_BIT |
			VK_COLOR_COMPONENT_A_BIT										// VkColorComponentFlags					colorWriteMask;
		};
		colorBlendAttachmentStates.emplace_back(colorBlendAttachmentState);
	}

	const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		&blendAdvancedStateParams,									// const void*									pNext;
		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
		VK_FALSE,													// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		(deUint32)colorBlendAttachmentStates.size(),				// deUint32										attachmentCount;
		colorBlendAttachmentStates.data(),							// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
	};

	const VkPipelineMultisampleStateCreateInfo  multisampleStateParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags		flags;
		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits						rasterizationSamples;
		VK_FALSE,													// VkBool32										sampleShadingEnable;
		0.0f,														// float										minSampleShading;
		DE_NULL,													// const VkSampleMask*							pSampleMask;
		VK_FALSE,													// VkBool32										alphaToCoverageEnable;
		VK_FALSE,													// VkBool32										alphaToOneEnable;
	};

	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0u,															// VkPipelineDepthStencilStateCreateFlags		flags;
		VK_FALSE,													// VkBool32										depthTestEnable;
		VK_FALSE,													// VkBool32										depthWriteEnable;
		VK_COMPARE_OP_NEVER,										// VkCompareOp									depthCompareOp;
		VK_FALSE,													// VkBool32										depthBoundsTestEnable;
		VK_FALSE,													// VkBool32										stencilTestEnable;
		// VkStencilOpState front;
		{
			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
			0u,						// deUint32		compareMask;
			0u,						// deUint32		writeMask;
			0u,						// deUint32		reference;
		},
		// VkStencilOpState back;
		{
			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
			0u,						// deUint32		compareMask;
			0u,						// deUint32		writeMask;
			0u,						// deUint32		reference;
		},
		0.0f,														// float										minDepthBounds;
		1.0f,														// float										maxDepthBounds;
	};

	const VkDynamicState dynamicState = VK_DYNAMIC_STATE_SCISSOR;
	const VkPipelineDynamicStateCreateInfo dynamicStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		0u,														// VkPipelineDynamicStateCreateFlags	flags;
		1u,														// uint32_t								dynamicStateCount;
		&dynamicState											// const VkDynamicState*				pDynamicStates;
	};

	const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType										sType;
		DE_NULL,											// const void*											pNext;
		0u,													// VkPipelineCreateFlags								flags;
		m_shaderStageCount,									// deUint32												stageCount;
		m_shaderStageInfo,									// const VkPipelineShaderStageCreateInfo*				pStages;
		&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*			pVertexInputState;
		&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*		pInputAssemblyState;
		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*			pTessellationState;
		&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*				pViewportState;
		&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*		pRasterState;
		&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*			pMultisampleState;
		&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*			pDepthStencilState;
		&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*			pColorBlendState;
		&dynamicStateParams,								// const VkPipelineDynamicStateCreateInfo*				pDynamicState;
		*m_pipelineLayout,									// VkPipelineLayout										layout;
		*m_renderPass,										// VkRenderPass											renderPass;
		0u,													// deUint32												subpass;
		DE_NULL,											// VkPipeline											basePipelineHandle;
		0u,													// deInt32												basePipelineIndex;
	};

	m_pipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
}

void BlendOperationAdvancedTestInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline) const
{
	const DeviceInterface&	vk				 = m_context.getDeviceInterface();

	std::vector<VkClearValue>	attachmentClearValues;

	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
		attachmentClearValues.emplace_back(makeClearValueColor(clearColorVec4));

	beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
					m_param.colorAttachmentsCount, attachmentClearValues.data());
	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
	VkDeviceSize offsets = 0u;
	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);

	// Draw all colors
	deUint32 skippedColors = 0u;
	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors); color++)
	{
		// Skip ill-formed colors when we have non-premultiplied destination colors.
		if (m_param.premultipliedDstColor == VK_FALSE)
		{
			deBool skipColor = false;
			for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
			{
				Vec4 calculatedColor = calculateFinalColor(m_param, m_param.blendOps[i], srcColors[color], dstColors[color]);
				if (calculatedColor.w() <= 0.0f && calculatedColor != Vec4(0.0f))
				{
					// Skip ill-formed colors, because the spec says the result is undefined.
					skippedColors++;
					skipColor = true;
					break;
				}
			}
			if (skipColor)
				continue;
		}

		deInt32 x = 0;
		deInt32 y = 0;
		getCoordinates(color, x, y);

		// Set source color as push constant
		vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(Vec4), &srcColors[color]);

		VkRect2D scissor = makeRect2D(x, y, 1u, 1u);
		vk.cmdSetScissor(*m_cmdBuffer, 0u, 1u, &scissor);

		// To set destination color, we do clear attachment restricting the area to the respective pixel of each color attachment.
		{
			// Set destination color as push constant.
			std::vector<VkClearAttachment> attachments;
			VkClearValue clearValue = vk::makeClearValueColorVec4(dstColors[color]);

			for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
			{
				VkClearAttachment	attachment	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,
					i,
					clearValue
				};
				attachments.emplace_back(attachment);
			}

			const VkClearRect rect =
			{
				scissor,
				0u,
				1u
			};
			vk.cmdClearAttachments(*m_cmdBuffer, (deUint32)attachments.size(), attachments.data(), 1u, &rect);
		}

		// Draw
		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
	}

	// If we break this assert, then we are not testing anything in this test.
	DE_ASSERT(skippedColors < DE_LENGTH_OF_ARRAY(srcColors));

	// Log number of skipped colors
	if (skippedColors != 0u)
	{
		tcu::TestLog& log = m_context.getTestContext().getLog();
		log << tcu::TestLog::Message << "Skipped " << skippedColors << " out of " << DE_LENGTH_OF_ARRAY(srcColors) << " color cases due to ill-formed colors" << tcu::TestLog::EndMessage;
	}
	endRenderPass(vk, *m_cmdBuffer);
}

void BlendOperationAdvancedTestInstance::prepareCommandBuffer () const
{
	const DeviceInterface&	vk				 = m_context.getDeviceInterface();


	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
						  0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageLayoutBarriers.size(), m_imageLayoutBarriers.data());

	prepareRenderPass(*m_framebuffer, *m_pipeline);

	endCommandBuffer(vk, *m_cmdBuffer);
}

BlendOperationAdvancedTestInstance::BlendOperationAdvancedTestInstance	(Context&							context,
																		 const BlendOperationAdvancedParam	param)
	: TestInstance			(context)
	, m_param				(param)
	, m_renderSize			(tcu::UVec2(widthArea, heightArea))
	, m_colorFormat			(VK_FORMAT_R16G16B16A16_SFLOAT)
	, m_shaderStageCount	(0)
{
	const DeviceInterface&		vk				 = m_context.getDeviceInterface();
	const VkDevice				vkDevice		 = m_context.getDevice();
	const deUint32				queueFamilyIndex = context.getUniversalQueueFamilyIndex();

	// Create vertex buffer and upload data
	{
		// Load vertices into vertex buffer
		m_vertices		= createPoints();
		DE_ASSERT((deUint32)m_vertices.size() == 6);

		m_vertexBuffer	= createBufferAndBindMemory(m_context, m_vertices.size() * sizeof(Vec4), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
		deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vec4));
		flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
	}

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

	const VkComponentMapping	componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};

	// Create color images
	for (deUint32 i = 0; i < param.colorAttachmentsCount; i++)
	{
		de::MovePtr<Allocation>	colorImageAlloc;
		m_colorImageAllocs.emplace_back(colorImageAlloc);

		Move<VkImage>			colorImage	= createImage2DAndBindMemory(m_context,
																		 m_colorFormat,
																		 m_renderSize.x(),
																		 m_renderSize.y(),
																		 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																		 VK_SAMPLE_COUNT_1_BIT,
																		 &m_colorImageAllocs.back());
		m_colorImages.emplace_back(colorImage);

		// Set up image layout transition barriers
		{
			VkImageMemoryBarrier colorImageBarrier =
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
				DE_NULL,												// const void*				pNext;
				0u,														// VkAccessFlags			srcAccessMask;
				(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
				 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			dstAccessMask;
				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			oldLayout;
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
				VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,								// deUint32					dstQueueFamilyIndex;
				*m_colorImages.back(),									// VkImage					image;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
			};

			m_imageLayoutBarriers.emplace_back(colorImageBarrier);
		}

		// Create color attachment view
		{
			VkImageViewCreateInfo colorAttachmentViewParams =
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
				DE_NULL,										// const void*				pNext;
				0u,												// VkImageViewCreateFlags	flags;
				*m_colorImages.back(),							// VkImage					image;
				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
				m_colorFormat,									// VkFormat					format;
				componentMappingRGBA,							// VkComponentMapping		components;
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
			};

			m_colorAttachmentViews.emplace_back(createImageView(vk, vkDevice, &colorAttachmentViewParams));
		}
	}

	// Create framebuffer
	{
		std::vector<VkImageView>	imageViews;

		for (auto& movePtr : m_colorAttachmentViews)
			imageViews.push_back(movePtr.get());

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

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

	// Bind shader stages
	{
		bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "vert", "main");
		bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "frag", "main");
	}


	// Create pipeline layout
	{
		const VkPushConstantRange pushConstantRange =
		{
			VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags
			0,									// deUint32				offset
			sizeof(Vec4)						// deUint32				size
		};

		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;
			1u,													// deUint32							pushConstantRangeCount;
			&pushConstantRange									// const VkPushConstantRange*		pPushConstantRanges;
		};

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

	// Create pipeline
	buildPipeline(m_param.premultipliedSrcColor, m_param.premultipliedDstColor);

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

	// Create command buffer
	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
}

BlendOperationAdvancedTestInstance::~BlendOperationAdvancedTestInstance (void)
{
}

tcu::TestStatus BlendOperationAdvancedTestInstance::iterate (void)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			vkDevice			= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	tcu::TestLog&			log					= m_context.getTestContext().getLog();

	// Log the blend operations to test
	{
		if (m_param.independentBlend)
		{
			for (deUint32 i = 0; (i < m_param.colorAttachmentsCount); i++)
				log << tcu::TestLog::Message << "Color attachment " << i << " uses depth op: "<< de::toLower(getBlendOpStr(m_param.blendOps[i]).toString().substr(3)) << tcu::TestLog::EndMessage;

		}
		else
		{
			log << tcu::TestLog::Message << "All color attachments use depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[0]).toString().substr(3)) << tcu::TestLog::EndMessage;

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

	if (verifyTestResult() == DE_FALSE)
		return tcu::TestStatus::fail("Image mismatch");

	return tcu::TestStatus::pass("Result images matches references");
}

deBool BlendOperationAdvancedTestInstance::verifyTestResult ()
{
	deBool							compareOk			= DE_TRUE;
	const DeviceInterface&			vk					= m_context.getDeviceInterface();
	const VkDevice					vkDevice			= m_context.getDevice();
	const VkQueue					queue				= m_context.getUniversalQueue();
	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&						allocator			= m_context.getDefaultAllocator();
	std::vector<tcu::TextureLevel>	referenceImages;

	for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
	{
		tcu::TextureLevel		refImage			(vk::mapVkFormat(m_colorFormat), 32, 32);
		tcu::clear(refImage.getAccess(), clearColorVec4);
		referenceImages.emplace_back(refImage);
	}

	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors); color++)
	{
		deBool skipColor = DE_FALSE;

		// Check if any color attachment will generate an ill-formed color. If that's the case, skip that color in the verification.
		for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
		{
			Vec4 rectColor = calculateFinalColor(m_param, m_param.blendOps[colorAtt], srcColors[color], dstColors[color]);
			if (m_param.premultipliedDstColor == VK_FALSE)
			{
				if (rectColor.w() > 0.0f)
				{
					rectColor.x() = rectColor.x() / rectColor.w();
					rectColor.y() = rectColor.y() / rectColor.w();
					rectColor.z() = rectColor.z() / rectColor.w();
				}
				else
				{
					// Skip the color check if it is ill-formed.
					if (rectColor != Vec4(0.0f))
					{
						skipColor = DE_TRUE;
						break;
					}
				}
			}
		}

		// Skip ill-formed colors that appears in any color attachment.
		if (skipColor)
			continue;

		// If we reach this point, the final color for all color attachment is not ill-formed.
		for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
		{
			Vec4 rectColor = calculateFinalColor(m_param, m_param.blendOps[colorAtt], srcColors[color], dstColors[color]);
			if (m_param.premultipliedDstColor == VK_FALSE)
			{
				if (rectColor.w() > 0.0f)
				{
					rectColor.x() = rectColor.x() / rectColor.w();
					rectColor.y() = rectColor.y() / rectColor.w();
					rectColor.z() = rectColor.z() / rectColor.w();
				}
				else
				{
					// Ill-formed colors were already skipped
					DE_ASSERT(rectColor == Vec4(0.0f));
				}
			}
			deInt32 x = 0;
			deInt32 y = 0;
			getCoordinates(color, x, y);
			tcu::clear(tcu::getSubregion(referenceImages[colorAtt].getAccess(), x, y, 1u, 1u), rectColor);
		}
	}

	for (deUint32 colorAtt = 0; colorAtt < m_param.colorAttachmentsCount; colorAtt++)
	{
		// Compare image
		de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImages[colorAtt], m_colorFormat, m_renderSize);
		std::ostringstream name;
		name << "Image comparison. Color attachment: "  << colorAtt << ". Depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[colorAtt]).toString().substr(3));

		compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
											   "FloatImageCompare",
											   name.str().c_str(),
											   referenceImages[colorAtt].getAccess(),
											   result->getAccess(),
											   Vec4(0.01f, 0.01f, 0.01f, 0.01f),
											   tcu::COMPARE_LOG_RESULT);
		if (!compareOk)
			return DE_FALSE;
	}
	return DE_TRUE;
}

class BlendOperationAdvancedTest : public vkt::TestCase
{
public:
							BlendOperationAdvancedTest	(tcu::TestContext&					testContext,
														 const std::string&					name,
														 const std::string&					description,
														 const BlendOperationAdvancedParam	param)
								: vkt::TestCase (testContext, name, description)
								, m_param		(param)
								{ }
	virtual					~BlendOperationAdvancedTest	(void) { }
	virtual void			initPrograms		(SourceCollections&	programCollection) const;
	virtual TestInstance*	createInstance		(Context&				context) const;
	virtual void			checkSupport		(Context& context) const;

protected:
		const BlendOperationAdvancedParam       m_param;
};

void BlendOperationAdvancedTest::checkSupport(Context& context) const
{
	const InstanceInterface&	vki				 = context.getInstanceInterface();

	context.requireDeviceFunctionality("VK_EXT_blend_operation_advanced");

	VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT blendProperties;
	blendProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT;
	blendProperties.pNext = DE_NULL;

	VkPhysicalDeviceProperties2 properties2;
	properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	properties2.pNext = &blendProperties;
	vki.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties2);

	if (!blendProperties.advancedBlendAllOperations)
	{
		for (deUint32 index = 0u; index < m_param.blendOps.size(); index++)
		{
			switch (m_param.blendOps[index])
			{
			case VK_BLEND_OP_MULTIPLY_EXT:
			case VK_BLEND_OP_SCREEN_EXT:
			case VK_BLEND_OP_OVERLAY_EXT:
			case VK_BLEND_OP_DARKEN_EXT:
			case VK_BLEND_OP_LIGHTEN_EXT:
			case VK_BLEND_OP_COLORDODGE_EXT:
			case VK_BLEND_OP_COLORBURN_EXT:
			case VK_BLEND_OP_HARDLIGHT_EXT:
			case VK_BLEND_OP_SOFTLIGHT_EXT:
			case VK_BLEND_OP_DIFFERENCE_EXT:
			case VK_BLEND_OP_EXCLUSION_EXT:
			case VK_BLEND_OP_HSL_HUE_EXT:
			case VK_BLEND_OP_HSL_SATURATION_EXT:
			case VK_BLEND_OP_HSL_COLOR_EXT:
			case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
				break;
			default:
				throw tcu::NotSupportedError("Unsupported all advanced blend operations and unsupported advanced blend operation");
			}
		}
	}

	if (m_param.colorAttachmentsCount > blendProperties.advancedBlendMaxColorAttachments)
	{
		std::ostringstream error;
		error << "Unsupported number of color attachments (" << blendProperties.advancedBlendMaxColorAttachments << " < " << m_param.colorAttachmentsCount;
		throw tcu::NotSupportedError(error.str().c_str());
	}

	if (m_param.overlap != VK_BLEND_OVERLAP_UNCORRELATED_EXT && !blendProperties.advancedBlendCorrelatedOverlap)
	{
		throw tcu::NotSupportedError("Unsupported blend correlated overlap");
	}

	if (m_param.colorAttachmentsCount > 1 && m_param.independentBlend && !blendProperties.advancedBlendIndependentBlend)
	{
		throw tcu::NotSupportedError("Unsupported independent blend");
	}

	if (!m_param.premultipliedSrcColor && !blendProperties.advancedBlendNonPremultipliedSrcColor)
	{
		throw tcu::NotSupportedError("Unsupported non-premultiplied source color");
	}

	if (!m_param.premultipliedDstColor && !blendProperties.advancedBlendNonPremultipliedDstColor)
	{
		throw tcu::NotSupportedError("Unsupported non-premultiplied destination color");
	}

	const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT blendFeatures = context.getBlendOperationAdvancedFeaturesEXT();
	if (m_param.coherentOperations && !blendFeatures.advancedBlendCoherentOperations)
	{
		throw tcu::NotSupportedError("Unsupported required coherent operations");
	}
}

void BlendOperationAdvancedTest::initPrograms (SourceCollections& programCollection) const
{
	programCollection.glslSources.add("vert") << glu::VertexSource(
				"#version 310 es\n"
				"layout(location = 0) in vec4 position;\n"
				"void main (void)\n"
				"{\n"
				"  gl_Position = position;\n"
				"}\n");

	std::ostringstream fragmentSource;
	fragmentSource << "#version 310 es\n";
	fragmentSource << "layout(push_constant) uniform Color { highp vec4 color; };\n";
	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
		fragmentSource << "layout(location = "<< i <<") out highp vec4 fragColor" << i <<";\n";
	fragmentSource << "void main (void)\n";
	fragmentSource << "{\n";
	for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
		fragmentSource << "  fragColor" << i <<" = color;\n";
	fragmentSource << "}\n";
	programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str().c_str());
}

class BlendOperationAdvancedTestCoherentInstance : public vkt::TestInstance
{
public:
								BlendOperationAdvancedTestCoherentInstance		(Context&				context,
																				 const BlendOperationAdvancedParam	param);
	virtual						~BlendOperationAdvancedTestCoherentInstance		(void);
	virtual tcu::TestStatus		iterate									(void);
protected:
			void				prepareRenderPass						(VkFramebuffer framebuffer, VkPipeline pipeline,
																		 VkRenderPass renderpass, deBool secondDraw);
	virtual	void				prepareCommandBuffer					(void);
	virtual	void				buildPipeline							(void);
	virtual	void				bindShaderStage							(VkShaderStageFlagBits					stage,
																		 const char*							sourceName,
																		 const char*							entryName);
	virtual	tcu::TestStatus		verifyTestResult						(void);

protected:
	const BlendOperationAdvancedParam		m_param;
	const tcu::UVec2						m_renderSize;
	const VkFormat							m_colorFormat;
	Move<VkPipelineLayout>					m_pipelineLayout;

	Move<VkBuffer>							m_vertexBuffer;
	de::MovePtr<Allocation>					m_vertexBufferMemory;
	std::vector<Vec4>						m_vertices;

	std::vector<Move<VkRenderPass>>			m_renderPasses;
	Move<VkCommandPool>						m_cmdPool;
	Move<VkCommandBuffer>					m_cmdBuffer;
	Move<VkImage>							m_colorImage;
	Move<VkImageView>						m_colorAttachmentView;
	de::MovePtr<Allocation>					m_colorImageAlloc;
	std::vector<VkImageMemoryBarrier>		m_imageLayoutBarriers;
	std::vector<Move<VkFramebuffer>>		m_framebuffers;
	std::vector<Move<VkPipeline>>			m_pipelines;

	Move<VkShaderModule>					m_shaderModules[2];
	deUint32								m_shaderStageCount;
	VkPipelineShaderStageCreateInfo			m_shaderStageInfo[2];
};

BlendOperationAdvancedTestCoherentInstance::~BlendOperationAdvancedTestCoherentInstance (void)
{
}

void BlendOperationAdvancedTestCoherentInstance::bindShaderStage (VkShaderStageFlagBits	stage,
																 const char*			sourceName,
																 const char*			entryName)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create shader module
	deUint32*				code		= (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();

	const VkShaderModuleCreateInfo moduleCreateInfo =
	{
		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,				// VkStructureType				sType;
		DE_NULL,													// const void*					pNext;
		0u,															// VkShaderModuleCreateFlags	flags;
		codeSize,													// deUintptr					codeSize;
		code,														// const deUint32*				pCode;
	};

	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);

	// Prepare shader stage info
	m_shaderStageInfo[m_shaderStageCount].sType					= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
	m_shaderStageInfo[m_shaderStageCount].pNext					= DE_NULL;
	m_shaderStageInfo[m_shaderStageCount].flags					= 0u;
	m_shaderStageInfo[m_shaderStageCount].stage					= stage;
	m_shaderStageInfo[m_shaderStageCount].module				= *m_shaderModules[m_shaderStageCount];
	m_shaderStageInfo[m_shaderStageCount].pName					= entryName;
	m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo	= DE_NULL;

	m_shaderStageCount++;
}

void BlendOperationAdvancedTestCoherentInstance::buildPipeline ()
{
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();

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

	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
	{
		0u,									// deUint32 location;
		0u,									// deUint32 binding;
		VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
		0u									// deUint32 offsetInBytes;
	};

	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;
		1u,																// deUint32									vertexAttributeDescriptionCount;
		&vertexInputAttributeDescription,								// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
	};

	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
		VK_FALSE,														// VkBool32									primitiveRestartEnable;
	};

	const VkRect2D		scissor		= makeRect2D(m_renderSize);
	VkViewport			viewport	= makeViewport(m_renderSize);

	const VkPipelineViewportStateCreateInfo viewportStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineViewportStateCreateFlags		flags;
		1u,																// deUint32									viewportCount;
		&viewport,														// const VkViewport*						pViewports;
		1u,																// deUint32									scissorCount;
		&scissor														// const VkRect2D*							pScissors;
	};

	const VkPipelineRasterizationStateCreateInfo rasterStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0u,																// VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,														// VkBool32									depthClampEnable;
		VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
		VK_FALSE,														// VkBool32									depthBiasEnable;
		0.0f,															// float									depthBiasConstantFactor;
		0.0f,															// float									depthBiasClamp;
		0.0f,															// float									depthBiasSlopeFactor;
		1.0f,															// float									lineWidth;
	};

	const VkPipelineColorBlendAdvancedStateCreateInfoEXT blendAdvancedStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT,	// VkStructureType		sType;
		DE_NULL,																// const void*			pNext;
		VK_TRUE,																// VkBool32				srcPremultiplied;
		VK_TRUE,																// VkBool32				dstPremultiplied;
		m_param.overlap,														// VkBlendOverlapEXT	blendOverlap;
	};

	std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;

	// One VkPipelineColorBlendAttachmentState for each pipeline, we only have one color attachment.
	for (deUint32 i = 0; i < 2; i++)
	{
		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
		{
			VK_TRUE,														// VkBool32									blendEnable;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcColorBlendFactor;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstColorBlendFactor;
			m_param.blendOps[i],											// VkBlendOp								colorBlendOp;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							srcAlphaBlendFactor;
			VK_BLEND_FACTOR_ONE,											// VkBlendFactor							dstAlphaBlendFactor;
			m_param.blendOps[i],											// VkBlendOp								alphaBlendOp;
			VK_COLOR_COMPONENT_R_BIT |
			VK_COLOR_COMPONENT_G_BIT |
			VK_COLOR_COMPONENT_B_BIT |
			VK_COLOR_COMPONENT_A_BIT										// VkColorComponentFlags					colorWriteMask;
		};
		colorBlendAttachmentStates.emplace_back(colorBlendAttachmentState);
	}

	std::vector<VkPipelineColorBlendStateCreateInfo> colorBlendStateParams;
	VkPipelineColorBlendStateCreateInfo colorBlendStateParam =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		&blendAdvancedStateParams,									// const void*									pNext;
		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
		VK_FALSE,													// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		1u,															// deUint32										attachmentCount;
		&colorBlendAttachmentStates[0],								// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
	};
	colorBlendStateParams.emplace_back(colorBlendStateParam);

	// For the second pipeline, the blendOp changed.
	colorBlendStateParam.pAttachments = &colorBlendAttachmentStates[1];
	colorBlendStateParams.emplace_back(colorBlendStateParam);

	const VkPipelineMultisampleStateCreateInfo  multisampleStateParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0u,															// VkPipelineMultisampleStateCreateFlags		flags;
		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits						rasterizationSamples;
		VK_FALSE,													// VkBool32										sampleShadingEnable;
		0.0f,														// float										minSampleShading;
		DE_NULL,													// const VkSampleMask*							pSampleMask;
		VK_FALSE,													// VkBool32										alphaToCoverageEnable;
		VK_FALSE,													// VkBool32										alphaToOneEnable;
	};

	VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0u,															// VkPipelineDepthStencilStateCreateFlags		flags;
		VK_FALSE,													// VkBool32										depthTestEnable;
		VK_FALSE,													// VkBool32										depthWriteEnable;
		VK_COMPARE_OP_NEVER,										// VkCompareOp									depthCompareOp;
		VK_FALSE,													// VkBool32										depthBoundsTestEnable;
		VK_FALSE,													// VkBool32										stencilTestEnable;
		// VkStencilOpState front;
		{
			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
			0u,						// deUint32		compareMask;
			0u,						// deUint32		writeMask;
			0u,						// deUint32		reference;
		},
		// VkStencilOpState back;
		{
			VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
			VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
			VK_COMPARE_OP_NEVER,	// VkCompareOp	compareOp;
			0u,						// deUint32		compareMask;
			0u,						// deUint32		writeMask;
			0u,						// deUint32		reference;
		},
		0.0f,														// float										minDepthBounds;
		1.0f,														// float										maxDepthBounds;
	};

	const VkDynamicState dynamicState = VK_DYNAMIC_STATE_SCISSOR;
	const VkPipelineDynamicStateCreateInfo dynamicStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		0u,														// VkPipelineDynamicStateCreateFlags	flags;
		1u,														// uint32_t								dynamicStateCount;
		&dynamicState											// const VkDynamicState*				pDynamicStates;
	};

	VkGraphicsPipelineCreateInfo graphicsPipelineParams =
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType										sType;
		DE_NULL,											// const void*											pNext;
		0u,													// VkPipelineCreateFlags								flags;
		m_shaderStageCount,									// deUint32												stageCount;
		m_shaderStageInfo,									// const VkPipelineShaderStageCreateInfo*				pStages;
		&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*			pVertexInputState;
		&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*		pInputAssemblyState;
		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*			pTessellationState;
		&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*				pViewportState;
		&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*		pRasterState;
		&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*			pMultisampleState;
		&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*			pDepthStencilState;
		&colorBlendStateParams[0],							// const VkPipelineColorBlendStateCreateInfo*			pColorBlendState;
		&dynamicStateParams,								// const VkPipelineDynamicStateCreateInfo*				pDynamicState;
		*m_pipelineLayout,									// VkPipelineLayout										layout;
		m_renderPasses[0].get(),							// VkRenderPass											renderPass;
		0u,													// deUint32												subpass;
		DE_NULL,											// VkPipeline											basePipelineHandle;
		0u,													// deInt32												basePipelineIndex;
	};

	// Create first pipeline
	m_pipelines.emplace_back(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams));
	// Create second pipeline
	graphicsPipelineParams.pColorBlendState = &colorBlendStateParams[1];
	graphicsPipelineParams.renderPass = m_renderPasses[1].get();
	m_pipelines.emplace_back(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams));
}

void BlendOperationAdvancedTestCoherentInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline, VkRenderPass renderpass, deBool secondDraw)
{
	const DeviceInterface&	vk				 = m_context.getDeviceInterface();

	VkClearValue	attachmentClearValue = makeClearValueColor(clearColorVec4);

	beginRenderPass(vk, *m_cmdBuffer, renderpass, framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
					(secondDraw ? 0u : 1u),
					(secondDraw ? DE_NULL : &attachmentClearValue));

	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
	VkDeviceSize offsets = 0u;
	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);

	// There are two different renderpasses, each of them draw
	// one half of the colors.
	deBool skippedColors = 0u;
	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors)/2; color++)
	{
		// Skip ill-formed colors when we have non-premultiplied destination colors.
		if (m_param.premultipliedDstColor == VK_FALSE)
		{
			deBool skipColor = false;
			for (deUint32 i = 0; i < m_param.colorAttachmentsCount; i++)
			{
				Vec4 calculatedColor = calculateFinalColor(m_param, m_param.blendOps[i], srcColors[color], dstColors[color]);
				if (calculatedColor.w() <= 0.0f && calculatedColor != Vec4(0.0f))
				{
					// Skip ill-formed colors, because the spec says the result is undefined.
					skippedColors++;
					skipColor = true;
					break;
				}
			}
			if (skipColor)
				continue;
		}
		deInt32 x = 0;
		deInt32 y = 0;
		getCoordinates(color, x, y);

		deUint32 index = secondDraw ? (color + DE_LENGTH_OF_ARRAY(srcColors) / 2) : color;

		// Set source color as push constant
		vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(Vec4), &srcColors[index]);
		VkRect2D scissor = makeRect2D(x, y, 1u, 1u);
		vk.cmdSetScissor(*m_cmdBuffer, 0u, 1u, &scissor);

		// To set destination color, we do clear attachment restricting the area to the respective pixel of each color attachment.
		// Only clear in the first draw, for the second draw the destination color is the result of the first draw's blend.
		if (secondDraw == DE_FALSE)
		{
			std::vector<VkClearAttachment> attachments;
			VkClearValue clearValue = vk::makeClearValueColorVec4(dstColors[index]);

			const VkClearAttachment	attachment	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,
				0u,
				clearValue
			};

			const VkClearRect rect =
			{
				scissor,
				0u,
				1u
			};
			vk.cmdClearAttachments(*m_cmdBuffer, 1u, &attachment, 1u, &rect);
		}

		// Draw
		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
	}

	// If we break this assert, then we are not testing anything in this test.
	DE_ASSERT(skippedColors < (DE_LENGTH_OF_ARRAY(srcColors) / 2));

	// Log number of skipped colors
	if (skippedColors != 0u)
	{
		tcu::TestLog& log = m_context.getTestContext().getLog();
		log << tcu::TestLog::Message << "Skipped " << skippedColors << " out of " << (DE_LENGTH_OF_ARRAY(srcColors) / 2) << " color cases due to ill-formed colors" << tcu::TestLog::EndMessage;
	}
	endRenderPass(vk, *m_cmdBuffer);
}

void BlendOperationAdvancedTestCoherentInstance::prepareCommandBuffer ()
{
	const DeviceInterface&	vk				 = m_context.getDeviceInterface();

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
						  0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageLayoutBarriers.size(), m_imageLayoutBarriers.data());

	prepareRenderPass(m_framebuffers[0].get(), m_pipelines[0].get(), m_renderPasses[0].get(), false);

	if (m_param.coherentOperations == DE_FALSE)
	{
		const VkImageMemoryBarrier colorImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
			DE_NULL,												// const void*				pNext;
			(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
			 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			srcAccessMask;
			(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
			 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,								// deUint32					dstQueueFamilyIndex;
			*m_colorImage,											// VkImage					image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
		};
		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
							  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
							  0u, DE_NULL, 0u, DE_NULL, 1u, &colorImageBarrier);
	}

	prepareRenderPass(m_framebuffers[1].get(), m_pipelines[1].get(), m_renderPasses[1].get(), true);

	endCommandBuffer(vk, *m_cmdBuffer);
}

BlendOperationAdvancedTestCoherentInstance::BlendOperationAdvancedTestCoherentInstance	(Context&							context,
																						 const BlendOperationAdvancedParam	param)
	: TestInstance			(context)
	, m_param				(param)
	, m_renderSize			(tcu::UVec2(widthArea, heightArea))
	, m_colorFormat			(VK_FORMAT_R16G16B16A16_SFLOAT)
	, m_shaderStageCount	(0)
{
	const DeviceInterface&		vk				 = m_context.getDeviceInterface();
	const VkDevice				vkDevice		 = m_context.getDevice();
	const deUint32				queueFamilyIndex = context.getUniversalQueueFamilyIndex();

	// Create vertex buffer
	{
		m_vertices		= createPoints();
		DE_ASSERT((deUint32)m_vertices.size() == 6);

		m_vertexBuffer	= createBufferAndBindMemory(m_context, m_vertices.size() * sizeof(Vec4), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vec4));
		flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
	}

	// Create render passes
	m_renderPasses.emplace_back(makeTestRenderPass(param, vk, vkDevice, m_colorFormat, VK_ATTACHMENT_LOAD_OP_CLEAR));
	m_renderPasses.emplace_back(makeTestRenderPass(param, vk, vkDevice, m_colorFormat, VK_ATTACHMENT_LOAD_OP_LOAD));

	const VkComponentMapping	componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};

	// Create color image
	m_colorImage	= createImage2DAndBindMemory(m_context,
												 m_colorFormat,
												 m_renderSize.x(),
												 m_renderSize.y(),
												 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
												 VK_SAMPLE_COUNT_1_BIT,
												 &m_colorImageAlloc);
	// Set up image layout transition barriers
	{
		VkImageMemoryBarrier colorImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
			DE_NULL,												// const void*				pNext;
			0u,														// VkAccessFlags			srcAccessMask;
			(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
			 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT),	// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,								// deUint32					dstQueueFamilyIndex;
			*m_colorImage,											// VkImage					image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },			// VkImageSubresourceRange	subresourceRange;
		};

		m_imageLayoutBarriers.emplace_back(colorImageBarrier);
	}

	// Create color attachment view
	{
		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;
			componentMappingRGBA,							// VkComponentMapping		components;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
		};

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

	// Create framebuffers
	{
		VkFramebufferCreateInfo framebufferParams =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			0u,													// VkFramebufferCreateFlags		flags;
			m_renderPasses[0].get(),							// 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_framebuffers.emplace_back(createFramebuffer(vk, vkDevice, &framebufferParams));
		framebufferParams.renderPass = m_renderPasses[1].get();
		m_framebuffers.emplace_back(createFramebuffer(vk, vkDevice, &framebufferParams));
	}

	// Bind shader stages
	{
		bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "vert", "main");
		bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "frag", "main");
	}


	// Create pipeline layout
	{
		const VkPushConstantRange pushConstantRange =
		{
			VK_SHADER_STAGE_FRAGMENT_BIT,		// VkShaderStageFlags	stageFlags
			0,									// deUint32				offset
			sizeof(Vec4)						// deUint32				size
		};

		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;
			1u,													// deUint32							pushConstantRangeCount;
			&pushConstantRange									// const VkPushConstantRange*		pPushConstantRanges;
		};

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

	// Create pipeline
	buildPipeline();

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

	// Create command buffer
	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
}

tcu::TestStatus BlendOperationAdvancedTestCoherentInstance::iterate (void)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			vkDevice			= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	tcu::TestLog&			log					= m_context.getTestContext().getLog();

	// Log the blend operations to test
	{
		DE_ASSERT(m_param.blendOps.size() == 2u);
		log << tcu::TestLog::Message << "First depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[0]).toString().substr(3)) << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Second depth op: " << de::toLower(getBlendOpStr(m_param.blendOps[1]).toString().substr(3)) << tcu::TestLog::EndMessage;

	}

	prepareCommandBuffer();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
	return verifyTestResult();
}

tcu::TestStatus BlendOperationAdvancedTestCoherentInstance::verifyTestResult (void)
{
	deBool					compareOk			= DE_TRUE;
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			vkDevice			= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&				allocator			= m_context.getDefaultAllocator();
	tcu::TextureLevel		refImage			(vk::mapVkFormat(m_colorFormat), 32, 32);

	tcu::clear(refImage.getAccess(), clearColorVec4);

	// Generate reference image
	for (deUint32 color = 0; color < DE_LENGTH_OF_ARRAY(srcColors)/2; color++)
	{
		deUint32 secondDrawColorIndex = color + DE_LENGTH_OF_ARRAY(srcColors)/2;
		// Calculate first draw final color
		Vec4 rectColorTmp = calculateFinalColor(m_param, m_param.blendOps[0], srcColors[color], dstColors[color]);

		if (m_param.premultipliedDstColor == VK_FALSE)
		{
			if (rectColorTmp.w() > 0.0f)
			{
				rectColorTmp.x() = rectColorTmp.x() / rectColorTmp.w();
				rectColorTmp.y() = rectColorTmp.y() / rectColorTmp.w();
				rectColorTmp.z() = rectColorTmp.z() / rectColorTmp.w();
			}
			else
			{
				// Skip the color check if it is ill-formed.
				if (rectColorTmp != Vec4(0.0f))
					continue;
			}
		}
		// Calculate second draw final color
		Vec4 rectColor = calculateFinalColor(m_param, m_param.blendOps[1], srcColors[secondDrawColorIndex], rectColorTmp);
		if (m_param.premultipliedDstColor == VK_FALSE)
		{
			if (rectColor.w() > 0.0f)
			{
				rectColor.x() = rectColor.x() / rectColor.w();
				rectColor.y() = rectColor.y() / rectColor.w();
				rectColor.z() = rectColor.z() / rectColor.w();
			}
			else
			{
				// Skip the color check if it is ill-formed.
				if (rectColor != Vec4(0.0f))
					continue;
			}
		}

		deInt32 x = 0;
		deInt32 y = 0;
		getCoordinates(color, x, y);
		tcu::clear(tcu::getSubregion(refImage.getAccess(), x, y, 1u, 1u), rectColor);
	}

	de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
	std::ostringstream name;
	name << "Image comparison. Depth ops: " << de::toLower(getBlendOpStr(m_param.blendOps[0]).toString().substr(3)) << " and " << de::toLower(getBlendOpStr(m_param.blendOps[1]).toString().substr(3));
	compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
										   "FloatImageCompare",
										   name.str().c_str(),
										   refImage.getAccess(),
										   result->getAccess(),
										   Vec4(0.01f, 0.01f, 0.01f, 0.01f),
										   tcu::COMPARE_LOG_RESULT);
	if (!compareOk)
		return tcu::TestStatus::fail("Image mismatch");

	return tcu::TestStatus::pass("Result images matches references");
}

TestInstance* BlendOperationAdvancedTest::createInstance (Context& context) const
{
	if (m_param.testMode == TEST_MODE_GENERIC)
		return new BlendOperationAdvancedTestInstance(context, m_param);
	else
		return new BlendOperationAdvancedTestCoherentInstance(context, m_param);
}

} // anonymous

tcu::TestCaseGroup* createBlendOperationAdvancedTests (tcu::TestContext& testCtx)
{
	enum nonpremultiplyEnum
	{
		PREMULTIPLY_SRC = 1u,
		PREMULTIPLY_DST = 2u
	};
	deUint32	premultiplyModes[] = { 0u, PREMULTIPLY_SRC, PREMULTIPLY_DST, PREMULTIPLY_SRC | PREMULTIPLY_DST };
	deUint32	colorAttachmentCounts[] = { 1u, 2u, 4u, 8u, 16u };
	deBool		coherentOps[] = { DE_FALSE, DE_TRUE };
	VkBlendOp	blendOps[] =
	{
		VK_BLEND_OP_ZERO_EXT, VK_BLEND_OP_SRC_EXT, VK_BLEND_OP_DST_EXT,	VK_BLEND_OP_SRC_OVER_EXT, VK_BLEND_OP_DST_OVER_EXT,
		VK_BLEND_OP_SRC_IN_EXT, VK_BLEND_OP_DST_IN_EXT, VK_BLEND_OP_SRC_OUT_EXT, VK_BLEND_OP_DST_OUT_EXT, VK_BLEND_OP_SRC_ATOP_EXT,
		VK_BLEND_OP_DST_ATOP_EXT, VK_BLEND_OP_XOR_EXT, VK_BLEND_OP_MULTIPLY_EXT, VK_BLEND_OP_SCREEN_EXT, VK_BLEND_OP_OVERLAY_EXT,
		VK_BLEND_OP_DARKEN_EXT, VK_BLEND_OP_LIGHTEN_EXT, VK_BLEND_OP_COLORDODGE_EXT, VK_BLEND_OP_COLORBURN_EXT, VK_BLEND_OP_HARDLIGHT_EXT,
		VK_BLEND_OP_SOFTLIGHT_EXT, VK_BLEND_OP_DIFFERENCE_EXT, VK_BLEND_OP_EXCLUSION_EXT, VK_BLEND_OP_INVERT_EXT, VK_BLEND_OP_INVERT_RGB_EXT,
		VK_BLEND_OP_LINEARDODGE_EXT, VK_BLEND_OP_LINEARBURN_EXT, VK_BLEND_OP_VIVIDLIGHT_EXT, VK_BLEND_OP_LINEARLIGHT_EXT, VK_BLEND_OP_PINLIGHT_EXT,
		VK_BLEND_OP_HARDMIX_EXT, VK_BLEND_OP_HSL_HUE_EXT, VK_BLEND_OP_HSL_SATURATION_EXT, VK_BLEND_OP_HSL_COLOR_EXT, VK_BLEND_OP_HSL_LUMINOSITY_EXT,
		VK_BLEND_OP_PLUS_EXT, VK_BLEND_OP_PLUS_CLAMPED_EXT, VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT, VK_BLEND_OP_PLUS_DARKER_EXT, VK_BLEND_OP_MINUS_EXT,
		VK_BLEND_OP_MINUS_CLAMPED_EXT, VK_BLEND_OP_CONTRAST_EXT, VK_BLEND_OP_INVERT_OVG_EXT, VK_BLEND_OP_RED_EXT, VK_BLEND_OP_GREEN_EXT, VK_BLEND_OP_BLUE_EXT,
	};

	de::MovePtr<tcu::TestCaseGroup> tests (new tcu::TestCaseGroup(testCtx, "blend_operation_advanced", "VK_EXT_blend_operation_advanced tests"));
	de::Random						rnd				(deStringHash(tests->getName()));

	de::MovePtr<tcu::TestCaseGroup> opsTests (new tcu::TestCaseGroup(testCtx, "ops", "Test each blend operation advance op"));


	for (deUint32 colorAttachmentCount = 0u; colorAttachmentCount < DE_LENGTH_OF_ARRAY(colorAttachmentCounts); colorAttachmentCount++)
	{
		for (deUint32 overlap = 0; overlap <= VK_BLEND_OVERLAP_CONJOINT_EXT; overlap++)
		{
			for (deUint32 premultiply = 0u; premultiply < DE_LENGTH_OF_ARRAY(premultiplyModes); premultiply++)
			{
				deUint32 testNumber = 0u;
				for (deUint64 blendOp = 0u; blendOp < DE_LENGTH_OF_ARRAY(blendOps); blendOp++)
				{
					deBool isAdditionalRGBBlendOp = blendOps[blendOp] >= VK_BLEND_OP_PLUS_EXT && blendOps[blendOp] < VK_BLEND_OP_MAX_ENUM;

					// Additional RGB Blend operations are not affected by the blend overlap modes
					if (isAdditionalRGBBlendOp && overlap != VK_BLEND_OVERLAP_UNCORRELATED_EXT)
						continue;

					BlendOperationAdvancedParam testParams;
					testParams.testMode					= TEST_MODE_GENERIC;
					testParams.overlap					= (VkBlendOverlapEXT) overlap;
					testParams.coherentOperations		= DE_FALSE;
					testParams.colorAttachmentsCount	= colorAttachmentCounts[colorAttachmentCount];
					testParams.independentBlend			= DE_FALSE;
					testParams.premultipliedSrcColor	= (premultiplyModes[premultiply] & PREMULTIPLY_SRC) ? VK_TRUE : VK_FALSE;
					testParams.premultipliedDstColor	= (premultiplyModes[premultiply] & PREMULTIPLY_DST) ? VK_TRUE : VK_FALSE;
					testParams.testNumber				= testNumber++;

					for (deUint32 numColorAtt = 0; numColorAtt < colorAttachmentCounts[colorAttachmentCount]; numColorAtt++)
						testParams.blendOps.push_back(blendOps[blendOp]);
					opsTests->addChild(newTestCase<BlendOperationAdvancedTest>(testCtx, testParams));
				}
			}
		}
	}
	tests->addChild(opsTests.release());

	// Independent Blend Tests: test more than one color attachment.
	de::MovePtr<tcu::TestCaseGroup> independentTests (new tcu::TestCaseGroup(testCtx, "independent", "Test independent blend feature"));
	deUint32 testNumber = 0u;

	for (deUint32 colorAttachmentCount = 1u; colorAttachmentCount < DE_LENGTH_OF_ARRAY(colorAttachmentCounts); colorAttachmentCount++)
	{
		BlendOperationAdvancedParam testParams;
		testParams.testMode					= TEST_MODE_GENERIC;
		testParams.overlap					= VK_BLEND_OVERLAP_UNCORRELATED_EXT;
		testParams.coherentOperations		= DE_FALSE;
		testParams.colorAttachmentsCount	= colorAttachmentCounts[colorAttachmentCount];
		testParams.independentBlend			= DE_TRUE;
		testParams.premultipliedSrcColor	= VK_TRUE;
		testParams.premultipliedDstColor	= VK_TRUE;
		testParams.testNumber				= testNumber++;

		for (deUint32 numColorAtt = 0; numColorAtt < colorAttachmentCounts[colorAttachmentCount]; numColorAtt++)
		{
			deUint32 i = de::randomScalar<deUint32>(rnd, 0, DE_LENGTH_OF_ARRAY(blendOps) - 1);
			testParams.blendOps.push_back(blendOps[i]);
		}
		independentTests->addChild(newTestCase<BlendOperationAdvancedTest>(testCtx, testParams));
	}

	tests->addChild(independentTests.release());

	// Coherent tests, do two consecutive advanced blending operations on the same color attachment.
	de::MovePtr<tcu::TestCaseGroup> coherentTests (new tcu::TestCaseGroup(testCtx, "coherent", "Test coherent memory"));
	testNumber = 0u;

	for (deUint32 coherent = 0u; coherent < DE_LENGTH_OF_ARRAY(coherentOps); coherent++)
	{
		BlendOperationAdvancedParam testParams;
		testParams.testMode					= TEST_MODE_COHERENT;
		testParams.overlap					= VK_BLEND_OVERLAP_UNCORRELATED_EXT;
		testParams.coherentOperations		= coherentOps[coherent];
		testParams.colorAttachmentsCount	= 1u;
		testParams.independentBlend			= DE_FALSE;
		testParams.premultipliedSrcColor	= VK_TRUE;
		testParams.premultipliedDstColor	= VK_TRUE;
		testParams.testNumber				= testNumber++;

		// We do two consecutive advanced blending operations
		deUint32 i = de::randomScalar<deUint32>(rnd, 0, DE_LENGTH_OF_ARRAY(blendOps) - 1);
		testParams.blendOps.push_back(blendOps[i]);
		i = de::randomScalar<deUint32>(rnd, 0, DE_LENGTH_OF_ARRAY(blendOps) - 1);
		testParams.blendOps.push_back(blendOps[i]);

		coherentTests->addChild(newTestCase<BlendOperationAdvancedTest>(testCtx, testParams));
	}
	tests->addChild(coherentTests.release());


	return tests.release();
}

} // pipeline

} // vkt
