/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2021 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 Tests for Color Write Enable
*//*--------------------------------------------------------------------*/

#include "vktPipelineColorWriteEnableTests.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktTestCase.hpp"

#include "vkDefs.hpp"
#include "vkTypeUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkImageUtil.hpp"

#include "tcuVector.hpp"
#include "tcuMaybe.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"

#include <vector>
#include <sstream>
#include <algorithm>
#include <utility>
#include <iterator>
#include <string>
#include <limits>
#include <memory>
#include <functional>

namespace vkt
{
namespace pipeline
{

namespace
{

// Framebuffer size.
constexpr deUint32 kFramebufferWidth  = 64u;
constexpr deUint32 kFramebufferHeight = 64u;

// Image formats.
constexpr	vk::VkFormat	kColorFormat	= vk::VK_FORMAT_R8G8B8A8_UNORM;
const		tcu::Vec4		kColorThreshold	(0.005f); // 1/255 < 0.005 < 2/255.

constexpr	deUint32		kNumColorAttachments = 3u;

const vk::VkFormat kDepthStencilFormats[] =
{
	vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
	vk::VK_FORMAT_D24_UNORM_S8_UINT
};

constexpr auto kCoordsSize = static_cast<deUint32>(2 * sizeof(float));

using Bool32Vec = std::vector<vk::VkBool32>;

// Generic, to be used with any state than can be set statically and, as an option, dynamically.
template<typename T>
struct StaticAndDynamicPair
{
	T				staticValue;
	tcu::Maybe<T>	dynamicValue;

	// Helper constructor to set a static value and no dynamic value.
	StaticAndDynamicPair (const T& value)
		: staticValue	(value)
		, dynamicValue	(tcu::Nothing)
	{
	}

	// Helper constructor to set both.
	StaticAndDynamicPair (const T& sVal, const T& dVal)
		: staticValue	(sVal)
		, dynamicValue	(tcu::just<T>(dVal))
	{
	}

	// If the dynamic value is present, swap static and dynamic values.
	void swapValues (void)
	{
		if (!dynamicValue)
			return;
		std::swap(staticValue, dynamicValue.get());
	}
};

const tcu::Vec4	kDefaultTriangleColor (0.0f, 0.0f, 1.0f, 1.0f);	// Opaque blue.
const tcu::Vec4	kDefaultClearColor    (0.0f, 0.0f, 0.0f, 1.0f);	// Opaque black.

struct MeshParams
{
	tcu::Vec4	color;
	float		depth;
	float		scaleX;
	float		scaleY;
	float		offsetX;
	float		offsetY;

	MeshParams (const tcu::Vec4&	color_		= kDefaultTriangleColor,
				float				depth_		= 0.0f,
				float				scaleX_		= 1.0f,
				float				scaleY_		= 1.0f,
				float				offsetX_	= 0.0f,
				float				offsetY_	= 0.0f)
		: color		(color_)
		, depth		(depth_)
		, scaleX	(scaleX_)
		, scaleY	(scaleY_)
		, offsetX	(offsetX_)
		, offsetY	(offsetY_)
	{}
};

enum class SequenceOrdering
{
	CMD_BUFFER_START	= 0,	// Set state at the start of the command buffer.
	BEFORE_DRAW			= 1,	// After binding dynamic pipeline and just before drawing.
	BETWEEN_PIPELINES	= 2,	// After a static state pipeline has been bound but before the dynamic state pipeline has been bound.
	AFTER_PIPELINES		= 3,	// After a static state pipeline and a second dynamic state pipeline have been bound.
	BEFORE_GOOD_STATIC	= 4,	// Before a static state pipeline with the correct values has been bound.
	TWO_DRAWS_DYNAMIC	= 5,	// Bind bad static pipeline and draw, followed by binding correct dynamic pipeline and drawing again.
	TWO_DRAWS_STATIC	= 6,	// Bind bad dynamic pipeline and draw, followed by binding correct static pipeline and drawing again.
};

struct TestConfig
{
	// Main sequence ordering.
	SequenceOrdering				sequenceOrdering;

	// Drawing parameters.
	MeshParams						meshParams;

	// Clearing parameters for the framebuffer.
	tcu::Vec4						clearColorValue;
	float							clearDepthValue;

	// Channels to enable
	tcu::BVec4						channelMask;

	// Expected output in the attachments.
	std::vector<tcu::Vec4>			expectedColor;
	float							expectedDepth;

	// Static and dynamic pipeline configuration.
	StaticAndDynamicPair<Bool32Vec>	colorWriteEnableConfig;

	// Sane defaults.
	TestConfig (SequenceOrdering ordering)
		: sequenceOrdering				(ordering)
		, clearColorValue				(kDefaultClearColor)
		, clearDepthValue				(1.0f)
		, expectedColor					(kNumColorAttachments, kDefaultTriangleColor)
		, expectedDepth					(1.0f)
		, colorWriteEnableConfig		(Bool32Vec(1u, VK_TRUE))
		, m_swappedValues				(false)
	{
	}

	// Returns true if we should use the static and dynamic values exchanged.
	// This makes the static part of the pipeline have the actual expected values.
	bool isReversed () const
	{
		return (sequenceOrdering == SequenceOrdering::BEFORE_GOOD_STATIC ||
				sequenceOrdering == SequenceOrdering::TWO_DRAWS_STATIC);
	}

	// Swaps static and dynamic configuration values.
	void swapValues ()
	{
		colorWriteEnableConfig.swapValues();
		m_swappedValues = !m_swappedValues;
	}

	// Returns the number of iterations when recording commands.
	deUint32 numIterations () const
	{
		deUint32 iterations = 0u;

		switch (sequenceOrdering)
		{
		case SequenceOrdering::TWO_DRAWS_DYNAMIC:
		case SequenceOrdering::TWO_DRAWS_STATIC:
			iterations = 2u;
			break;
		default:
			iterations = 1u;
			break;
		}

		return iterations;
	}

private:
	// Color Write Enable cases as created by createColorWriteEnableTests() are based on the assumption that, when a state
	// has a static and a dynamic value configured at the same time, the static value is wrong and the dynamic value will give
	// expected results. That's appropriate for most test variants, but in some others we want to reverse the situation: a dynamic
	// pipeline with wrong values and a static one with good values.
	//
	// Instead of modifying how tests are created, we use isReversed() and swapValues() above, allowing us to swap static and
	// dynamic values and to know if we should do it for a given test case. However, we need to know were the good value is at any
	// given point in time in order to correctly answer some questions while running the test. m_swappedValues tracks that state.
	bool m_swappedValues;
};

struct PushConstants
{
	tcu::Vec4	triangleColor;
	float		meshDepth;
	float		scaleX;
	float		scaleY;
	float		offsetX;
	float		offsetY;
};

class ColorWriteEnableTest : public vkt::TestCase
{
public:
							ColorWriteEnableTest		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestConfig& testConfig);
	virtual					~ColorWriteEnableTest		(void) {}

	virtual void			checkSupport					(Context& context) const;
	virtual void			initPrograms					(vk::SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance					(Context& context) const;

private:
	TestConfig				m_testConfig;
};

class ColorWriteEnableInstance : public vkt::TestInstance
{
public:
								ColorWriteEnableInstance	(Context& context, const TestConfig& testConfig);
	virtual						~ColorWriteEnableInstance	(void) {}

	virtual tcu::TestStatus		iterate							(void);

private:
	TestConfig					m_testConfig;
};

ColorWriteEnableTest::ColorWriteEnableTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestConfig& testConfig)
	: vkt::TestCase	(testCtx, name, description)
	, m_testConfig	(testConfig)
{
}

void ColorWriteEnableTest::checkSupport (Context& context) const
{
	const auto&	vki				= context.getInstanceInterface();
	const auto	physicalDevice	= context.getPhysicalDevice();

	// This is always required.
	context.requireDeviceFunctionality("VK_EXT_color_write_enable");

	// Check color image format support (depth/stencil will be chosen at runtime).
	const vk::VkFormatFeatureFlags	kColorFeatures	= (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
	const auto						colorProperties	= vk::getPhysicalDeviceFormatProperties(vki, physicalDevice, kColorFormat);

	if ((colorProperties.optimalTilingFeatures & kColorFeatures) != kColorFeatures)
		TCU_THROW(NotSupportedError, "Required color image features not supported");
}

void ColorWriteEnableTest::initPrograms (vk::SourceCollections& programCollection) const
{
	std::ostringstream pushSource;
	pushSource
		<< "layout(push_constant, std430) uniform PushConstantsBlock {\n"
		<< "    vec4  triangleColor;\n"
		<< "    float depthValue;\n"
		<< "    float scaleX;\n"
		<< "    float scaleY;\n"
		<< "    float offsetX;\n"
		<< "    float offsetY;\n"
		<< "} pushConstants;\n"
		;

	std::ostringstream vertSource;
	vertSource
		<< "#version 450\n"
		<< pushSource.str()
		<< "layout(location=0) in vec2 position;\n"
		<< "out gl_PerVertex\n"
		<< "{\n"
		<< "    vec4 gl_Position;\n"
		<< "};\n"
		<< "void main() {\n"
		<< "    vec2 vertexCoords = position;\n"
		<< "    gl_Position = vec4(vertexCoords.x * pushConstants.scaleX + pushConstants.offsetX, vertexCoords.y * pushConstants.scaleY + pushConstants.offsetY, pushConstants.depthValue, 1.0);\n"
		<< "}\n"
		;

	std::ostringstream fragOutputs;
	std::ostringstream colorWrite;
	for (deUint32 i = 0u; i < kNumColorAttachments; ++i)
	{
		fragOutputs << "layout(location=" << i << ") out vec4 color" << i << ";\n";
		colorWrite << "    color" << i << " = pushConstants.triangleColor * " << powf(0.5f, static_cast<float>(i)) << ";\n";
	}

	std::ostringstream fragSource;
	fragSource
		<< "#version 450\n"
		<< pushSource.str()
		<< fragOutputs.str()
		<< "void main() {\n"
		<< colorWrite.str()
		<< "}\n"
		;

	programCollection.glslSources.add("vert") << glu::VertexSource(vertSource.str());
	programCollection.glslSources.add("frag") << glu::FragmentSource(fragSource.str());
}

TestInstance* ColorWriteEnableTest::createInstance (Context& context) const
{
	return new ColorWriteEnableInstance(context, m_testConfig);
}

ColorWriteEnableInstance::ColorWriteEnableInstance(Context& context, const TestConfig& testConfig)
	: vkt::TestInstance	(context)
	, m_testConfig		(testConfig)
{
}

void logErrors(tcu::TestLog& log, const std::string& setName, const std::string& setDesc, const tcu::ConstPixelBufferAccess& result, const tcu::ConstPixelBufferAccess& errorMask)
{
	log << tcu::TestLog::ImageSet(setName, setDesc)
		<< tcu::TestLog::Image(setName + "Result", "Result image", result)
		<< tcu::TestLog::Image(setName + "ErrorMask", "Error mask with errors marked in red", errorMask)
		<< tcu::TestLog::EndImageSet;
}

// Sets values for dynamic states if needed according to the test configuration.
void setDynamicStates(const TestConfig& testConfig, const vk::DeviceInterface& vkd, vk::VkCommandBuffer cmdBuffer)
{
	if (testConfig.colorWriteEnableConfig.dynamicValue)
	{
		const auto& colorWriteEnables = testConfig.colorWriteEnableConfig.dynamicValue.get();
		vkd.cmdSetColorWriteEnableEXT(cmdBuffer, static_cast<deUint32>(colorWriteEnables.size()), colorWriteEnables.data());
	}
}

tcu::TestStatus ColorWriteEnableInstance::iterate (void)
{
	using ImageWithMemoryVec	= std::vector<std::unique_ptr<vk::ImageWithMemory>>;
	using ImageViewVec			= std::vector<vk::Move<vk::VkImageView>>;
	using FramebufferVec		= std::vector<vk::Move<vk::VkFramebuffer>>;

	const auto&	vki					= m_context.getInstanceInterface();
	const auto&	vkd					= m_context.getDeviceInterface();
	const auto	physicalDevice		= m_context.getPhysicalDevice();
	const auto	device				= m_context.getDevice();
	auto&		allocator			= m_context.getDefaultAllocator();
	const auto	queue				= m_context.getUniversalQueue();
	const auto	queueIndex			= m_context.getUniversalQueueFamilyIndex();
	auto&		log					= m_context.getTestContext().getLog();

	const auto	kReversed			= m_testConfig.isReversed();
	const auto	kNumIterations		= m_testConfig.numIterations();
	const auto	kSequenceOrdering	= m_testConfig.sequenceOrdering;

	const auto						kFramebufferExtent	= vk::makeExtent3D(kFramebufferWidth, kFramebufferHeight, 1u);
	const vk::VkImageUsageFlags		kColorUsage			= (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
	const vk::VkImageUsageFlags		kDSUsage			= (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
	const vk::VkFormatFeatureFlags	kDSFeatures			= (vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);

	// Choose depth/stencil format.
	vk::VkFormat dsFormat = vk::VK_FORMAT_UNDEFINED;

	for (int formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(kDepthStencilFormats); ++formatIdx)
	{
		const auto dsProperties = vk::getPhysicalDeviceFormatProperties(vki, physicalDevice, kDepthStencilFormats[formatIdx]);
		if ((dsProperties.optimalTilingFeatures & kDSFeatures) == kDSFeatures)
		{
			dsFormat = kDepthStencilFormats[formatIdx];
			break;
		}
	}

	// Note: Not Supported insted of Fail because the transfer feature is not mandatory.
	if (dsFormat == vk::VK_FORMAT_UNDEFINED)
		TCU_THROW(NotSupportedError, "Required depth/stencil image features not supported");
	log << tcu::TestLog::Message << "Chosen depth/stencil format: " << dsFormat << tcu::TestLog::EndMessage;

	// Swap static and dynamic values in the test configuration so the static pipeline ends up with the expected values for cases
	// where we will bind the static pipeline last before drawing.
	if (kReversed)
		m_testConfig.swapValues();

	// Create color and depth/stencil images.
	ImageWithMemoryVec colorImages;
	ImageWithMemoryVec dsImages;

	const vk::VkImageCreateInfo colorImageInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,									//	const void*				pNext;
		0u,											//	VkImageCreateFlags		flags;
		vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		kColorFormat,								//	VkFormat				format;
		kFramebufferExtent,							//	VkExtent3D				extent;
		1u,											//	deUint32				mipLevels;
		1u,											//	deUint32				arrayLayers;
		vk::VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		kColorUsage,								//	VkImageUsageFlags		usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		1u,											//	deUint32				queueFamilyIndexCount;
		&queueIndex,								//	const deUint32*			pQueueFamilyIndices;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};
	for (deUint32 i = 0u; i < kNumIterations * kNumColorAttachments; ++i)
		colorImages.emplace_back(new vk::ImageWithMemory(vkd, device, allocator, colorImageInfo, vk::MemoryRequirement::Any));

	const vk::VkImageCreateInfo dsImageInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,									//	const void*				pNext;
		0u,											//	VkImageCreateFlags		flags;
		vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		dsFormat,									//	VkFormat				format;
		kFramebufferExtent,							//	VkExtent3D				extent;
		1u,											//	deUint32				mipLevels;
		1u,											//	deUint32				arrayLayers;
		vk::VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		kDSUsage,									//	VkImageUsageFlags		usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		1u,											//	deUint32				queueFamilyIndexCount;
		&queueIndex,								//	const deUint32*			pQueueFamilyIndices;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};
	for (deUint32 i = 0u; i < kNumIterations; ++i)
		dsImages.emplace_back(new vk::ImageWithMemory(vkd, device, allocator, dsImageInfo, vk::MemoryRequirement::Any));

	const auto colorSubresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto dsSubresourceRange		= vk::makeImageSubresourceRange((vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT), 0u, 1u, 0u, 1u);

	ImageViewVec colorImageViews;
	ImageViewVec dsImageViews;

	for (const auto& img : colorImages)
		colorImageViews.emplace_back(vk::makeImageView(vkd, device, img->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, colorSubresourceRange));

	for (const auto& img : dsImages)
		dsImageViews.emplace_back(vk::makeImageView(vkd, device, img->get(), vk::VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresourceRange));

	// Vertex buffer.
	// Full-screen triangle fan with 6 vertices.
	//
	// 4        3        2
	//  +-------+-------+
	//  |X      X      X|
	//  | X     X     X |
	//  |  X    X    X  |
	//  |   X   X   X   |
	//  |    X  X  X    |
	//  |     X X X     |
	//  |      XXX      |
	//  +-------+-------+
	// 5        0        1
	std::vector<float> vertices = {
		 0.0f,  1.0f,
		 1.0f,  1.0f,
		 1.0f, -1.0f,
		 0.0f, -1.0f,
		-1.0f, -1.0f,
		-1.0f,  1.0f,
	};

	const auto vertDataSize				= vertices.size() * sizeof(float);
	const auto vertBufferInfo			= vk::makeBufferCreateInfo(static_cast<vk::VkDeviceSize>(vertDataSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
	vk::BufferWithMemory vertBuffer		(vkd, device, allocator, vertBufferInfo, vk::MemoryRequirement::HostVisible);
	auto& alloc							= vertBuffer.getAllocation();

	deMemcpy(reinterpret_cast<char*>(alloc.getHostPtr()), vertices.data(), vertDataSize);
	vk::flushAlloc(vkd, device, alloc);

	// Descriptor set layout.
	vk::DescriptorSetLayoutBuilder layoutBuilder;
	const auto descriptorSetLayout = layoutBuilder.build(vkd, device);

	// Pipeline layout.
	vk::VkShaderStageFlags pushConstantStageFlags = (vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT);

	const vk::VkPushConstantRange pushConstantRange =
	{
		pushConstantStageFlags,							//	VkShaderStageFlags	stageFlags;
		0u,												//	deUint32			offset;
		static_cast<deUint32>(sizeof(PushConstants)),	//	deUint32			size;
	};

	const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
		nullptr,											//	const void*						pNext;
		0u,													//	VkPipelineLayoutCreateFlags		flags;
		1u,													//	deUint32						setLayoutCount;
		&descriptorSetLayout.get(),							//	const VkDescriptorSetLayout*	pSetLayouts;
		1u,													//	deUint32						pushConstantRangeCount;
		&pushConstantRange,									//	const VkPushConstantRange*		pPushConstantRanges;
	};
	const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);

	// Render pass with single subpass.
	std::vector<vk::VkAttachmentReference> colorAttachmentReference;
	for (deUint32 i = 0u; i < kNumColorAttachments; ++i)
	{
		colorAttachmentReference.push_back(vk::VkAttachmentReference
			{
				i,												//	deUint32		attachment;
				vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	//	VkImageLayout	layout;
			}
		);
	}

	const vk::VkAttachmentReference dsAttachmentReference =
	{
		kNumColorAttachments,									//	deUint32		attachment;
		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	//	VkImageLayout	layout;
	};

	const vk::VkSubpassDescription subpassDescription =
	{
		0u,										//	VkSubpassDescriptionFlags		flags;
		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,	//	VkPipelineBindPoint				pipelineBindPoint;
		0u,										//	deUint32						inputAttachmentCount;
		nullptr,								//	const VkAttachmentReference*	pInputAttachments;
		kNumColorAttachments,					//	deUint32						colorAttachmentCount;
		colorAttachmentReference.data(),		//	const VkAttachmentReference*	pColorAttachments;
		nullptr,								//	const VkAttachmentReference*	pResolveAttachments;
		&dsAttachmentReference,					//	const VkAttachmentReference*	pDepthStencilAttachment;
		0u,										//	deUint32						preserveAttachmentCount;
		nullptr,								//	const deUint32*					pPreserveAttachments;
	};

	std::vector<vk::VkAttachmentDescription> attachmentDescriptions(
		kNumColorAttachments,
		vk::VkAttachmentDescription
		{
			0u,												//	VkAttachmentDescriptionFlags	flags;
			kColorFormat,									//	VkFormat						format;
			vk::VK_SAMPLE_COUNT_1_BIT,						//	VkSampleCountFlagBits			samples;
			vk::VK_ATTACHMENT_LOAD_OP_CLEAR,				//	VkAttachmentLoadOp				loadOp;
			vk::VK_ATTACHMENT_STORE_OP_STORE,				//	VkAttachmentStoreOp				storeOp;
			vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//	VkAttachmentLoadOp				stencilLoadOp;
			vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,			//	VkAttachmentStoreOp				stencilStoreOp;
			vk::VK_IMAGE_LAYOUT_UNDEFINED,					//	VkImageLayout					initialLayout;
			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout					finalLayout;
		}
	);

	attachmentDescriptions.push_back(vk::VkAttachmentDescription
	{
		0u,														//	VkAttachmentDescriptionFlags	flags;
		dsFormat,												//	VkFormat						format;
		vk::VK_SAMPLE_COUNT_1_BIT,								//	VkSampleCountFlagBits			samples;
		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,						//	VkAttachmentLoadOp				loadOp;
		vk::VK_ATTACHMENT_STORE_OP_STORE,						//	VkAttachmentStoreOp				storeOp;
		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,						//	VkAttachmentLoadOp				stencilLoadOp;
		vk::VK_ATTACHMENT_STORE_OP_STORE,						//	VkAttachmentStoreOp				stencilStoreOp;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,							//	VkImageLayout					initialLayout;
		vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	//	VkImageLayout					finalLayout;
	});

	const vk::VkRenderPassCreateInfo renderPassCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			//	VkStructureType					sType;
		nullptr,												//	const void*						pNext;
		0u,														//	VkRenderPassCreateFlags			flags;
		static_cast<deUint32>(attachmentDescriptions.size()),	//	deUint32						attachmentCount;
		attachmentDescriptions.data(),							//	const VkAttachmentDescription*	pAttachments;
		1u,														//	deUint32						subpassCount;
		&subpassDescription,									//	const VkSubpassDescription*		pSubpasses;
		0u,														//	deUint32						dependencyCount;
		nullptr,												//	const VkSubpassDependency*		pDependencies;
	};
	const auto renderPass = vk::createRenderPass(vkd, device, &renderPassCreateInfo);

	// Framebuffers.
	FramebufferVec framebuffers;

	DE_ASSERT(colorImageViews.size() == dsImageViews.size() * kNumColorAttachments);
	for (size_t imgIdx = 0; imgIdx < dsImageViews.size(); ++imgIdx)
	{
		std::vector<vk::VkImageView> attachments;
		for (deUint32 i = 0u; i < kNumColorAttachments; ++i)
			attachments.push_back(colorImageViews[imgIdx * kNumColorAttachments + i].get());

		attachments.push_back(dsImageViews[imgIdx].get());

		const vk::VkFramebufferCreateInfo framebufferCreateInfo =
		{
			vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	//	VkStructureType				sType;
			nullptr,										//	const void*					pNext;
			0u,												//	VkFramebufferCreateFlags	flags;
			renderPass.get(),								//	VkRenderPass				renderPass;
			static_cast<deUint32>(attachments.size()),		//	deUint32					attachmentCount;
			attachments.data(),								//	const VkImageView*			pAttachments;
			kFramebufferWidth,								//	deUint32					width;
			kFramebufferHeight,								//	deUint32					height;
			1u,												//	deUint32					layers;
		};

		framebuffers.emplace_back(vk::createFramebuffer(vkd, device, &framebufferCreateInfo));
	}

	// Shader modules.
	const auto	vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
	const auto	fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);

	// Shader stages.
	std::vector<vk::VkPipelineShaderStageCreateInfo> shaderStages;

	vk::VkPipelineShaderStageCreateInfo shaderStageCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType						sType;
		nullptr,													//	const void*							pNext;
		0u,															//	VkPipelineShaderStageCreateFlags	flags;
		vk::VK_SHADER_STAGE_VERTEX_BIT,								//	VkShaderStageFlagBits				stage;
		vertModule.get(),											//	VkShaderModule						module;
		"main",														//	const char*							pName;
		nullptr,													//	const VkSpecializationInfo*			pSpecializationInfo;
	};

	shaderStages.push_back(shaderStageCreateInfo);
	shaderStageCreateInfo.stage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
	shaderStageCreateInfo.module = fragModule.get();
	shaderStages.push_back(shaderStageCreateInfo);

	// Input state.
	const auto vertexBinding = vk::makeVertexInputBindingDescription(0u, kCoordsSize, vk::VK_VERTEX_INPUT_RATE_VERTEX);
	const std::vector<vk::VkVertexInputAttributeDescription> vertexAttributes = {
		vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u)
	};

	const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	VkStructureType								sType;
		nullptr,														//	const void*									pNext;
		0u,																//	VkPipelineVertexInputStateCreateFlags		flags;
		1u,																//	deUint32									vertexBindingDescriptionCount;
		&vertexBinding,													//	const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
		static_cast<deUint32>(vertexAttributes.size()),					//	deUint32									vertexAttributeDescriptionCount;
		vertexAttributes.data(),										//	const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	// Input assembly.
	const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	//	VkStructureType							sType;
		nullptr,															//	const void*								pNext;
		0u,																	//	VkPipelineInputAssemblyStateCreateFlags	flags;
		vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,								//	VkPrimitiveTopology						topology;
		VK_FALSE,															//	VkBool32								primitiveRestartEnable;
	};

	// Viewport state.
	const vk::VkViewport viewport	(vk::makeViewport(kFramebufferWidth, kFramebufferHeight));
	const vk::VkRect2D scissor		(vk::makeRect2D(kFramebufferWidth, kFramebufferHeight));

	// For the static pipeline.
	const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,					//	VkStructureType						sType;
		nullptr,																	//	const void*							pNext;
		0u,																			//	VkPipelineViewportStateCreateFlags	flags;
		1u,																			//	deUint32							viewportCount;
		&viewport,																	//	const VkViewport*					pViewports;
		1u,																			//	deUint32							scissorCount;
		&scissor,																	//	const VkRect2D*						pScissors;
	};

	// Rasterization state.
	const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
		nullptr,														//	const void*								pNext;
		0u,																//	VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,														//	VkBool32								depthClampEnable;
		VK_FALSE,														//	VkBool32								rasterizerDiscardEnable;
		vk::VK_POLYGON_MODE_FILL,										//	VkPolygonMode							polygonMode;
		vk::VK_CULL_MODE_NONE,											//	VkCullModeFlags							cullMode;
		vk::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;
	};

	// Multisample state.
	const vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	//	VkStructureType							sType;
		nullptr,														//	const void*								pNext;
		0u,																//	VkPipelineMultisampleStateCreateFlags	flags;
		vk::VK_SAMPLE_COUNT_1_BIT,										//	VkSampleCountFlagBits					rasterizationSamples;
		VK_FALSE,														//	VkBool32								sampleShadingEnable;
		0.0f,															//	float									minSampleShading;
		nullptr,														//	const VkSampleMask*						pSampleMask;
		VK_FALSE,														//	VkBool32								alphaToCoverageEnable;
		VK_FALSE,														//	VkBool32								alphaToOneEnable;
	};

	// Depth/stencil state.
	const vk::VkStencilOpState stencil =
	{
		vk::VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp;
		vk::VK_STENCIL_OP_KEEP,		// VkStencilOp	passOp;
		vk::VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp;
		vk::VK_COMPARE_OP_ALWAYS,	// VkCompareOp	compareOp;
		0xFFu,						// deUint32		compareMask;
		0xFFu,						// deUint32		writeMask;
		0u,							// deUint32		reference;
	};

	const vk::VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		//	VkStructureType							sType;
		nullptr,															//	const void*								pNext;
		0u,																	//	VkPipelineDepthStencilStateCreateFlags	flags;
		VK_TRUE,															//	VkBool32								depthTestEnable;
		VK_TRUE,															//	VkBool32								depthWriteEnable;
		vk::VK_COMPARE_OP_LESS,												//	VkCompareOp								depthCompareOp;
		VK_FALSE,															//	VkBool32								depthBoundsTestEnable;
		VK_FALSE,															//	VkBool32								stencilTestEnable;
		stencil,															//	VkStencilOpState						front;
		stencil,															//	VkStencilOpState						back;
		0.0f,																//	float									minDepthBounds;
		1.0f,																//	float									maxDepthBounds;
	};

	// Dynamic state. Here we will set all states which have a dynamic value.
	std::vector<vk::VkDynamicState> dynamicStates;

	if (m_testConfig.colorWriteEnableConfig.dynamicValue)
		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);

	const vk::VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	//	VkStructureType						sType;
		nullptr,													//	const void*							pNext;
		0u,															//	VkPipelineDynamicStateCreateFlags	flags;
		static_cast<deUint32>(dynamicStates.size()),				//	deUint32							dynamicStateCount;
		dynamicStates.data(),										//	const VkDynamicState*				pDynamicStates;
	};

	std::vector<vk::VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
		kNumColorAttachments,
		vk::VkPipelineColorBlendAttachmentState
		{
			VK_FALSE,								// VkBool32                 blendEnable
			vk::VK_BLEND_FACTOR_ZERO,				// VkBlendFactor            srcColorBlendFactor
			vk::VK_BLEND_FACTOR_ZERO,				// VkBlendFactor            dstColorBlendFactor
			vk::VK_BLEND_OP_ADD,					// VkBlendOp                colorBlendOp
			vk::VK_BLEND_FACTOR_ZERO,				// VkBlendFactor            srcAlphaBlendFactor
			vk::VK_BLEND_FACTOR_ZERO,				// VkBlendFactor            dstAlphaBlendFactor
			vk::VK_BLEND_OP_ADD,					// VkBlendOp                alphaBlendOp
			static_cast<vk::VkColorComponentFlags>(	// VkColorComponentFlags    colorWriteMask
				(m_testConfig.channelMask.x() ? vk::VK_COLOR_COMPONENT_R_BIT : 0)
				| (m_testConfig.channelMask.y() ? vk::VK_COLOR_COMPONENT_G_BIT : 0)
				| (m_testConfig.channelMask.z() ? vk::VK_COLOR_COMPONENT_B_BIT : 0)
				| (m_testConfig.channelMask.w() ? vk::VK_COLOR_COMPONENT_A_BIT : 0)
			)
		}
	);

	const vk::VkPipelineColorWriteCreateInfoEXT colorWriteCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT,		// VkStructureType	sType;
		nullptr,														// const void*		pNext;
		kNumColorAttachments,											// deUint32			attachmentCount;
		m_testConfig.colorWriteEnableConfig.staticValue.data()			// const VkBool32*	pColorWriteEnables;
	};

	const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType                               sType
		&colorWriteCreateInfo,											// const void*                                   pNext
		0u,																// VkPipelineColorBlendStateCreateFlags          flags
		VK_FALSE,														// VkBool32                                      logicOpEnable
		vk::VK_LOGIC_OP_CLEAR,											// VkLogicOp                                     logicOp
		kNumColorAttachments,											// deUint32                                      attachmentCount
		colorBlendAttachmentState.data(),								// const VkPipelineColorBlendAttachmentState*    pAttachments
		{ 0.0f, 0.0f, 0.0f, 0.0f }										// float                                         blendConstants[4]
	};

	const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfoTemplate =
	{
		vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	//	VkStructureType									sType;
		nullptr,												//	const void*										pNext;
		0u,														//	VkPipelineCreateFlags							flags;
		static_cast<deUint32>(shaderStages.size()),				//	deUint32										stageCount;
		shaderStages.data(),									//	const VkPipelineShaderStageCreateInfo*			pStages;
		&vertexInputStateCreateInfo,							//	const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
		&inputAssemblyStateCreateInfo,							//	const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
		nullptr,												//	const VkPipelineTessellationStateCreateInfo*	pTessellationState;
		nullptr,												//	const VkPipelineViewportStateCreateInfo*		pViewportState;
		&rasterizationStateCreateInfo,							//	const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
		&multisampleStateCreateInfo,							//	const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
		&depthStencilStateCreateInfo,							//	const VkPipelineDepthStencilStateCreateInfo*	pDepthStencilState;
		&colorBlendStateCreateInfo,								//	const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
		nullptr,												//	const VkPipelineDynamicStateCreateInfo*			pDynamicState;
		pipelineLayout.get(),									//	VkPipelineLayout								layout;
		renderPass.get(),										//	VkRenderPass									renderPass;
		0u,														//	deUint32										subpass;
		DE_NULL,												//	VkPipeline										basePipelineHandle;
		0,														//	deInt32											basePipelineIndex;
	};

	vk::Move<vk::VkPipeline>	staticPipeline;
	const bool					bindStaticFirst		= (kSequenceOrdering == SequenceOrdering::BETWEEN_PIPELINES	||
													   kSequenceOrdering == SequenceOrdering::AFTER_PIPELINES	||
													   kSequenceOrdering == SequenceOrdering::TWO_DRAWS_DYNAMIC);
	const bool					useStaticPipeline	= (bindStaticFirst || kReversed);

	// Create static pipeline when needed.
	if (useStaticPipeline)
	{
		auto staticPipelineCreateInfo			= graphicsPipelineCreateInfoTemplate;
		staticPipelineCreateInfo.pViewportState	= &viewportStateCreateInfo;
		staticPipeline							= vk::createGraphicsPipeline(vkd, device, DE_NULL, &staticPipelineCreateInfo);
	}

	// Create dynamic pipeline.
	vk::Move<vk::VkPipeline> graphicsPipeline;
	{
		auto dynamicPipelineCreateInfo				= graphicsPipelineCreateInfoTemplate;
		dynamicPipelineCreateInfo.pDynamicState		= &dynamicStateCreateInfo;
		dynamicPipelineCreateInfo.pViewportState	= &viewportStateCreateInfo;
		graphicsPipeline							= vk::createGraphicsPipeline(vkd, device, DE_NULL, &dynamicPipelineCreateInfo);
	}

	// Command buffer.
	const auto cmdPool		= vk::makeCommandPool(vkd, device, queueIndex);
	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	// Clear values.
	std::vector<vk::VkClearValue> clearValues;
	auto colorClearValue = vk::makeClearValueColor(m_testConfig.clearColorValue);
	for (deUint32 i = 0u; i < kNumColorAttachments; ++i)
		clearValues.push_back(colorClearValue);
	clearValues.push_back(vk::makeClearValueDepthStencil(m_testConfig.clearDepthValue, 0u));

	// Record command buffer.
	vk::beginCommandBuffer(vkd, cmdBuffer);

	for (deUint32 iteration = 0u; iteration < kNumIterations; ++iteration)
	{
		// Maybe set dynamic state here.
		if (kSequenceOrdering == SequenceOrdering::CMD_BUFFER_START)
		{
			setDynamicStates(m_testConfig, vkd, cmdBuffer);
		}

		// Begin render pass.
		vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffers[iteration].get(), vk::makeRect2D(kFramebufferWidth, kFramebufferHeight), static_cast<deUint32>(clearValues.size()), clearValues.data());

			// Bind a static pipeline first if needed.
			if (bindStaticFirst && iteration == 0u)
			{
				vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, staticPipeline.get());
			}

			// Maybe set dynamic state here.
			if (kSequenceOrdering == SequenceOrdering::BETWEEN_PIPELINES)
			{
				setDynamicStates(m_testConfig, vkd, cmdBuffer);
			}

			// Bind dynamic pipeline.
			if ((kSequenceOrdering != SequenceOrdering::TWO_DRAWS_DYNAMIC &&
				 kSequenceOrdering != SequenceOrdering::TWO_DRAWS_STATIC) ||
				(kSequenceOrdering == SequenceOrdering::TWO_DRAWS_DYNAMIC && iteration > 0u) ||
				(kSequenceOrdering == SequenceOrdering::TWO_DRAWS_STATIC && iteration == 0u))
			{
				vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
			}

			if (kSequenceOrdering == SequenceOrdering::BEFORE_GOOD_STATIC ||
				(kSequenceOrdering == SequenceOrdering::TWO_DRAWS_DYNAMIC && iteration > 0u) ||
				(kSequenceOrdering == SequenceOrdering::TWO_DRAWS_STATIC && iteration == 0u))
			{
				setDynamicStates(m_testConfig, vkd, cmdBuffer);
			}

			// Bind a static pipeline last if needed.
			if (kSequenceOrdering == SequenceOrdering::BEFORE_GOOD_STATIC ||
				(kSequenceOrdering == SequenceOrdering::TWO_DRAWS_STATIC && iteration > 0u))
			{
				vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, staticPipeline.get());
			}

			// Push constants.
			PushConstants pushConstants =
			{
				m_testConfig.meshParams.color,		//	tcu::Vec4	triangleColor;
				m_testConfig.meshParams.depth,		//	float		meshDepth;
				m_testConfig.meshParams.scaleX,		//	float		scaleX;
				m_testConfig.meshParams.scaleY,		//	float		scaleY;
				m_testConfig.meshParams.offsetX,	//	float		offsetX;
				m_testConfig.meshParams.offsetY,	//	float		offsetY;
			};
			vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantStageFlags, 0u, static_cast<deUint32>(sizeof(pushConstants)), &pushConstants);

			// Maybe set dynamic state here.
			if (kSequenceOrdering == SequenceOrdering::BEFORE_DRAW || kSequenceOrdering == SequenceOrdering::AFTER_PIPELINES)
			{
				setDynamicStates(m_testConfig, vkd, cmdBuffer);
			}

			// Bind vertex buffer and draw.
			vk::VkDeviceSize offset = 0ull;
			vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertBuffer.get(), &offset);
			vkd.cmdDraw(cmdBuffer, 6u, 1u, 0u, 0u);

		vk::endRenderPass(vkd, cmdBuffer);
	}

	vk::endCommandBuffer(vkd, cmdBuffer);

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

	// Read result image aspects from the last used framebuffer.
	const tcu::UVec2	renderSize(kFramebufferWidth, kFramebufferHeight);

	const int kWidth	= static_cast<int>(kFramebufferWidth);
	const int kHeight	= static_cast<int>(kFramebufferHeight);

	const tcu::Vec4		kGood(0.0f, 1.0f, 0.0f, 1.0f);
	const tcu::Vec4		kBad(1.0f, 0.0f, 0.0f, 1.0f);

	const tcu::TextureFormat errorFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);

	bool colorMatchAll = true;

	// Check expected values.
	auto nextAttachmentImage = colorImages.end() - kNumColorAttachments;
	for (deUint32 attachmentIndex = 0u; attachmentIndex < kNumColorAttachments; ++attachmentIndex, ++nextAttachmentImage)
	{
		const auto			colorBuffer = readColorAttachment(vkd, device, queue, queueIndex, allocator, (*nextAttachmentImage)->get(), kColorFormat, renderSize);
		const auto			colorAccess = colorBuffer->getAccess();

		tcu::TextureLevel	colorError			(errorFormat, kWidth, kHeight);
		const auto			colorErrorAccess	= colorError.getAccess();

		bool colorMatch = true;

		for (int y = 0; y < kHeight; ++y)
		for (int x = 0; x < kWidth; ++x)
		{
			const auto colorPixel = colorAccess.getPixel(x, y);

			bool match = tcu::boolAll(tcu::lessThan(tcu::absDiff(colorPixel, m_testConfig.expectedColor[attachmentIndex]), kColorThreshold));
			colorErrorAccess.setPixel((match ? kGood : kBad), x, y);
			if (!match)
				colorMatch = false;
		}

		if (!colorMatch)
		{
			std::ostringstream desc;
			desc << "Result color image and error mask for attachment #" << attachmentIndex;
			logErrors(log, "Color", desc.str(), colorAccess, colorErrorAccess);
			colorMatchAll = false;
		}
	}

	const auto			depthBuffer = readDepthAttachment(vkd, device, queue, queueIndex, allocator, dsImages.back()->get(), dsFormat, renderSize);
	const auto			depthAccess = depthBuffer->getAccess();
	tcu::TextureLevel	depthError(errorFormat, kWidth, kHeight);
	const auto			depthErrorAccess = depthError.getAccess();

	const auto	minDepth	= m_testConfig.expectedDepth - 1.0e-07f;
	const auto	maxDepth	= m_testConfig.expectedDepth + 1.0e-07f;
	bool		depthMatch	= true;

	for (int y = 0; y < kHeight; ++y)
	for (int x = 0; x < kWidth; ++x)
	{
		const auto depthPixel = depthAccess.getPixDepth(x, y);
		bool match = de::inRange(depthPixel, minDepth, maxDepth);
		depthErrorAccess.setPixel((match ? kGood : kBad), x, y);
		if (!match)
			depthMatch = false;
	}

	if (!depthMatch)
	{
		logErrors(log, "Depth", "Result depth image and error mask", depthAccess, depthErrorAccess);
	}

	if (!(colorMatchAll && depthMatch))
	{
		return tcu::TestStatus::fail("Incorrect value found in attachments; please check logged images");
	}

	return tcu::TestStatus::pass("Pass");
}

template <typename VectorType>
VectorType MaskVector(const VectorType& valueIfMaskIsFalse, const VectorType& valueIfMaskIsTrue, const std::vector<bool>& mask, bool inverse = false)
{
	DE_ASSERT(valueIfMaskIsFalse.size() == valueIfMaskIsTrue.size() && valueIfMaskIsFalse.size() == mask.size());

	VectorType ret(mask.size());

	for (size_t i = 0; i < mask.size(); ++i)
	{
		bool m = mask[i];
		if (inverse)
			m = !m;
		ret[i] = m ? valueIfMaskIsTrue[i] : valueIfMaskIsFalse[i];
	}

	return ret;
}

void ApplyChannelMask(std::vector<tcu::Vec4>& meshColors, const tcu::BVec4& channelMask, const tcu::Vec4& clearColor)
{
	for (auto&& attachmentColor : meshColors)
		attachmentColor = tcu::Vec4(
			channelMask.x() ? attachmentColor.x() : clearColor.x(),
			channelMask.y() ? attachmentColor.y() : clearColor.y(),
			channelMask.z() ? attachmentColor.z() : clearColor.z(),
			channelMask.w() ? attachmentColor.w() : clearColor.w()
		);
}

void AddSingleTestCaseStatic(
	const std::string& name,
	const std::string& description,
	const std::vector<bool> mask,
	const tcu::BVec4 channelMask,
	bool inverse,
	tcu::TestCaseGroup* orderingGroup,
	tcu::TestContext& testCtx)
{
	TestConfig config(SequenceOrdering::CMD_BUFFER_START);

	// Enable writes and expect the mesh color, or disable writes and expect the clear color.

	config.clearColorValue						= tcu::Vec4(0.25f, 0.5f, 0.75f, 0.5f);
	config.meshParams.color						= tcu::Vec4(1.0f, 0.75f, 0.5f, 0.25f);

	const auto allVkFalse						= Bool32Vec(kNumColorAttachments, VK_FALSE);
	const auto allVkTrue						= Bool32Vec(kNumColorAttachments, VK_TRUE);

	config.channelMask = channelMask;

	config.colorWriteEnableConfig.staticValue	= MaskVector(allVkFalse, allVkTrue, mask, inverse);

	// Note colorWriteEnableConfig.dynamicValue is unset, defaults to an empty Maybe<T>

	std::vector<tcu::Vec4> meshColorsPerAttachment(kNumColorAttachments);
	meshColorsPerAttachment[0] = config.meshParams.color;
	for (deUint32 i = 1u; i < kNumColorAttachments; ++i)
		meshColorsPerAttachment[i] = meshColorsPerAttachment[i - 1] * 0.5f;

	std::vector<tcu::Vec4> clearColorsPerAttachment(kNumColorAttachments, config.clearColorValue);

	ApplyChannelMask(meshColorsPerAttachment, channelMask, config.clearColorValue);

	config.expectedColor = MaskVector(clearColorsPerAttachment, meshColorsPerAttachment, mask, inverse);

	// Depth should always be written even when color is not
	config.clearDepthValue	= 0.5f;
	config.meshParams.depth	= 0.25f;
	config.expectedDepth	= 0.25f;

	orderingGroup->addChild(new ColorWriteEnableTest(testCtx, name, description, config));
}

void AddSingleTestCaseDynamic(
	const std::string& name,
	const std::string& description,
	const std::vector<bool> mask,
	const tcu::BVec4 channelMask,
	bool inverse,
	tcu::TestCaseGroup* orderingGroup,
	tcu::TestContext& testCtx,
	SequenceOrdering ordering)
{
	TestConfig config(ordering);

	// Enable writes and expect the mesh color, or disable writes and expect the clear color.

	config.clearColorValue						= tcu::Vec4(0.25f, 0.5f, 0.75f, 0.5f);
	config.meshParams.color						= tcu::Vec4(1.0f, 0.75f, 0.5f, 0.25f);

	const auto allVkFalse						= Bool32Vec(kNumColorAttachments, VK_FALSE);
	const auto allVkTrue						= Bool32Vec(kNumColorAttachments, VK_TRUE);

	config.channelMask = channelMask;

	config.colorWriteEnableConfig.staticValue	= inverse ? allVkTrue : allVkFalse;
	config.colorWriteEnableConfig.dynamicValue	= MaskVector(allVkFalse, allVkTrue, mask, inverse);

	std::vector<tcu::Vec4> meshColorsPerAttachment(kNumColorAttachments);
	meshColorsPerAttachment[0] = config.meshParams.color;
	for (deUint32 i = 1u; i < kNumColorAttachments; ++i)
		meshColorsPerAttachment[i] = meshColorsPerAttachment[i - 1] * 0.5f;

	std::vector<tcu::Vec4> clearColorsPerAttachment(kNumColorAttachments, config.clearColorValue);

	ApplyChannelMask(meshColorsPerAttachment, channelMask, config.clearColorValue);

	config.expectedColor = MaskVector(clearColorsPerAttachment, meshColorsPerAttachment, mask, inverse);

	// Depth should always be written even when color is not
	config.clearDepthValue	= 0.5f;
	config.meshParams.depth	= 0.25f;
	config.expectedDepth	= 0.25f;

	orderingGroup->addChild(new ColorWriteEnableTest(testCtx, name, description, config));
}

} // anonymous namespace

tcu::TestCaseGroup* createColorWriteEnableTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> colorWriteEnableGroup(new tcu::TestCaseGroup(testCtx, "color_write_enable", "Tests for VK_EXT_color_write_enable"));

	DE_ASSERT(kNumColorAttachments >= 2);

	std::vector<bool> mask_all				(kNumColorAttachments, true);
	std::vector<bool> mask_first			(kNumColorAttachments, false);	mask_first[0]												= true;
	std::vector<bool> mask_second			(kNumColorAttachments, false);	mask_second[1]												= true;
	std::vector<bool> mask_last				(kNumColorAttachments, false);	mask_last.back()											= true;
	std::vector<bool> mask_first_and_second	(kNumColorAttachments, false);	mask_first_and_second[0]	= mask_first_and_second[1]		= true;
	std::vector<bool> mask_second_and_last	(kNumColorAttachments, false);	mask_second_and_last[1]		= mask_second_and_last.back()	= true;

	// Test cases for channel enables
	static const struct
	{
		tcu::BVec4		enabledChannels;
		std::string		name;
		std::string		desc;
	} kChannelCases[] =
	{
		{ tcu::BVec4(true, true, true, true), "all_channels", "Enable all channels in colorWriteMask"},
		{ tcu::BVec4(true, false, false, false), "red_channel", "Red channel enabled in colorWriteMask"},
		{ tcu::BVec4(false, true, false, false), "green_channel", "Green channel enabled in colorWriteMask"},
		{ tcu::BVec4(false, false, true, false), "blue_channel", "Blue channel enabled in colorWriteMask"},
		{ tcu::BVec4(false, false, false, true), "alpha_channel", "Alpha channel enabled in colorWriteMask"},
		{ tcu::BVec4(false, false, false, false), "no_channels", "Disable all channels in colorWriteMask"},
	};

	// Test cases for the dynamic state
	static const struct
	{
		SequenceOrdering	ordering;
		std::string			name;
		std::string			desc;
	} kOrderingCases[] =
	{
		{ SequenceOrdering::CMD_BUFFER_START,	"cmd_buffer_start",		"Dynamic state set after command buffer start"																								},
		{ SequenceOrdering::BEFORE_DRAW,		"before_draw",			"Dynamic state set just before drawing"																										},
		{ SequenceOrdering::BETWEEN_PIPELINES,	"between_pipelines",	"Dynamic after a pipeline with static states has been bound and before a pipeline with dynamic states has been bound"						},
		{ SequenceOrdering::AFTER_PIPELINES,	"after_pipelines",		"Dynamic state set after both a static-state pipeline and a second dynamic-state pipeline have been bound"									},
		{ SequenceOrdering::BEFORE_GOOD_STATIC,	"before_good_static",	"Dynamic state set after a dynamic pipeline has been bound and before a second static-state pipeline with the right values has been bound"	},
		{ SequenceOrdering::TWO_DRAWS_DYNAMIC,	"two_draws_dynamic",	"Bind bad static pipeline and draw, followed by binding correct dynamic pipeline and drawing again"											},
		{ SequenceOrdering::TWO_DRAWS_STATIC,	"two_draws_static",		"Bind bad dynamic pipeline and draw, followed by binding correct static pipeline and drawing again"											},
	};

	for (int channelCaseIdx = 0; channelCaseIdx < DE_LENGTH_OF_ARRAY(kChannelCases); ++channelCaseIdx)
	{
		const auto& kChannelCase	 = kChannelCases[channelCaseIdx];
		de::MovePtr<tcu::TestCaseGroup> channelGroup(new tcu::TestCaseGroup(testCtx, kChannelCase.name.c_str(), kChannelCase.desc.c_str()));

		for (int orderingIdx = 0; orderingIdx < DE_LENGTH_OF_ARRAY(kOrderingCases); ++orderingIdx)
		{
			const auto& kOrderingCase	= kOrderingCases[orderingIdx];
			const auto& kOrdering		= kOrderingCase.ordering;

			de::MovePtr<tcu::TestCaseGroup> orderingGroup(new tcu::TestCaseGroup(testCtx, kOrderingCase.name.c_str(), kOrderingCase.desc.c_str()));

			AddSingleTestCaseDynamic("enable_all",					"Dynamically enable writes to all color attachments",							mask_all,				kChannelCase.enabledChannels, false, orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("enable_first",				"Dynamically enable writes to the first color attachment",						mask_first,				kChannelCase.enabledChannels, false, orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("enable_second",				"Dynamically enable writes to the second color attachment",						mask_second,			kChannelCase.enabledChannels, false, orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("enable_last",					"Dynamically enable writes to the last color attachment",						mask_last,				kChannelCase.enabledChannels, false, orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("enable_first_and_second",		"Dynamically enable writes to the first two color attachments",					mask_first_and_second,	kChannelCase.enabledChannels, false, orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("enable_second_and_last",		"Dynamically enable writes to the second and last color attachments",			mask_second_and_last,	kChannelCase.enabledChannels, false, orderingGroup.get(), testCtx, kOrdering);

			AddSingleTestCaseDynamic("disable_all",					"Dynamically disable writes to all color attachments",							mask_all,				kChannelCase.enabledChannels, true,  orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("disable_first",				"Dynamically disable writes to the first color attachment",						mask_first,				kChannelCase.enabledChannels, true,  orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("disable_second",				"Dynamically disable writes to the second color attachment",					mask_second,			kChannelCase.enabledChannels, true,  orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("disable_last",				"Dynamically disable writes to the last color attachment",						mask_last,				kChannelCase.enabledChannels, true,  orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("disable_first_and_second",	"Dynamically disable writes to the first two color attachments",				mask_first_and_second,	kChannelCase.enabledChannels, true,  orderingGroup.get(), testCtx, kOrdering);
			AddSingleTestCaseDynamic("disable_second_and_last",		"Dynamically disable writes to the second and last color attachments",			mask_second_and_last,	kChannelCase.enabledChannels, true,  orderingGroup.get(), testCtx, kOrdering);

			channelGroup->addChild(orderingGroup.release());
		}

		// Test cases for the static state
		// Note that the dynamic state test cases above also test pipelines with static state (when ordering is BEFORE_GOOD_STATIC and TWO_DRAWS_STATIC).
		// However they all bind a pipeline with the static state AFTER binding a pipeline with the dynamic state.
		// The only case missing, then, is static state alone without any dynamic pipelines in the same render pass or command buffer.
		de::MovePtr<tcu::TestCaseGroup> staticOrderingGroup(new tcu::TestCaseGroup(testCtx, "static", "Static state set"));

		AddSingleTestCaseStatic("enable_all",				"Statically enable writes to all color attachments",							mask_all,				kChannelCase.enabledChannels, false, staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("enable_first",				"Statically enable writes to the first color attachment",						mask_first,				kChannelCase.enabledChannels, false, staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("enable_second",			"Statically enable writes to the second color attachment",						mask_second,			kChannelCase.enabledChannels, false, staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("enable_last",				"Statically enable writes to the last color attachment",						mask_last,				kChannelCase.enabledChannels, false, staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("enable_first_and_second",	"Statically enable writes to the first two color attachments",					mask_first_and_second,	kChannelCase.enabledChannels, false, staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("enable_second_and_last",	"Statically enable writes to the second and last color attachments",			mask_second_and_last,	kChannelCase.enabledChannels, false, staticOrderingGroup.get(), testCtx);

		AddSingleTestCaseStatic("disable_all",				"Statically disable writes to all color attachments",							mask_all,				kChannelCase.enabledChannels, true,  staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("disable_first",			"Statically disable writes to the first color attachment",						mask_first,				kChannelCase.enabledChannels, true,  staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("disable_second",			"Statically disable writes to the second color attachment",						mask_second,			kChannelCase.enabledChannels, true,  staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("disable_last",				"Statically disable writes to the last color attachment",						mask_last,				kChannelCase.enabledChannels, true,  staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("disable_first_and_second",	"Statically disable writes to the first two color attachments",					mask_first_and_second,	kChannelCase.enabledChannels, true,  staticOrderingGroup.get(), testCtx);
		AddSingleTestCaseStatic("disable_second_and_last",	"Statically disable writes to the second and last color attachments",			mask_second_and_last,	kChannelCase.enabledChannels, true,  staticOrderingGroup.get(), testCtx);

		channelGroup->addChild(staticOrderingGroup.release());

		colorWriteEnableGroup->addChild(channelGroup.release());
	}

	return colorWriteEnableGroup.release();
}

} // pipeline
} // vkt
