/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 Google 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 Graphics pipeline for SPIR-V assembly tests
 *//*--------------------------------------------------------------------*/

#include "vktSpvAsmGraphicsShaderTestUtil.hpp"

#include "tcuFloat.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTextureUtil.hpp"

#include "vkDefs.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"

#include "deRandom.hpp"

namespace vkt
{
namespace SpirVAssembly
{

using namespace vk;
using std::map;
using std::string;
using std::vector;
using tcu::Float16;
using tcu::Float32;
using tcu::Float64;
using tcu::IVec3;
using tcu::IVec4;
using tcu::RGBA;
using tcu::TestLog;
using tcu::TestStatus;
using tcu::Vec4;
using de::UniquePtr;
using tcu::StringTemplate;
using tcu::Vec4;

deUint32 IFDataType::getElementNumBytes (void) const
{
	if (elementType < NUMBERTYPE_END32)
		return 4;

	if (elementType < NUMBERTYPE_END16)
		return 2;

	return 8;
}

VkFormat IFDataType::getVkFormat (void) const
{
	if (numElements == 1)
	{
		switch (elementType)
		{
			case NUMBERTYPE_FLOAT64:	return VK_FORMAT_R64_SFLOAT;
			case NUMBERTYPE_FLOAT32:	return VK_FORMAT_R32_SFLOAT;
			case NUMBERTYPE_INT32:		return VK_FORMAT_R32_SINT;
			case NUMBERTYPE_UINT32:		return VK_FORMAT_R32_UINT;
			case NUMBERTYPE_FLOAT16:	return VK_FORMAT_R16_SFLOAT;
			case NUMBERTYPE_INT16:		return VK_FORMAT_R16_SINT;
			case NUMBERTYPE_UINT16:		return VK_FORMAT_R16_UINT;
			default:					break;
		}
	}
	else if (numElements == 2)
	{
		switch (elementType)
		{
			case NUMBERTYPE_FLOAT64:	return VK_FORMAT_R64G64_SFLOAT;
			case NUMBERTYPE_FLOAT32:	return VK_FORMAT_R32G32_SFLOAT;
			case NUMBERTYPE_INT32:		return VK_FORMAT_R32G32_SINT;
			case NUMBERTYPE_UINT32:		return VK_FORMAT_R32G32_UINT;
			case NUMBERTYPE_FLOAT16:	return VK_FORMAT_R16G16_SFLOAT;
			case NUMBERTYPE_INT16:		return VK_FORMAT_R16G16_SINT;
			case NUMBERTYPE_UINT16:		return VK_FORMAT_R16G16_UINT;
			default:					break;
		}
	}
	else if (numElements == 3)
	{
		switch (elementType)
		{
			case NUMBERTYPE_FLOAT64:	return VK_FORMAT_R64G64B64_SFLOAT;
			case NUMBERTYPE_FLOAT32:	return VK_FORMAT_R32G32B32_SFLOAT;
			case NUMBERTYPE_INT32:		return VK_FORMAT_R32G32B32_SINT;
			case NUMBERTYPE_UINT32:		return VK_FORMAT_R32G32B32_UINT;
			case NUMBERTYPE_FLOAT16:	return VK_FORMAT_R16G16B16_SFLOAT;
			case NUMBERTYPE_INT16:		return VK_FORMAT_R16G16B16_SINT;
			case NUMBERTYPE_UINT16:		return VK_FORMAT_R16G16B16_UINT;
			default:					break;
		}
	}
	else if (numElements == 4)
	{
		switch (elementType)
		{
			case NUMBERTYPE_FLOAT64:	return VK_FORMAT_R64G64B64A64_SFLOAT;
			case NUMBERTYPE_FLOAT32:	return VK_FORMAT_R32G32B32A32_SFLOAT;
			case NUMBERTYPE_INT32:		return VK_FORMAT_R32G32B32A32_SINT;
			case NUMBERTYPE_UINT32:		return VK_FORMAT_R32G32B32A32_UINT;
			case NUMBERTYPE_FLOAT16:	return VK_FORMAT_R16G16B16A16_SFLOAT;
			case NUMBERTYPE_INT16:		return VK_FORMAT_R16G16B16A16_SINT;
			case NUMBERTYPE_UINT16:		return VK_FORMAT_R16G16B16A16_UINT;
			default:					break;
		}
	}

	DE_ASSERT(false);
	return VK_FORMAT_UNDEFINED;
}

tcu::TextureFormat IFDataType::getTextureFormat (void) const
{
	tcu::TextureFormat::ChannelType		ct	= tcu::TextureFormat::CHANNELTYPE_LAST;
	tcu::TextureFormat::ChannelOrder	co	= tcu::TextureFormat::CHANNELORDER_LAST;

	switch (elementType)
	{
		case NUMBERTYPE_FLOAT64:	ct = tcu::TextureFormat::FLOAT64;			break;
		case NUMBERTYPE_FLOAT32:	ct = tcu::TextureFormat::FLOAT;				break;
		case NUMBERTYPE_INT32:		ct = tcu::TextureFormat::SIGNED_INT32;		break;
		case NUMBERTYPE_UINT32:		ct = tcu::TextureFormat::UNSIGNED_INT32;	break;
		case NUMBERTYPE_FLOAT16:	ct = tcu::TextureFormat::HALF_FLOAT;		break;
		case NUMBERTYPE_INT16:		ct = tcu::TextureFormat::SIGNED_INT16;		break;
		case NUMBERTYPE_UINT16:		ct = tcu::TextureFormat::UNSIGNED_INT16;	break;
		default:					DE_ASSERT(false);
	}

	switch (numElements)
	{
		case 1:				co = tcu::TextureFormat::R;					break;
		case 2:				co = tcu::TextureFormat::RG;				break;
		case 3:				co = tcu::TextureFormat::RGB;				break;
		case 4:				co = tcu::TextureFormat::RGBA;				break;
		default:			DE_ASSERT(false);
	}

	return tcu::TextureFormat(co, ct);
}

string IFDataType::str (void) const
{
	string	ret;

	switch (elementType)
	{
		case NUMBERTYPE_FLOAT64:	ret = "f64"; break;
		case NUMBERTYPE_FLOAT32:	ret = "f32"; break;
		case NUMBERTYPE_INT32:		ret = "i32"; break;
		case NUMBERTYPE_UINT32:		ret = "u32"; break;
		case NUMBERTYPE_FLOAT16:	ret = "f16"; break;
		case NUMBERTYPE_INT16:		ret = "i16"; break;
		case NUMBERTYPE_UINT16:		ret = "u16"; break;
		default:					DE_ASSERT(false);
	}

	if (numElements == 1)
		return ret;

	return string("v") + numberToString(numElements) + ret;
}

VkBufferUsageFlagBits getMatchingBufferUsageFlagBit (VkDescriptorType dType)
{
	switch (dType)
	{
		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:			return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
		case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:			return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:			return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:			return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:	return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
		default:										DE_ASSERT(0 && "not implemented");
	}
	return (VkBufferUsageFlagBits)0;
}

VkImageUsageFlags getMatchingImageUsageFlags (VkDescriptorType dType)
{
	switch (dType)
	{
		case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:			return VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:			return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:	return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		default:										DE_FATAL("Not implemented");
	}
	return (VkImageUsageFlags)0;
}

static void requireFormatUsageSupport (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling imageTiling, VkImageUsageFlags requiredUsageFlags)
{
	VkFormatProperties		properties;
	VkFormatFeatureFlags	tilingFeatures	= 0;

	vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);

	switch (imageTiling)
	{
		case VK_IMAGE_TILING_LINEAR:
			tilingFeatures = properties.linearTilingFeatures;
			break;

		case VK_IMAGE_TILING_OPTIMAL:
			tilingFeatures = properties.optimalTilingFeatures;
			break;

		default:
			DE_ASSERT(false);
			break;
	}

	if ((requiredUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
	{
		if ((tilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
			TCU_THROW(NotSupportedError, "Image format cannot be used as color attachment");
		requiredUsageFlags ^= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
	}


	if ((requiredUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0)
	{
		if ((tilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) == 0)
			TCU_THROW(NotSupportedError, "Image format cannot be used as transfer source");
		requiredUsageFlags ^= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	}


	DE_ASSERT(!requiredUsageFlags && "checking other image usage bits not supported yet");
}

InstanceContext::InstanceContext (const RGBA						(&inputs)[4],
								  const RGBA						(&outputs)[4],
								  const map<string, string>&		testCodeFragments_,
								  const StageToSpecConstantMap&		specConstants_,
								  const PushConstants&				pushConsants_,
								  const GraphicsResources&			resources_,
								  const GraphicsInterfaces&			interfaces_,
								  const vector<string>&				extensions_,
								  VulkanFeatures					vulkanFeatures_,
								  VkShaderStageFlags				customizedStages_)
	: testCodeFragments				(testCodeFragments_)
	, specConstants					(specConstants_)
	, hasTessellation				(false)
	, requiredStages				(static_cast<VkShaderStageFlagBits>(0))
	, requiredDeviceExtensions		(extensions_)
	, requestedFeatures				(vulkanFeatures_)
	, pushConstants					(pushConsants_)
	, customizedStages				(customizedStages_)
	, resources						(resources_)
	, interfaces					(interfaces_)
	, failResult					(QP_TEST_RESULT_FAIL)
	, failMessageTemplate			("${reason}")
	, renderFullSquare				(false)
	, splitRenderArea				(false)
{
	inputColors[0]		= inputs[0];
	inputColors[1]		= inputs[1];
	inputColors[2]		= inputs[2];
	inputColors[3]		= inputs[3];

	outputColors[0]		= outputs[0];
	outputColors[1]		= outputs[1];
	outputColors[2]		= outputs[2];
	outputColors[3]		= outputs[3];
}

InstanceContext::InstanceContext (const InstanceContext& other)
	: moduleMap						(other.moduleMap)
	, testCodeFragments				(other.testCodeFragments)
	, specConstants					(other.specConstants)
	, hasTessellation				(other.hasTessellation)
	, requiredStages				(other.requiredStages)
	, requiredDeviceExtensions		(other.requiredDeviceExtensions)
	, requestedFeatures				(other.requestedFeatures)
	, pushConstants					(other.pushConstants)
	, customizedStages				(other.customizedStages)
	, resources						(other.resources)
	, interfaces					(other.interfaces)
	, failResult					(other.failResult)
	, failMessageTemplate			(other.failMessageTemplate)
	, renderFullSquare				(other.renderFullSquare)
	, splitRenderArea				(other.splitRenderArea)
{
	inputColors[0]		= other.inputColors[0];
	inputColors[1]		= other.inputColors[1];
	inputColors[2]		= other.inputColors[2];
	inputColors[3]		= other.inputColors[3];

	outputColors[0]		= other.outputColors[0];
	outputColors[1]		= other.outputColors[1];
	outputColors[2]		= other.outputColors[2];
	outputColors[3]		= other.outputColors[3];
}

string InstanceContext::getSpecializedFailMessage (const string& failureReason)
{
	map<string, string>		parameters;
	parameters["reason"]	= failureReason;
	return StringTemplate(failMessageTemplate).specialize(parameters);
}

ShaderElement::ShaderElement (const string&				moduleName_,
							  const string&				entryPoint_,
							  VkShaderStageFlagBits		shaderStage_)
		: moduleName(moduleName_)
		, entryName(entryPoint_)
		, stage(shaderStage_)
{
}

void getDefaultColors (RGBA (&colors)[4])
{
	colors[0] = RGBA::white();
	colors[1] = RGBA::red();
	colors[2] = RGBA::green();
	colors[3] = RGBA::blue();
}

void getHalfColorsFullAlpha (RGBA (&colors)[4])
{
	colors[0] = RGBA(127, 127, 127, 255);
	colors[1] = RGBA(127, 0,   0,	255);
	colors[2] = RGBA(0,	  127, 0,	255);
	colors[3] = RGBA(0,	  0,   127, 255);
}

void getInvertedDefaultColors (RGBA (&colors)[4])
{
	colors[0] = RGBA(0,		0,		0,		255);
	colors[1] = RGBA(0,		255,	255,	255);
	colors[2] = RGBA(255,	0,		255,	255);
	colors[3] = RGBA(255,	255,	0,		255);
}

// For the current InstanceContext, constructs the required modules and shader stage create infos.
void createPipelineShaderStages (const DeviceInterface&						vk,
								 const VkDevice								vkDevice,
								 InstanceContext&							instance,
								 Context&									context,
								 vector<ModuleHandleSp>&					modules,
								 vector<VkPipelineShaderStageCreateInfo>&	createInfos)
{
	for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
	{
		const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
		modules.push_back(ModuleHandleSp(mod));
		for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
		{
			const EntryToStage&						stage			= *shaderNdx;
			const VkPipelineShaderStageCreateInfo	shaderParam		=
			{
				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType			sType;
				DE_NULL,												//	const void*				pNext;
				(VkPipelineShaderStageCreateFlags)0,
				stage.second,											//	VkShaderStageFlagBits	stage;
				**modules.back(),										//	VkShaderModule			module;
				stage.first.c_str(),									//	const char*				pName;
				(const VkSpecializationInfo*)DE_NULL,
			};
			createInfos.push_back(shaderParam);
		}
	}
}

// Creates vertex-shader assembly by specializing a boilerplate StringTemplate
// on fragments, which must (at least) map "testfun" to an OpFunction definition
// for %test_code that takes and returns a %v4f32.  Boilerplate IDs are prefixed
// with "BP_" to avoid collisions with fragments.
//
// It corresponds roughly to this GLSL:
//;
// layout(location = 0) in vec4 position;
// layout(location = 1) in vec4 color;
// layout(location = 1) out highp vec4 vtxColor;
// void main (void) { gl_Position = position; vtxColor = test_func(color); }
string makeVertexShaderAssembly (const map<string, string>& fragments)
{
	static const char vertexShaderBoilerplate[] =
		"OpCapability Shader\n"
		"${capability:opt}\n"
		"${extension:opt}\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Vertex %BP_main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n"
		"${execution_mode:opt}\n"
		"${debug:opt}\n"
		"${moduleprocessed:opt}\n"
		"OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
		"OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
		"OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
		"OpDecorate %BP_gl_PerVertex Block\n"
		"OpDecorate %BP_position Location 0\n"
		"OpDecorate %BP_vtx_color Location 1\n"
		"OpDecorate %BP_color Location 1\n"
		"OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n"
		"OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n"
		"${IF_decoration:opt}\n"
		"${decoration:opt}\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n"
		"%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n"
		"%BP_position = OpVariable %ip_v4f32 Input\n"
		"%BP_vtx_color = OpVariable %op_v4f32 Output\n"
		"%BP_color = OpVariable %ip_v4f32 Input\n"
		"%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n"
		"%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n"
		"${pre_main:opt}\n"
		"${IF_variable:opt}\n"
		"%BP_main = OpFunction %void None %fun\n"
		"%BP_label = OpLabel\n"
		"${IF_carryforward:opt}\n"
		"${post_interface_op_vert:opt}\n"
		"%BP_pos = OpLoad %v4f32 %BP_position\n"
		"%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
		"OpStore %BP_gl_pos %BP_pos\n"
		"%BP_col = OpLoad %v4f32 %BP_color\n"
		"%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n"
		"OpStore %BP_vtx_color %BP_col_transformed\n"
		"OpReturn\n"
		"OpFunctionEnd\n"
		"${interface_op_func:opt}\n"

		"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
		"%getId_label = OpLabel\n"
		"%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n"
		"%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n"
		"OpReturnValue %is_id_0\n"
		"OpFunctionEnd\n"

		"${testfun}\n";
	return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments);
}

// Creates tess-control-shader assembly by specializing a boilerplate
// StringTemplate on fragments, which must (at least) map "testfun" to an
// OpFunction definition for %test_code that takes and returns a %v4f32.
// Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
//
// It roughly corresponds to the following GLSL.
//
// #version 450
// layout(vertices = 3) out;
// layout(location = 1) in vec4 in_color[];
// layout(location = 1) out vec4 out_color[];
//
// void main() {
//   out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]);
//   gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
//   if (gl_InvocationID == 0) {
//     gl_TessLevelOuter[0] = 1.0;
//     gl_TessLevelOuter[1] = 1.0;
//     gl_TessLevelOuter[2] = 1.0;
//     gl_TessLevelInner[0] = 1.0;
//   }
// }
string makeTessControlShaderAssembly (const map<string, string>& fragments)
{
	static const char tessControlShaderBoilerplate[] =
		"OpCapability Tessellation\n"
		"${capability:opt}\n"
		"${extension:opt}\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint TessellationControl %BP_main \"main\" %BP_out_color %BP_gl_InvocationID %BP_gl_PrimitiveID %BP_in_color %BP_gl_out %BP_gl_in %BP_gl_TessLevelOuter %BP_gl_TessLevelInner ${IF_entrypoint:opt} \n"
		"OpExecutionMode %BP_main OutputVertices 3\n"
		"${execution_mode:opt}\n"
		"${debug:opt}\n"
		"${moduleprocessed:opt}\n"
		"OpDecorate %BP_out_color Location 1\n"
		"OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
		"OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
		"OpDecorate %BP_in_color Location 1\n"
		"OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
		"OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
		"OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
		"OpDecorate %BP_gl_PerVertex Block\n"
		"OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n"
		"OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n"
		"OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n"
		"OpDecorate %BP_gl_PVOut Block\n"
		"OpDecorate %BP_gl_TessLevelOuter Patch\n"
		"OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
		"OpDecorate %BP_gl_TessLevelInner Patch\n"
		"OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
		"${IF_decoration:opt}\n"
		"${decoration:opt}\n"
		"${decoration_tessc:opt}\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%BP_out_color = OpVariable %op_a3v4f32 Output\n"
		"%BP_gl_InvocationID = OpVariable %ip_i32 Input\n"
		"%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
		"%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
		"%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n"
		"%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n"
		"%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n"
		"%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n"
		"%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n"
		"%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n"
		"%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
		"%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
		"${pre_main:opt}\n"
		"${IF_variable:opt}\n"

		"%BP_main = OpFunction %void None %fun\n"
		"%BP_label = OpLabel\n"
		"%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n"
		"${IF_carryforward:opt}\n"
		"${post_interface_op_tessc:opt}\n"
		"%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n"
		"%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n"
		"%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n"
		"%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n"
		"OpStore %BP_out_col_loc %BP_clr_transformed\n"

		"%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n"
		"%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n"
		"%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n"
		"OpStore %BP_out_pos_loc %BP_in_pos_val\n"

		"%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n"
		"OpSelectionMerge %BP_merge_label None\n"
		"OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n"
		"%BP_if_label = OpLabel\n"
		"%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n"
		"%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n"
		"%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n"
		"%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n"
		"OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n"
		"OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n"
		"OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n"
		"OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n"
		"OpBranch %BP_merge_label\n"
		"%BP_merge_label = OpLabel\n"
		"OpReturn\n"
		"OpFunctionEnd\n"
		"${interface_op_func:opt}\n"

		"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
		"%getId_label = OpLabel\n"
		"%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n"
		"%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
		"%is_invocation_0 = OpIEqual %bool %invocation_id %c_i32_0\n"
		"%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
		"%is_id_0 = OpLogicalAnd %bool %is_invocation_0 %is_primitive_0\n"
		"OpReturnValue %is_id_0\n"
		"OpFunctionEnd\n"

		"${testfun}\n";
	return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments);
}

// Creates tess-evaluation-shader assembly by specializing a boilerplate
// StringTemplate on fragments, which must (at least) map "testfun" to an
// OpFunction definition for %test_code that takes and returns a %v4f32.
// Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
//
// It roughly corresponds to the following glsl.
//
// #version 450
//
// layout(triangles, equal_spacing, ccw) in;
// layout(location = 1) in vec4 in_color[];
// layout(location = 1) out vec4 out_color;
//
// #define interpolate(val)
//   vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] +
//          vec4(gl_TessCoord.z) * val[2]
//
// void main() {
//   gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position +
//                  vec4(gl_TessCoord.y) * gl_in[1].gl_Position +
//                  vec4(gl_TessCoord.z) * gl_in[2].gl_Position;
//   out_color = testfun(interpolate(in_color));
// }
string makeTessEvalShaderAssembly (const map<string, string>& fragments)
{
	static const char tessEvalBoilerplate[] =
		"OpCapability Tessellation\n"
		"${capability:opt}\n"
		"${extension:opt}\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint TessellationEvaluation %BP_main \"main\" %BP_stream %BP_gl_TessCoord %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
		"OpExecutionMode %BP_main Triangles\n"
		"OpExecutionMode %BP_main SpacingEqual\n"
		"OpExecutionMode %BP_main VertexOrderCcw\n"
		"${execution_mode:opt}\n"
		"${debug:opt}\n"
		"${moduleprocessed:opt}\n"
		"OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
		"OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
		"OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n"
		"OpDecorate %BP_gl_PerVertexOut Block\n"
		"OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
		"OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n"
		"OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n"
		"OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n"
		"OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n"
		"OpDecorate %BP_gl_PerVertexIn Block\n"
		"OpDecorate %BP_out_color Location 1\n"
		"OpDecorate %BP_in_color Location 1\n"
		"${IF_decoration:opt}\n"
		"${decoration:opt}\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n"
		"%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n"
		"%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n"
		"%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
		"%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n"
		"%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n"
		"%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n"
		"%BP_out_color = OpVariable %op_v4f32 Output\n"
		"%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
		"${pre_main:opt}\n"
		"${IF_variable:opt}\n"
		"%BP_main = OpFunction %void None %fun\n"
		"%BP_label = OpLabel\n"
		"${IF_carryforward:opt}\n"
		"${post_interface_op_tesse:opt}\n"
		"%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
		"%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
		"%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
		"%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
		"%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
		"%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"

		"%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
		"%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
		"%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
		"%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"

		"%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n"
		"%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n"
		"%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n"
		"%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n"
		"%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n"
		"%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n"

		"%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n"
		"%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n"
		"%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n"

		"%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n"
		"%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n"
		"%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n"

		"%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n"
		"%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n"

		"OpStore %BP_gl_OPos %BP_pos_sum_1\n"

		"%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n"
		"%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n"
		"%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n"

		"%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n"
		"%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n"
		"%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n"

		"%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n"
		"%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n"

		"%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n"

		"OpStore %BP_out_color %BP_clr_transformed\n"
		"OpReturn\n"
		"OpFunctionEnd\n"
		"${interface_op_func:opt}\n"

		"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
		"%getId_label = OpLabel\n"
		"%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
		"%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
		"%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
		"%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
		"%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
		"%TC_W_0 = OpLoad %f32 %TC_0_loc\n"
		"%TC_W_1 = OpLoad %f32 %TC_1_loc\n"
		"%TC_W_2 = OpLoad %f32 %TC_2_loc\n"
		"%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n"
		"%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n"
		"%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n"
		"%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n"
		"%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n"
		"%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n"
		"OpReturnValue %is_unique_id_0\n"
		"OpFunctionEnd\n"

		"${testfun}\n";
	return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments);
}

// Creates geometry-shader assembly by specializing a boilerplate StringTemplate
// on fragments, which must (at least) map "testfun" to an OpFunction definition
// for %test_code that takes and returns a %v4f32.  Boilerplate IDs are prefixed
// with "BP_" to avoid collisions with fragments.
//
// Derived from this GLSL:
//
// #version 450
// layout(triangles) in;
// layout(triangle_strip, max_vertices = 3) out;
//
// layout(location = 1) in vec4 in_color[];
// layout(location = 1) out vec4 out_color;
//
// void main() {
//   gl_Position = gl_in[0].gl_Position;
//   out_color = test_fun(in_color[0]);
//   EmitVertex();
//   gl_Position = gl_in[1].gl_Position;
//   out_color = test_fun(in_color[1]);
//   EmitVertex();
//   gl_Position = gl_in[2].gl_Position;
//   out_color = test_fun(in_color[2]);
//   EmitVertex();
//   EndPrimitive();
// }
string makeGeometryShaderAssembly (const map<string, string>& fragments)
{
	static const char geometryShaderBoilerplate[] =
		"OpCapability Geometry\n"
		"${capability:opt}\n"
		"${extension:opt}\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Geometry %BP_main \"main\" %BP_out_gl_position %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
		"OpExecutionMode %BP_main Triangles\n"
		"OpExecutionMode %BP_main OutputTriangleStrip\n"
		"OpExecutionMode %BP_main OutputVertices 3\n"
		"${execution_mode:opt}\n"
		"${debug:opt}\n"
		"${moduleprocessed:opt}\n"
		"OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
		"OpDecorate %BP_out_gl_position BuiltIn Position\n"
		"OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
		"OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n"
		"OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n"
		"OpDecorate %BP_per_vertex_in Block\n"
		"OpDecorate %BP_out_color Location 1\n"
		"OpDecorate %BP_in_color Location 1\n"
		"${IF_decoration:opt}\n"
		"${decoration:opt}\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
		"%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
		"%BP_pp_i32 = OpTypePointer Private %i32\n"
		"%BP_pp_v4i32 = OpTypePointer Private %v4i32\n"

		"%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
		"%BP_out_color = OpVariable %op_v4f32 Output\n"
		"%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
		"%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
		"%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
		"%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n"
		"${pre_main:opt}\n"
		"${IF_variable:opt}\n"

		"%BP_main = OpFunction %void None %fun\n"
		"%BP_label = OpLabel\n"

		"${IF_carryforward:opt}\n"
		"${post_interface_op_geom:opt}\n"

		"%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n"
		"%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n"

		"%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
		"%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
		"%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"

		"%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n"
		"%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n"
		"%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n"

		"%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
		"%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
		"%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"

		"%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n"
		"%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
		"%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"

		"OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n"
		"%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
		"OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n"
		"%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
		"OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n"
		"%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"


		"OpStore %BP_out_gl_position %BP_in_position_0\n"
		"OpStore %BP_out_color %BP_transformed_in_color_0\n"
		"OpEmitVertex\n"

		"OpStore %BP_out_gl_position %BP_in_position_1\n"
		"OpStore %BP_out_color %BP_transformed_in_color_1\n"
		"OpEmitVertex\n"

		"OpStore %BP_out_gl_position %BP_in_position_2\n"
		"OpStore %BP_out_color %BP_transformed_in_color_2\n"
		"OpEmitVertex\n"

		"OpEndPrimitive\n"
		"OpReturn\n"
		"OpFunctionEnd\n"
		"${interface_op_func:opt}\n"

		"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
		"%getId_label = OpLabel\n"
		"%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
		"%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n"
		"%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n"
		"%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
		"%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n"
		"%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n"
		"OpReturnValue %is_unique_id_0\n"
		"OpFunctionEnd\n"

		"${testfun}\n";
	return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments);
}

// Creates fragment-shader assembly by specializing a boilerplate StringTemplate
// on fragments, which must (at least) map "testfun" to an OpFunction definition
// for %test_code that takes and returns a %v4f32.  Boilerplate IDs are prefixed
// with "BP_" to avoid collisions with fragments.
//
// Derived from this GLSL:
//
// layout(location = 1) in highp vec4 vtxColor;
// layout(location = 0) out highp vec4 fragColor;
// highp vec4 testfun(highp vec4 x) { return x; }
// void main(void) { fragColor = testfun(vtxColor); }
//
// with modifications including passing vtxColor by value and ripping out
// testfun() definition.
string makeFragmentShaderAssembly (const map<string, string>& fragments)
{
	static const char fragmentShaderBoilerplate[] =
		"OpCapability Shader\n"
		"${capability:opt}\n"
		"${extension:opt}\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n"
		"OpExecutionMode %BP_main OriginUpperLeft\n"
		"${execution_mode:opt}\n"
		"${debug:opt}\n"
		"${moduleprocessed:opt}\n"
		"OpDecorate %BP_fragColor Location 0\n"
		"OpDecorate %BP_vtxColor Location 1\n"
		"OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
		"${IF_decoration:opt}\n"
		"${decoration:opt}\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n"
		"%BP_fragColor = OpVariable %op_v4f32 Output\n"
		"%BP_vtxColor = OpVariable %ip_v4f32 Input\n"
		"${pre_main:opt}\n"
		"${IF_variable:opt}\n"
		"%BP_main = OpFunction %void None %fun\n"
		"%BP_label_main = OpLabel\n"
		"${IF_carryforward:opt}\n"
		"${post_interface_op_frag:opt}\n"
		"%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n"
		"%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n"
		"OpStore %BP_fragColor %BP_tmp2\n"
		"OpReturn\n"
		"OpFunctionEnd\n"
		"${interface_op_func:opt}\n"

		"%isUniqueIdZero = OpFunction %bool None %bool_function\n"
		"%getId_label = OpLabel\n"
		"%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
		"%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
		"%x_coord = OpLoad %f32 %loc_x_coord\n"
		"%y_coord = OpLoad %f32 %loc_y_coord\n"
		"%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n"
		"%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n"
		"%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n"
		"OpReturnValue %is_frag_0\n"
		"OpFunctionEnd\n"

		"${testfun}\n";
	return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments);
}

// Creates mappings from placeholders to pass-through shader code which copies
// the input to the output faithfully.
map<string, string> passthruInterface (const IFDataType& data_type)
{
	const string		var_type	= data_type.str();
	map<string, string>	fragments	= passthruFragments();
	const string		functype	= string("%") + var_type + "_" + var_type + "_function";

	fragments["interface_op_func"]	=
		string("%interface_op_func = OpFunction %") + var_type + " None " + functype + "\n"
		"               %io_param1 = OpFunctionParameter %" + var_type + "\n"
		"                %IF_label = OpLabel\n"
		"                            OpReturnValue %io_param1\n"
		"                            OpFunctionEnd\n";
	fragments["input_type"]			= var_type;
	fragments["output_type"]		= var_type;
	fragments["pre_main"]			= "";

	if (!data_type.elementIs32bit())
	{
		if (data_type.elementType == NUMBERTYPE_FLOAT64)
		{
			fragments["capability"]		= "OpCapability Float64\n\n";
			fragments["pre_main"]	+= "%f64 = OpTypeFloat 64\n";
		}
		else if (data_type.elementType == NUMBERTYPE_FLOAT16)
		{
			fragments["capability"]		= "OpCapability StorageInputOutput16\n";
			fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"\n";
			fragments["pre_main"]	+= "%f16 = OpTypeFloat 16\n";
		}
		else if (data_type.elementType == NUMBERTYPE_INT16)
		{
			fragments["capability"]		= "OpCapability StorageInputOutput16\n";
			fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"\n";
			fragments["pre_main"]	+= "%i16 = OpTypeInt 16 1\n";
		}
		else if (data_type.elementType == NUMBERTYPE_UINT16)
		{
			fragments["capability"]		= "OpCapability StorageInputOutput16\n";
			fragments["extension"]		= "OpExtension \"SPV_KHR_16bit_storage\"\n";
			fragments["pre_main"]	+= "%u16 = OpTypeInt 16 0\n";
		}
		else
		{
			DE_ASSERT(0 && "unhandled type");
		}

		if (data_type.isVector())
		{
			fragments["pre_main"]	+= "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n";
		}

		fragments["pre_main"]		+=
			"%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n"
			"%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n";
	}

	if (strcmp(var_type.c_str(), "v4f32") != 0)
		fragments["pre_main"]		+=
			functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n"
			"%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n"
			"%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n"
			"%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n";

	return fragments;
}

// Returns mappings from interface placeholders to their concrete values.
//
// The concrete values should be specialized again to provide ${input_type}
// and ${output_type}.
//
// %ip_${input_type} and %op_${output_type} should also be defined in the final code.
map<string, string> fillInterfacePlaceholderVert (void)
{
	map<string, string>	fragments;

	fragments["IF_entrypoint"]		= "%IF_input %IF_output";
	fragments["IF_variable"]		=
		" %IF_input = OpVariable %ip_${input_type} Input\n"
		"%IF_output = OpVariable %op_${output_type} Output\n";
	fragments["IF_decoration"]		=
		"OpDecorate  %IF_input Location 2\n"
		"OpDecorate %IF_output Location 2\n";
	fragments["IF_carryforward"]	=
		"%IF_input_val = OpLoad %${input_type} %IF_input\n"
		"   %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
		"                OpStore %IF_output %IF_result\n";

	// Make sure the rest still need to be instantialized.
	fragments["capability"]				= "${capability:opt}";
	fragments["extension"]				= "${extension:opt}";
	fragments["execution_mode"]			= "${execution_mode:opt}";
	fragments["debug"]					= "${debug:opt}";
	fragments["decoration"]				= "${decoration:opt}";
	fragments["pre_main"]				= "${pre_main:opt}";
	fragments["testfun"]				= "${testfun}";
	fragments["interface_op_func"]		= "${interface_op_func}";
	fragments["post_interface_op_vert"]	= "${post_interface_op_vert:opt}";

	return fragments;
}

// Returns mappings from interface placeholders to their concrete values.
//
// The concrete values should be specialized again to provide ${input_type}
// and ${output_type}.
//
// %ip_${input_type} and %op_${output_type} should also be defined in the final code.
map<string, string> fillInterfacePlaceholderFrag (void)
{
	map<string, string>	fragments;

	fragments["IF_entrypoint"]		= "%IF_input %IF_output";
	fragments["IF_variable"]		=
		" %IF_input = OpVariable %ip_${input_type} Input\n"
		"%IF_output = OpVariable %op_${output_type} Output\n";
	fragments["IF_decoration"]		=
		"OpDecorate %IF_input Flat\n"
		"OpDecorate %IF_input Location 2\n"
		"OpDecorate %IF_output Location 1\n";  // Fragment shader should write to location #1.
	fragments["IF_carryforward"]	=
		"%IF_input_val = OpLoad %${input_type} %IF_input\n"
		"   %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
		"                OpStore %IF_output %IF_result\n";

	// Make sure the rest still need to be instantialized.
	fragments["capability"]				= "${capability:opt}";
	fragments["extension"]				= "${extension:opt}";
	fragments["execution_mode"]			= "${execution_mode:opt}";
	fragments["debug"]					= "${debug:opt}";
	fragments["decoration"]				= "${decoration:opt}";
	fragments["pre_main"]				= "${pre_main:opt}";
	fragments["testfun"]				= "${testfun}";
	fragments["interface_op_func"]		= "${interface_op_func}";
	fragments["post_interface_op_frag"]	= "${post_interface_op_frag:opt}";

	return fragments;
}

// Returns mappings from interface placeholders to their concrete values.
//
// The concrete values should be specialized again to provide ${input_type}
// and ${output_type}.
//
// %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
// should also be defined in the final code.
map<string, string> fillInterfacePlaceholderTessCtrl (void)
{
	map<string, string>	fragments;

	fragments["IF_entrypoint"]		= "%IF_input %IF_output";
	fragments["IF_variable"]		=
		" %IF_input = OpVariable %ip_a3${input_type} Input\n"
		"%IF_output = OpVariable %op_a3${output_type} Output\n";
	fragments["IF_decoration"]		=
		"OpDecorate  %IF_input Location 2\n"
		"OpDecorate %IF_output Location 2\n";
	fragments["IF_carryforward"]	=
		" %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
		" %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n"
		" %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n"
		"%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n"
		"%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n"
		"%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n"
		"%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
		"%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n"
		"%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n"
		"%IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
		"%IF_input_res1 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val1\n"
		"%IF_input_res2 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val2\n"
		"OpStore %IF_output_ptr0 %IF_input_res0\n"
		"OpStore %IF_output_ptr1 %IF_input_res1\n"
		"OpStore %IF_output_ptr2 %IF_input_res2\n";

	// Make sure the rest still need to be instantialized.
	fragments["capability"]					= "${capability:opt}";
	fragments["extension"]					= "${extension:opt}";
	fragments["execution_mode"]				= "${execution_mode:opt}";
	fragments["debug"]						= "${debug:opt}";
	fragments["decoration"]					= "${decoration:opt}";
	fragments["decoration_tessc"]			= "${decoration_tessc:opt}";
	fragments["pre_main"]					= "${pre_main:opt}";
	fragments["testfun"]					= "${testfun}";
	fragments["interface_op_func"]			= "${interface_op_func}";
	fragments["post_interface_op_tessc"]	= "${post_interface_op_tessc:opt}";

	return fragments;
}

// Returns mappings from interface placeholders to their concrete values.
//
// The concrete values should be specialized again to provide ${input_type}
// and ${output_type}.
//
// %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
// should also be defined in the final code.
map<string, string> fillInterfacePlaceholderTessEvalGeom (void)
{
	map<string, string>	fragments;

	fragments["IF_entrypoint"]		= "%IF_input %IF_output";
	fragments["IF_variable"]		=
		" %IF_input = OpVariable %ip_a3${input_type} Input\n"
		"%IF_output = OpVariable %op_${output_type} Output\n";
	fragments["IF_decoration"]		=
		"OpDecorate  %IF_input Location 2\n"
		"OpDecorate %IF_output Location 2\n";
	fragments["IF_carryforward"]	=
		// Only get the first value since all three values are the same anyway.
		" %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
		" %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
		" %IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
		"OpStore %IF_output %IF_input_res0\n";

	// Make sure the rest still need to be instantialized.
	fragments["capability"]					= "${capability:opt}";
	fragments["extension"]					= "${extension:opt}";
	fragments["execution_mode"]				= "${execution_mode:opt}";
	fragments["debug"]						= "${debug:opt}";
	fragments["decoration"]					= "${decoration:opt}";
	fragments["pre_main"]					= "${pre_main:opt}";
	fragments["testfun"]					= "${testfun}";
	fragments["interface_op_func"]			= "${interface_op_func}";
	fragments["post_interface_op_tesse"]	= "${post_interface_op_tesse:opt}";
	fragments["post_interface_op_geom"]		= "${post_interface_op_geom:opt}";

	return fragments;
}

map<string, string> passthruFragments (void)
{
	map<string, string> fragments;
	fragments["testfun"] =
		// A %test_code function that returns its argument unchanged.
		"%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
		"%param1 = OpFunctionParameter %v4f32\n"
		"%label_testfun = OpLabel\n"
		"OpReturnValue %param1\n"
		"OpFunctionEnd\n";
	return fragments;
}

// Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
// Vertex shader gets custom code from context, the rest are pass-through.
void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
{
	const deUint32 vulkanVersion = dst.usedVulkanVersion;
	SpirvVersion targetSpirvVersion;

	if (spirVAsmBuildOptions == DE_NULL)
		targetSpirvVersion = context.resources.spirvVersion;
	else
		targetSpirvVersion = spirVAsmBuildOptions->targetVersion;

	if (!context.interfaces.empty())
	{
		// Inject boilerplate code to wire up additional input/output variables between stages.
		// Just copy the contents in input variable to output variable in all stages except
		// the customized stage.
		dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	} else {
		map<string, string> passthru = passthruFragments();

		dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
}

void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext context)
{
	addShaderCodeCustomVertex(dst, context, DE_NULL);
}

// Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
// Tessellation control shader gets custom code from context, the rest are
// pass-through.
void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
{
	const deUint32 vulkanVersion = dst.usedVulkanVersion;
	SpirvVersion targetSpirvVersion;

	if (spirVAsmBuildOptions == DE_NULL)
		targetSpirvVersion = context.resources.spirvVersion;
	else
		targetSpirvVersion = spirVAsmBuildOptions->targetVersion;

	if (!context.interfaces.empty())
	{
		// Inject boilerplate code to wire up additional input/output variables between stages.
		// Just copy the contents in input variable to output variable in all stages except
		// the customized stage.
		dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
	else
	{
		map<string, string> passthru = passthruFragments();

		dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
}

void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext context)
{
	addShaderCodeCustomTessControl(dst, context, DE_NULL);
}

// Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
// Tessellation evaluation shader gets custom code from context, the rest are
// pass-through.
void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
{
	const deUint32 vulkanVersion = dst.usedVulkanVersion;
	SpirvVersion targetSpirvVersion;

	if (spirVAsmBuildOptions == DE_NULL)
		targetSpirvVersion = context.resources.spirvVersion;
	else
		targetSpirvVersion = spirVAsmBuildOptions->targetVersion;

	if (!context.interfaces.empty())
	{
		// Inject boilerplate code to wire up additional input/output variables between stages.
		// Just copy the contents in input variable to output variable in all stages except
		// the customized stage.
		dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
	else
	{
		map<string, string> passthru = passthruFragments();
		dst.spirvAsmSources.add("vert",  spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag",  spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
}

void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext context)
{
	addShaderCodeCustomTessEval(dst, context, DE_NULL);
}

// Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
// Geometry shader gets custom code from context, the rest are pass-through.
void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
{
	const deUint32 vulkanVersion = dst.usedVulkanVersion;
	SpirvVersion targetSpirvVersion;

	if (spirVAsmBuildOptions == DE_NULL)
		targetSpirvVersion = context.resources.spirvVersion;
	else
		targetSpirvVersion = spirVAsmBuildOptions->targetVersion;

	if (!context.interfaces.empty())
	{
		// Inject boilerplate code to wire up additional input/output variables between stages.
		// Just copy the contents in input variable to output variable in all stages except
		// the customized stage.
		dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
	else
	{
		map<string, string> passthru = passthruFragments();
		dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << makeGeometryShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
}

void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext context)
{
	addShaderCodeCustomGeometry(dst, context, DE_NULL);
}

// Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
// Fragment shader gets custom code from context, the rest are pass-through.
void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
{
	const deUint32 vulkanVersion = dst.usedVulkanVersion;
	SpirvVersion targetSpirvVersion;

	if (spirVAsmBuildOptions == DE_NULL)
		targetSpirvVersion = context.resources.spirvVersion;
	else
		targetSpirvVersion = spirVAsmBuildOptions->targetVersion;

	if (!context.interfaces.empty())
	{
		// Inject boilerplate code to wire up additional input/output variables between stages.
		// Just copy the contents in input variable to output variable in all stages except
		// the customized stage.
		dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
	else
	{
		map<string, string> passthru = passthruFragments();
		dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
		dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
	}
}

void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext context)
{
	addShaderCodeCustomFragment(dst, context, DE_NULL);
}

void createCombinedModule (vk::SourceCollections& dst, InstanceContext ctx)
{
	const bool			useTessellation	(ctx.requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
	const bool			useGeometry		(ctx.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT);
	std::stringstream	combinedModule;
	std::stringstream	opCapabilities;
	std::stringstream	opEntryPoints;

	// opCapabilities
	{
		opCapabilities << "OpCapability Shader\n";

		if (useGeometry)
			opCapabilities << "OpCapability Geometry\n";

		if (useTessellation)
			opCapabilities << "OpCapability Tessellation\n";
	}

	// opEntryPoints
	{
		if (useTessellation)
			opEntryPoints << "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n";
		else
			opEntryPoints << "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_glPerVertex %vert_vertex_id %vert_instance_id\n";

		if (useGeometry)
			opEntryPoints << "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n";

		if (useTessellation)
		{
			opEntryPoints <<	"OpEntryPoint TessellationControl %tessc_main \"main\" %tessc_out_color %tessc_gl_InvocationID %tessc_in_color %tessc_out_position %tessc_in_position %tessc_gl_TessLevelOuter %tessc_gl_TessLevelInner\n"
								"OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n";
		}

		opEntryPoints << "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n";
	}

	combinedModule	<<	opCapabilities.str()
					<<	"OpMemoryModel Logical GLSL450\n"
					<<	opEntryPoints.str();

	if (useGeometry)
	{
		combinedModule <<	"OpExecutionMode %geom_main Triangles\n"
							"OpExecutionMode %geom_main OutputTriangleStrip\n"
							"OpExecutionMode %geom_main OutputVertices 3\n";
	}

	if (useTessellation)
	{
		combinedModule <<	"OpExecutionMode %tessc_main OutputVertices 3\n"
							"OpExecutionMode %tesse_main Triangles\n"
							"OpExecutionMode %tesse_main SpacingEqual\n"
							"OpExecutionMode %tesse_main VertexOrderCcw\n";
	}

	combinedModule <<	"OpExecutionMode %frag_main OriginUpperLeft\n"

						"; Vertex decorations\n"
						"OpDecorate %vert_Position Location 0\n"
						"OpDecorate %vert_vtxColor Location 1\n"
						"OpDecorate %vert_color Location 1\n"
						"OpDecorate %vert_vertex_id BuiltIn VertexIndex\n"
						"OpDecorate %vert_instance_id BuiltIn InstanceIndex\n";

	// If tessellation is used, vertex position is written by tessellation stage.
	// Otherwise it will be written by vertex stage.
	if (useTessellation)
		combinedModule <<	"OpDecorate %vert_vtxPosition Location 2\n";
	else
	{
		combinedModule <<	"OpMemberDecorate %vert_per_vertex_out 0 BuiltIn Position\n"
							"OpMemberDecorate %vert_per_vertex_out 1 BuiltIn PointSize\n"
							"OpMemberDecorate %vert_per_vertex_out 2 BuiltIn ClipDistance\n"
							"OpMemberDecorate %vert_per_vertex_out 3 BuiltIn CullDistance\n"
							"OpDecorate %vert_per_vertex_out Block\n";
	}

	if (useGeometry)
	{
		combinedModule <<	"; Geometry decorations\n"
							"OpDecorate %geom_out_gl_position BuiltIn Position\n"
							"OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n"
							"OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n"
							"OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n"
							"OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n"
							"OpDecorate %geom_per_vertex_in Block\n"
							"OpDecorate %geom_out_color Location 1\n"
							"OpDecorate %geom_in_color Location 1\n";
	}

	if (useTessellation)
	{
		combinedModule <<	"; Tessellation Control decorations\n"
							"OpDecorate %tessc_out_color Location 1\n"
							"OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n"
							"OpDecorate %tessc_in_color Location 1\n"
							"OpDecorate %tessc_out_position Location 2\n"
							"OpDecorate %tessc_in_position Location 2\n"
							"OpDecorate %tessc_gl_TessLevelOuter Patch\n"
							"OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
							"OpDecorate %tessc_gl_TessLevelInner Patch\n"
							"OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n"

							"; Tessellation Evaluation decorations\n"
							"OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n"
							"OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n"
							"OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n"
							"OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n"
							"OpDecorate %tesse_per_vertex_out Block\n"
							"OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n"
							"OpDecorate %tesse_in_position Location 2\n"
							"OpDecorate %tesse_out_color Location 1\n"
							"OpDecorate %tesse_in_color Location 1\n";
	}

	combinedModule <<	"; Fragment decorations\n"
						"OpDecorate %frag_fragColor Location 0\n"
						"OpDecorate %frag_vtxColor Location 1\n"

						SPIRV_ASSEMBLY_TYPES
						SPIRV_ASSEMBLY_CONSTANTS
						SPIRV_ASSEMBLY_ARRAYS

						"; Vertex Variables\n"
						"%vert_Position = OpVariable %ip_v4f32 Input\n"
						"%vert_vtxColor = OpVariable %op_v4f32 Output\n"
						"%vert_color = OpVariable %ip_v4f32 Input\n"
						"%vert_vertex_id = OpVariable %ip_i32 Input\n"
						"%vert_instance_id = OpVariable %ip_i32 Input\n";

	if (useTessellation)
		combinedModule <<	"%vert_vtxPosition = OpVariable %op_v4f32 Output\n";
	else
	{
		combinedModule <<	"%vert_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
							"%vert_op_per_vertex_out = OpTypePointer Output %vert_per_vertex_out\n"
							"%vert_glPerVertex = OpVariable %vert_op_per_vertex_out Output\n";
	}

	if (useGeometry)
	{
		combinedModule <<	"; Geometry Variables\n"
							"%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
							"%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n"
							"%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n"
							"%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n"
							"%geom_out_color = OpVariable %op_v4f32 Output\n"
							"%geom_in_color = OpVariable %ip_a3v4f32 Input\n"
							"%geom_out_gl_position = OpVariable %op_v4f32 Output\n";
	}

	if (useTessellation)
	{
		combinedModule <<	"; Tessellation Control Variables\n"
							"%tessc_out_color = OpVariable %op_a3v4f32 Output\n"
							"%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n"
							"%tessc_in_color = OpVariable %ip_a32v4f32 Input\n"
							"%tessc_out_position = OpVariable %op_a3v4f32 Output\n"
							"%tessc_in_position = OpVariable %ip_a32v4f32 Input\n"
							"%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
							"%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"

							"; Tessellation Evaluation Decorations\n"
							"%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
							"%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n"
							"%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n"
							"%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n"
							"%tesse_in_position = OpVariable %ip_a32v4f32 Input\n"
							"%tesse_out_color = OpVariable %op_v4f32 Output\n"
							"%tesse_in_color = OpVariable %ip_a32v4f32 Input\n";
	}

	combinedModule	<<	"; Fragment Variables\n"
						"%frag_fragColor = OpVariable %op_v4f32 Output\n"
						"%frag_vtxColor = OpVariable %ip_v4f32 Input\n"

						"; Vertex Entry\n"
						"%vert_main = OpFunction %void None %fun\n"
						"%vert_label = OpLabel\n"
						"%vert_tmp_position = OpLoad %v4f32 %vert_Position\n";

	if (useTessellation)
		combinedModule <<	"OpStore %vert_vtxPosition %vert_tmp_position\n";
	else
	{
		combinedModule <<	"%vert_out_pos_ptr = OpAccessChain %op_v4f32 %vert_glPerVertex %c_i32_0\n"
							"OpStore %vert_out_pos_ptr %vert_tmp_position\n";
	}

	combinedModule <<	"%vert_tmp_color = OpLoad %v4f32 %vert_color\n"
						"OpStore %vert_vtxColor %vert_tmp_color\n"
						"OpReturn\n"
						"OpFunctionEnd\n";

	if (useGeometry)
	{
		combinedModule <<	"; Geometry Entry\n"
							"%geom_main = OpFunction %void None %fun\n"
							"%geom_label = OpLabel\n"
							"%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n"
							"%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n"
							"%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n"
							"%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n"
							"%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n"
							"%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n"
							"%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n"
							"%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n"
							"%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n"
							"%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n"
							"%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n"
							"%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n"
							"OpStore %geom_out_gl_position %geom_in_position_0\n"
							"OpStore %geom_out_color %geom_in_color_0\n"
							"OpEmitVertex\n"
							"OpStore %geom_out_gl_position %geom_in_position_1\n"
							"OpStore %geom_out_color %geom_in_color_1\n"
							"OpEmitVertex\n"
							"OpStore %geom_out_gl_position %geom_in_position_2\n"
							"OpStore %geom_out_color %geom_in_color_2\n"
							"OpEmitVertex\n"
							"OpEndPrimitive\n"
							"OpReturn\n"
							"OpFunctionEnd\n";
	}

	if (useTessellation)
	{
		combinedModule <<	"; Tessellation Control Entry\n"
							"%tessc_main = OpFunction %void None %fun\n"
							"%tessc_label = OpLabel\n"
							"%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n"
							"%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n"
							"%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n"
							"%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n"
							"%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n"
							"%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n"
							"%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n"
							"OpStore %tessc_out_color_ptr %tessc_in_color_val\n"
							"OpStore %tessc_out_position_ptr %tessc_in_position_val\n"
							"%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n"
							"OpSelectionMerge %tessc_merge_label None\n"
							"OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n"
							"%tessc_first_invocation = OpLabel\n"
							"%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n"
							"%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n"
							"%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n"
							"%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n"
							"OpStore %tessc_tess_outer_0 %c_f32_1\n"
							"OpStore %tessc_tess_outer_1 %c_f32_1\n"
							"OpStore %tessc_tess_outer_2 %c_f32_1\n"
							"OpStore %tessc_tess_inner %c_f32_1\n"
							"OpBranch %tessc_merge_label\n"
							"%tessc_merge_label = OpLabel\n"
							"OpReturn\n"
							"OpFunctionEnd\n"

							"; Tessellation Evaluation Entry\n"
							"%tesse_main = OpFunction %void None %fun\n"
							"%tesse_label = OpLabel\n"
							"%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n"
							"%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n"
							"%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n"
							"%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n"
							"%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n"
							"%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n"
							"%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n"
							"%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n"
							"%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n"
							"%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n"
							"%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n"
							"%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n"
							"%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n"
							"%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n"
							"%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n"
							"%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n"
							"%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n"
							"%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n"
							"OpStore %tesse_out_pos_ptr %tesse_computed_out\n"
							"%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n"
							"%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n"
							"%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n"
							"%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n"
							"%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n"
							"%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n"
							"%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n"
							"%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n"
							"%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n"
							"%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n"
							"%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n"
							"OpStore %tesse_out_color %tesse_computed_clr\n"
							"OpReturn\n"
							"OpFunctionEnd\n";
	}

	combinedModule	<<	"; Fragment Entry\n"
						"%frag_main = OpFunction %void None %fun\n"
						"%frag_label_main = OpLabel\n"
						"%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n"
						"OpStore %frag_fragColor %frag_tmp1\n"
						"OpReturn\n"
						"OpFunctionEnd\n";

	dst.spirvAsmSources.add("module") << combinedModule.str();
}

void createMultipleEntries (vk::SourceCollections& dst, InstanceContext)
{
	dst.spirvAsmSources.add("vert") <<
	// This module contains 2 vertex shaders. One that is a passthrough
	// and a second that inverts the color of the output (1.0 - color).
		"OpCapability Shader\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
		"OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"

		"OpDecorate %vtxPosition Location 2\n"
		"OpDecorate %Position Location 0\n"
		"OpDecorate %vtxColor Location 1\n"
		"OpDecorate %color Location 1\n"
		"OpDecorate %vertex_id BuiltIn VertexIndex\n"
		"OpDecorate %instance_id BuiltIn InstanceIndex\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
		"%vtxPosition = OpVariable %op_v4f32 Output\n"
		"%Position = OpVariable %ip_v4f32 Input\n"
		"%vtxColor = OpVariable %op_v4f32 Output\n"
		"%color = OpVariable %ip_v4f32 Input\n"
		"%vertex_id = OpVariable %ip_i32 Input\n"
		"%instance_id = OpVariable %ip_i32 Input\n"

		"%main = OpFunction %void None %fun\n"
		"%label = OpLabel\n"
		"%tmp_position = OpLoad %v4f32 %Position\n"
		"OpStore %vtxPosition %tmp_position\n"
		"%tmp_color = OpLoad %v4f32 %color\n"
		"OpStore %vtxColor %tmp_color\n"
		"OpReturn\n"
		"OpFunctionEnd\n"

		"%main2 = OpFunction %void None %fun\n"
		"%label2 = OpLabel\n"
		"%tmp_position2 = OpLoad %v4f32 %Position\n"
		"OpStore %vtxPosition %tmp_position2\n"
		"%tmp_color2 = OpLoad %v4f32 %color\n"
		"%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n"
		"%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n"
		"OpStore %vtxColor %tmp_color4\n"
		"OpReturn\n"
		"OpFunctionEnd\n";

	dst.spirvAsmSources.add("frag") <<
		// This is a single module that contains 2 fragment shaders.
		// One that passes color through and the other that inverts the output
		// color (1.0 - color).
		"OpCapability Shader\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n"
		"OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n"
		"OpExecutionMode %main OriginUpperLeft\n"
		"OpExecutionMode %main2 OriginUpperLeft\n"

		"OpDecorate %fragColor Location 0\n"
		"OpDecorate %vtxColor Location 1\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
		"%fragColor = OpVariable %op_v4f32 Output\n"
		"%vtxColor = OpVariable %ip_v4f32 Input\n"

		"%main = OpFunction %void None %fun\n"
		"%label_main = OpLabel\n"
		"%tmp1 = OpLoad %v4f32 %vtxColor\n"
		"OpStore %fragColor %tmp1\n"
		"OpReturn\n"
		"OpFunctionEnd\n"

		"%main2 = OpFunction %void None %fun\n"
		"%label_main2 = OpLabel\n"
		"%tmp2 = OpLoad %v4f32 %vtxColor\n"
		"%tmp3 = OpFSub %v4f32 %cval %tmp2\n"
		"%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n"
		"OpStore %fragColor %tmp4\n"
		"OpReturn\n"
		"OpFunctionEnd\n";

	dst.spirvAsmSources.add("geom") <<
		"OpCapability Geometry\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n"
		"OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n"
		"OpExecutionMode %geom1_main Triangles\n"
		"OpExecutionMode %geom2_main Triangles\n"
		"OpExecutionMode %geom1_main OutputTriangleStrip\n"
		"OpExecutionMode %geom2_main OutputTriangleStrip\n"
		"OpExecutionMode %geom1_main OutputVertices 3\n"
		"OpExecutionMode %geom2_main OutputVertices 3\n"
		"OpDecorate %out_gl_position BuiltIn Position\n"
		"OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
		"OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
		"OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
		"OpDecorate %per_vertex_in Block\n"
		"OpDecorate %out_color Location 1\n"
		"OpDecorate %in_color Location 1\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
		"%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
		"%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
		"%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
		"%out_color = OpVariable %op_v4f32 Output\n"
		"%in_color = OpVariable %ip_a3v4f32 Input\n"
		"%out_gl_position = OpVariable %op_v4f32 Output\n"

		"%geom1_main = OpFunction %void None %fun\n"
		"%geom1_label = OpLabel\n"
		"%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
		"%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
		"%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
		"%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
		"%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
		"%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
		"%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
		"%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
		"%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
		"%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
		"%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
		"%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
		"OpStore %out_gl_position %geom1_in_position_0\n"
		"OpStore %out_color %geom1_in_color_0\n"
		"OpEmitVertex\n"
		"OpStore %out_gl_position %geom1_in_position_1\n"
		"OpStore %out_color %geom1_in_color_1\n"
		"OpEmitVertex\n"
		"OpStore %out_gl_position %geom1_in_position_2\n"
		"OpStore %out_color %geom1_in_color_2\n"
		"OpEmitVertex\n"
		"OpEndPrimitive\n"
		"OpReturn\n"
		"OpFunctionEnd\n"

		"%geom2_main = OpFunction %void None %fun\n"
		"%geom2_label = OpLabel\n"
		"%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
		"%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
		"%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
		"%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n"
		"%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n"
		"%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n"
		"%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
		"%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
		"%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
		"%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n"
		"%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n"
		"%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n"
		"%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n"
		"%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n"
		"%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n"
		"%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n"
		"%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n"
		"%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n"
		"OpStore %out_gl_position %geom2_in_position_0\n"
		"OpStore %out_color %geom2_transformed_in_color_0_a\n"
		"OpEmitVertex\n"
		"OpStore %out_gl_position %geom2_in_position_1\n"
		"OpStore %out_color %geom2_transformed_in_color_1_a\n"
		"OpEmitVertex\n"
		"OpStore %out_gl_position %geom2_in_position_2\n"
		"OpStore %out_color %geom2_transformed_in_color_2_a\n"
		"OpEmitVertex\n"
		"OpEndPrimitive\n"
		"OpReturn\n"
		"OpFunctionEnd\n";

	dst.spirvAsmSources.add("tessc") <<
		"OpCapability Tessellation\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
		"OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
		"OpExecutionMode %tessc1_main OutputVertices 3\n"
		"OpExecutionMode %tessc2_main OutputVertices 3\n"
		"OpDecorate %out_color Location 1\n"
		"OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
		"OpDecorate %in_color Location 1\n"
		"OpDecorate %out_position Location 2\n"
		"OpDecorate %in_position Location 2\n"
		"OpDecorate %gl_TessLevelOuter Patch\n"
		"OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
		"OpDecorate %gl_TessLevelInner Patch\n"
		"OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
		"%out_color = OpVariable %op_a3v4f32 Output\n"
		"%gl_InvocationID = OpVariable %ip_i32 Input\n"
		"%in_color = OpVariable %ip_a32v4f32 Input\n"
		"%out_position = OpVariable %op_a3v4f32 Output\n"
		"%in_position = OpVariable %ip_a32v4f32 Input\n"
		"%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
		"%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"

		"%tessc1_main = OpFunction %void None %fun\n"
		"%tessc1_label = OpLabel\n"
		"%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
		"%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
		"%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
		"%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
		"%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
		"%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
		"%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
		"OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
		"OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
		"%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
		"OpSelectionMerge %tessc1_merge_label None\n"
		"OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
		"%tessc1_first_invocation = OpLabel\n"
		"%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
		"%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
		"%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
		"%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
		"OpStore %tessc1_tess_outer_0 %c_f32_1\n"
		"OpStore %tessc1_tess_outer_1 %c_f32_1\n"
		"OpStore %tessc1_tess_outer_2 %c_f32_1\n"
		"OpStore %tessc1_tess_inner %c_f32_1\n"
		"OpBranch %tessc1_merge_label\n"
		"%tessc1_merge_label = OpLabel\n"
		"OpReturn\n"
		"OpFunctionEnd\n"

		"%tessc2_main = OpFunction %void None %fun\n"
		"%tessc2_label = OpLabel\n"
		"%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n"
		"%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n"
		"%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n"
		"%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n"
		"%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n"
		"%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n"
		"%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n"
		"%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n"
		"%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n"
		"OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n"
		"OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n"
		"%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n"
		"OpSelectionMerge %tessc2_merge_label None\n"
		"OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n"
		"%tessc2_first_invocation = OpLabel\n"
		"%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
		"%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
		"%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
		"%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
		"OpStore %tessc2_tess_outer_0 %c_f32_1\n"
		"OpStore %tessc2_tess_outer_1 %c_f32_1\n"
		"OpStore %tessc2_tess_outer_2 %c_f32_1\n"
		"OpStore %tessc2_tess_inner %c_f32_1\n"
		"OpBranch %tessc2_merge_label\n"
		"%tessc2_merge_label = OpLabel\n"
		"OpReturn\n"
		"OpFunctionEnd\n";

	dst.spirvAsmSources.add("tesse") <<
		"OpCapability Tessellation\n"
		"OpMemoryModel Logical GLSL450\n"
		"OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
		"OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
		"OpExecutionMode %tesse1_main Triangles\n"
		"OpExecutionMode %tesse1_main SpacingEqual\n"
		"OpExecutionMode %tesse1_main VertexOrderCcw\n"
		"OpExecutionMode %tesse2_main Triangles\n"
		"OpExecutionMode %tesse2_main SpacingEqual\n"
		"OpExecutionMode %tesse2_main VertexOrderCcw\n"
		"OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
		"OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
		"OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
		"OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
		"OpDecorate %per_vertex_out Block\n"
		"OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
		"OpDecorate %in_position Location 2\n"
		"OpDecorate %out_color Location 1\n"
		"OpDecorate %in_color Location 1\n"
		SPIRV_ASSEMBLY_TYPES
		SPIRV_ASSEMBLY_CONSTANTS
		SPIRV_ASSEMBLY_ARRAYS
		"%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
		"%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
		"%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
		"%stream = OpVariable %op_per_vertex_out Output\n"
		"%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
		"%in_position = OpVariable %ip_a32v4f32 Input\n"
		"%out_color = OpVariable %op_v4f32 Output\n"
		"%in_color = OpVariable %ip_a32v4f32 Input\n"

		"%tesse1_main = OpFunction %void None %fun\n"
		"%tesse1_label = OpLabel\n"
		"%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
		"%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
		"%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
		"%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
		"%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
		"%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
		"%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
		"%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
		"%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
		"%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
		"%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
		"%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
		"%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
		"%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
		"%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
		"%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
		"%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
		"%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
		"OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
		"%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
		"%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
		"%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
		"%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
		"%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
		"%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
		"%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
		"%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
		"%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
		"%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
		"%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
		"OpStore %out_color %tesse1_computed_clr\n"
		"OpReturn\n"
		"OpFunctionEnd\n"

		"%tesse2_main = OpFunction %void None %fun\n"
		"%tesse2_label = OpLabel\n"
		"%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
		"%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
		"%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
		"%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n"
		"%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n"
		"%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n"
		"%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
		"%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
		"%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
		"%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n"
		"%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n"
		"%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n"
		"%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n"
		"%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n"
		"%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n"
		"%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
		"%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n"
		"%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n"
		"OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n"
		"%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
		"%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
		"%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
		"%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n"
		"%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n"
		"%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n"
		"%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n"
		"%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n"
		"%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n"
		"%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n"
		"%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n"
		"%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n"
		"%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n"
		"OpStore %out_color %tesse2_clr_transformed_a\n"
		"OpReturn\n"
		"OpFunctionEnd\n";
}

bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
{
	// We only support RTE, RTZ, or both.
	DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);

	const Float32	originalFloat	(original);
	const Float16	returnedFloat	(returned);

	// Zero are turned into zero under both RTE and RTZ.
	if (originalFloat.isZero())
	{
		if (returnedFloat.isZero())
			return true;

		log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// Any denormalized value input into a shader may be flushed to 0.
	if (originalFloat.isDenorm() && returnedFloat.isZero())
		return true;

	// Inf are always turned into Inf with the same sign, too.
	if (originalFloat.isInf())
	{
		if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
			return true;

		log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// NaN are always turned into NaN, too.
	if (originalFloat.isNaN())
	{
		if (returnedFloat.isNaN())
			return true;

		log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// Check all rounding modes
	for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
	{
		if ((flags & (1u << bitNdx)) == 0)
			continue;	// This rounding mode is not selected.

		const Float16	expectedFloat	(deFloat32To16Round(original, deRoundingMode(bitNdx)));

		// Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
		if (expectedFloat.isDenorm() && returnedFloat.isZero())
			return true;

		// If not matched in the above cases, they should have the same bit pattern.
		if (expectedFloat.bits() == returnedFloat.bits())
			return true;
	}

	log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
	return false;
}

bool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log)
{
	const Float16	originalFloat	(original);
	const Float16	returnedFloat	(returned);

	if (originalFloat.isZero())
	{
		if (returnedFloat.isZero())
			return true;

		log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// Any denormalized value input into a shader or potentially generated by any instruction in a shader
	// may be flushed to 0.
	if (originalFloat.isDenorm() && returnedFloat.isZero())
		return true;

	// Inf are always turned into Inf with the same sign, too.
	if (originalFloat.isInf())
	{
		if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
			return true;

		log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// NaN are always turned into NaN, too.
	if (originalFloat.isNaN())
	{
		if (returnedFloat.isNaN())
			return true;

		log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// If not matched in the above cases, they should have the same bit pattern.
	if (originalFloat.bits() == returnedFloat.bits())
		return true;

	log << TestLog::Message << "Error: found unmatched 16-bit and 16-bit floats: " << original << " vs " << returned << TestLog::EndMessage;
	return false;
}

bool compare16BitFloat(deUint16 original, float returned, tcu::TestLog & log)
{
	const Float16	originalFloat	(original);
	const Float32	returnedFloat	(returned);

	// Zero are turned into zero under both RTE and RTZ.
	if (originalFloat.isZero())
	{
		if (returnedFloat.isZero())
			return true;

		log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// Any denormalized value input into a shader may be flushed to 0.
	if (originalFloat.isDenorm() && returnedFloat.isZero())
		return true;

	// Inf are always turned into Inf with the same sign, too.
	if (originalFloat.isInf())
	{
		if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
			return true;

		log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// NaN are always turned into NaN, too.
	if (originalFloat.isNaN())
	{
		if (returnedFloat.isNaN())
			return true;

		log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// In all other cases, conversion should be exact.
	const Float32 expectedFloat (deFloat16To32(original));
	if (expectedFloat.bits() == returnedFloat.bits())
		return true;

	log << TestLog::Message << "Error: found unmatched 16-bit and 32-bit floats: " << original << " vs " << returnedFloat.bits() << TestLog::EndMessage;
	return false;
}

bool compare16BitFloat (deFloat16 original, deFloat16 returned, std::string& error)
{
	std::ostringstream	log;
	const Float16		originalFloat	(original);
	const Float16		returnedFloat	(returned);

	if (originalFloat.isZero())
	{
		if (returnedFloat.isZero())
			return true;

		log << "Error: expected zero but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
		error = log.str();
		return false;
	}

	// Any denormalized value input into a shader may be flushed to 0.
	if (originalFloat.isDenorm() && returnedFloat.isZero())
		return true;

	// Inf are always turned into Inf with the same sign, too.
	if (originalFloat.isInf())
	{
		if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
			return true;

		log << "Error: expected Inf but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
		error = log.str();
		return false;
	}

	// NaN are always turned into NaN, too.
	if (originalFloat.isNaN())
	{
		if (returnedFloat.isNaN())
			return true;

		log << "Error: expected NaN but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
		error = log.str();
		return false;
	}

	// Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
	if (originalFloat.isDenorm() && returnedFloat.isZero())
		return true;

	// If not matched in the above cases, they should have the same bit pattern.
	if (originalFloat.bits() == returnedFloat.bits())
		return true;

	log << "Error: found unmatched 16-bit and 16-bit floats: 0x"
		<< std::hex << original << " <=> 0x" << returned
		<< " (" << originalFloat.asFloat() << " <=> " << returnedFloat.asFloat() << ")";
	error = log.str();
	return false;
}

bool compare16BitFloat64 (double original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
{
	// We only support RTE, RTZ, or both.
	DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);

	const Float64	originalFloat	(original);
	const Float16	returnedFloat	(returned);

	// Zero are turned into zero under both RTE and RTZ.
	if (originalFloat.isZero())
	{
		if (returnedFloat.isZero())
			return true;

		log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// Any denormalized value input into a shader may be flushed to 0.
	if (originalFloat.isDenorm() && returnedFloat.isZero())
		return true;

	// Inf are always turned into Inf with the same sign, too.
	if (originalFloat.isInf())
	{
		if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
			return true;

		log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// NaN are always turned into NaN, too.
	if (originalFloat.isNaN())
	{
		if (returnedFloat.isNaN())
			return true;

		log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
		return false;
	}

	// Check all rounding modes
	for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
	{
		if ((flags & (1u << bitNdx)) == 0)
			continue;	// This rounding mode is not selected.

		const Float16	expectedFloat	(deFloat64To16Round(original, deRoundingMode(bitNdx)));

		// Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
		if (expectedFloat.isDenorm() && returnedFloat.isZero())
			return true;

		// If not matched in the above cases, they should have the same bit pattern.
		if (expectedFloat.bits() == returnedFloat.bits())
			return true;
	}

	log << TestLog::Message << "Error: found unmatched 64-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
	return false;
}

bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
{
	const Float32	expectedFloat	(expected);
	const Float32	returnedFloat	(returned);

	// Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
	if (expectedFloat.isDenorm() && returnedFloat.isZero())
		return true;

	{
		const Float16	originalFloat	(deFloat32To16(expected));

		// Any denormalized value input into a shader may be flushed to 0.
		if (originalFloat.isDenorm() && returnedFloat.isZero())
			return true;
	}

	if (expectedFloat.isNaN())
	{
		if (returnedFloat.isNaN())
			return true;

		log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
		return false;
	}

	if (returned == expected)
		return true;

	log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage;
	return false;
}

bool compare64BitFloat (double expected, double returned, tcu::TestLog& log)
{
	const Float64	expectedDouble	(expected);
	const Float64	returnedDouble	(returned);

	// Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
	if (expectedDouble.isDenorm() && returnedDouble.isZero())
		return true;

	{
		const Float16	originalDouble	(deFloat64To16(expected));

		// Any denormalized value input into a shader may be flushed to 0.
		if (originalDouble.isDenorm() && returnedDouble.isZero())
			return true;
	}

	if (expectedDouble.isNaN())
	{
		if (returnedDouble.isNaN())
			return true;

		log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
		return false;
	}

	if (returned == expected)
		return true;

	log << TestLog::Message << "Error: found unmatched 64-bit float: expected " << expectedDouble.bits() << " vs. returned " << returnedDouble.bits() << TestLog::EndMessage;
	return false;
}

Move<VkBuffer> createBufferForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
{
	const vk::VkDescriptorType resourceType = resource.getDescriptorType();

	vector<deUint8>	resourceBytes;
	resource.getBytes(resourceBytes);

	const VkBufferCreateInfo	resourceBufferParams	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,								// sType
		DE_NULL,															// pNext
		(VkBufferCreateFlags)0,												// flags
		(VkDeviceSize)resourceBytes.size(),									// size
		(VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resourceType),	// usage
		VK_SHARING_MODE_EXCLUSIVE,											// sharingMode
		1u,																	// queueFamilyCount
		&queueFamilyIndex,													// pQueueFamilyIndices
	};

	return createBuffer(vk, vkDevice, &resourceBufferParams);
}

Move<VkImage> createImageForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, VkFormat inputFormat, deUint32 queueFamilyIndex)
{
	const VkImageCreateInfo	resourceImageParams	=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								//	VkStructureType		sType;
		DE_NULL,															//	const void*			pNext;
		0u,																	//	VkImageCreateFlags	flags;
		VK_IMAGE_TYPE_2D,													//	VkImageType			imageType;
		inputFormat,														//	VkFormat			format;
		{ 8, 8, 1 },														//	VkExtent3D			extent;
		1u,																	//	deUint32			mipLevels;
		1u,																	//	deUint32			arraySize;
		VK_SAMPLE_COUNT_1_BIT,												//	deUint32			samples;
		VK_IMAGE_TILING_OPTIMAL,											//	VkImageTiling		tiling;
		getMatchingImageUsageFlags(resource.getDescriptorType()),			//	VkImageUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,											//	VkSharingMode		sharingMode;
		1u,																	//	deUint32			queueFamilyCount;
		&queueFamilyIndex,													//	const deUint32*		pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED											//	VkImageLayout		initialLayout;
	};

	return createImage(vk, vkDevice, &resourceImageParams);
}

void copyBufferToImage (const DeviceInterface& vk, const VkDevice& device, const VkQueue& queue, VkCommandBuffer cmdBuffer, VkBuffer buffer, VkImage image, VkImageAspectFlags aspect)
{
	const VkBufferImageCopy			copyRegion			=
	{
		0u,												// VkDeviceSize				bufferOffset;
		0u,												// deUint32					bufferRowLength;
		0u,												// deUint32					bufferImageHeight;
		{
			aspect,											// VkImageAspectFlags		aspect;
			0u,												// deUint32					mipLevel;
			0u,												// deUint32					baseArrayLayer;
			1u,												// deUint32					layerCount;
		},												// VkImageSubresourceLayers	imageSubresource;
		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
		{ 8, 8, 1 }										// VkExtent3D				imageExtent;
	};

	// Copy buffer to image
	beginCommandBuffer(vk, cmdBuffer);

	copyBufferToImage(vk, cmdBuffer, buffer, VK_WHOLE_SIZE, vector<VkBufferImageCopy>(1, copyRegion), aspect, 1u, 1u, image, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);

	endCommandBuffer(vk, cmdBuffer);

	submitCommandsAndWait(vk, device, queue, cmdBuffer);
}

VkImageAspectFlags getImageAspectFlags (VkFormat format)
{
	const tcu::TextureFormat::ChannelOrder	channelOrder	= vk::mapVkFormat(format).order;
	VkImageAspectFlags						aspectFlags		= (VkImageAspectFlags)0u;

	if (tcu::hasDepthComponent(channelOrder))
		aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;

	if (tcu::hasStencilComponent(channelOrder))
		aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;

	if (!aspectFlags)
		aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT;

	return aspectFlags;
};

TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
{
	if (getMinRequiredVulkanVersion(instance.resources.spirvVersion) > context.getUsedApiVersion())
	{
		TCU_THROW(NotSupportedError, string("Vulkan higher than or equal to " + getVulkanName(getMinRequiredVulkanVersion(instance.resources.spirvVersion)) + " is required for this test to run").c_str());
	}

	const DeviceInterface&						vk						= context.getDeviceInterface();
	const InstanceInterface&					vkInstance				= context.getInstanceInterface();
	const VkPhysicalDevice						vkPhysicalDevice		= context.getPhysicalDevice();
	const deUint32								queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
	const VkQueue								queue					= context.getUniversalQueue();
	const VkDevice&								device					= context.getDevice();
	Allocator&									allocator				= context.getDefaultAllocator();
	vector<ModuleHandleSp>						modules;
	map<VkShaderStageFlagBits, VkShaderModule>	moduleByStage;
	const deUint32								fullRenderSize			= 256;
	const deUint32								quarterRenderSize		= 64;
	const tcu::UVec2							renderSize				(fullRenderSize, fullRenderSize);
	const int									testSpecificSeed		= 31354125;
	const int									seed					= context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed;
	bool										supportsGeometry		= false;
	bool										supportsTessellation	= false;
	bool										hasGeometry				= false;
	bool										hasTessellation			= false;
	const bool									hasPushConstants		= !instance.pushConstants.empty();
	const deUint32								numResources			= static_cast<deUint32>(instance.resources.inputs.size() + instance.resources.outputs.size());
	const bool									needInterface			= !instance.interfaces.empty();
	const VkPhysicalDeviceFeatures&				features				= context.getDeviceFeatures();
	const Vec4									defaulClearColor		(0.125f, 0.25f, 0.75f, 1.0f);
	bool										splitRenderArea			= instance.splitRenderArea;

	const deUint32								renderDimension			= splitRenderArea ? quarterRenderSize : fullRenderSize;
	const int									numRenderSegments		= splitRenderArea ? 4 : 1;

	supportsGeometry		= features.geometryShader == VK_TRUE;
	supportsTessellation	= features.tessellationShader == VK_TRUE;
	hasGeometry				= (instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT);
	hasTessellation			= (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ||
								(instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);

	if (hasGeometry && !supportsGeometry)
	{
		TCU_THROW(NotSupportedError, "Geometry not supported");
	}

	if (hasTessellation && !supportsTessellation)
	{
		TCU_THROW(NotSupportedError, "Tessellation not supported");
	}

	// Check all required extensions are supported
	for (std::vector<std::string>::const_iterator i = instance.requiredDeviceExtensions.begin(); i != instance.requiredDeviceExtensions.end(); ++i)
	{
		if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), *i))
			TCU_THROW(NotSupportedError, (std::string("Extension not supported: ") + *i).c_str());
	}

	// Core features
	{
		const VkShaderStageFlags		vertexPipelineStoresAndAtomicsAffected	= vk::VK_SHADER_STAGE_VERTEX_BIT
																				| vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
																				| vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
																				| vk::VK_SHADER_STAGE_GEOMETRY_BIT;
		const char*						unsupportedFeature						= DE_NULL;
		vk::VkPhysicalDeviceFeatures	localRequiredCoreFeatures				= instance.requestedFeatures.coreFeatures;

		// reset fragment stores and atomics feature requirement
		if ((localRequiredCoreFeatures.fragmentStoresAndAtomics != DE_FALSE) &&
			(instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
		{
			localRequiredCoreFeatures.fragmentStoresAndAtomics = DE_FALSE;
		}

		// reset vertex pipeline stores and atomics feature requirement
		if (localRequiredCoreFeatures.vertexPipelineStoresAndAtomics != DE_FALSE &&
			(instance.customizedStages & vertexPipelineStoresAndAtomicsAffected) == 0)
		{
			localRequiredCoreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
		}

		if (!isCoreFeaturesSupported(context, localRequiredCoreFeatures, &unsupportedFeature))
			TCU_THROW(NotSupportedError, std::string("At least following requested core feature is not supported: ") + unsupportedFeature);
	}

	// Extension features
	{
		// 8bit storage features
		{
			if (!is8BitStorageFeaturesSupported(context, instance.requestedFeatures.ext8BitStorage))
				TCU_THROW(NotSupportedError, "Requested 8bit storage features not supported");
		}

		// 16bit storage features
		{
			if (!is16BitStorageFeaturesSupported(context, instance.requestedFeatures.ext16BitStorage))
				TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
		}

		// Variable Pointers features
		{
			if (!isVariablePointersFeaturesSupported(context, instance.requestedFeatures.extVariablePointers))
				TCU_THROW(NotSupportedError, "Requested Variable Pointer features not supported");
		}

		// Float16/Int8 shader features
		{
			if (!isFloat16Int8FeaturesSupported(context, instance.requestedFeatures.extFloat16Int8))
				TCU_THROW(NotSupportedError, "Requested 16bit float or 8bit int feature not supported");
		}
	}

	// FloatControls features
	{
		if (!isFloatControlsFeaturesSupported(context, instance.requestedFeatures.floatControlsProperties))
			TCU_THROW(NotSupportedError, "Requested Float Controls features not supported");
	}

	// Check Interface Input/Output formats are supported
	if (needInterface)
	{
		VkFormatProperties formatProperties;
		vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getInputType().getVkFormat(), &formatProperties);
		if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0)
		{
			std::string	error				= "Interface Input format (";
			const std::string formatName	= getFormatName(instance.interfaces.getInputType().getVkFormat());
			error += formatName + ") not supported";
			TCU_THROW(NotSupportedError, error.c_str());
		}

		vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getOutputType().getVkFormat(), &formatProperties);
		if (((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) ||
			((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0))
		{
			std::string	error				= "Interface Output format (";
			const std::string formatName	= getFormatName(instance.interfaces.getInputType().getVkFormat());
			error += formatName + ") not supported";
			TCU_THROW(NotSupportedError, error.c_str());
		}
	}

	de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
	de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
	const Vec4								vertexData[]			=
	{
		// Upper left corner:
		Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),	//1
		Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),	//2
		Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(),	//3

		// Upper right corner:
		Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),	//4
		Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),	//5
		Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(),	//6

		// Lower left corner:
		Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(),	//7
		Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),	//8
		Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),	//9

		// Lower right corner:
		Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(),	//10
		Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),	//11
		Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),	//12

		// The rest is used only renderFullSquare specified. Fills area already filled with clear color
		// Left 1
		Vec4(-1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor,					//3
		Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,					//2
		Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor,					//7

		// Left 2
		Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor,					//7
		Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,					//2
		Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,					//8

		// Left-Center
		Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,					//8
		Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,					//2
		Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,					//4

		// Right-Center
		Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,					//4
		Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,					//12
		Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,					//8

		// Right 2
		Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor,					//4
		Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor,					//6
		Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,					//12

		// Right 1
		Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor,					//12
		Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor,					//6
		Vec4(+1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor,					//10
	};

	const size_t							singleVertexDataSize	= 2 * sizeof(Vec4);
	const size_t							vertexCount				= instance.renderFullSquare ? sizeof(vertexData) / singleVertexDataSize : 4*3;
	const size_t							vertexDataSize			= vertexCount * singleVertexDataSize;

	Move<VkBuffer>							vertexInputBuffer;
	de::MovePtr<Allocation>					vertexInputMemory;
	Move<VkBuffer>							fragOutputBuffer;
	de::MovePtr<Allocation>					fragOutputMemory;
	Move<VkImage>							fragOutputImage;
	de::MovePtr<Allocation>					fragOutputImageMemory;
	Move<VkImageView>						fragOutputImageView;

	const VkBufferCreateInfo				vertexBufferParams		=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType;
		DE_NULL,								//	const void*			pNext;
		0u,										//	VkBufferCreateFlags	flags;
		(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size;
		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode;
		1u,										//	deUint32			queueFamilyCount;
		&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices;
	};
	const Unique<VkBuffer>					vertexBuffer			(createBuffer(vk, device, &vertexBufferParams));
	const UniquePtr<Allocation>				vertexBufferMemory		(allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(device, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

	const VkDeviceSize						imageSizeBytes			= (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
	const VkBufferCreateInfo				readImageBufferParams	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		//	VkStructureType		sType;
		DE_NULL,									//	const void*			pNext;
		0u,											//	VkBufferCreateFlags	flags;
		imageSizeBytes,								//	VkDeviceSize		size;
		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			//	VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,					//	VkSharingMode		sharingMode;
		1u,											//	deUint32			queueFamilyCount;
		&queueFamilyIndex,							//	const deUint32*		pQueueFamilyIndices;
	};
	const Unique<VkBuffer>					readImageBuffer			(createBuffer(vk, device, &readImageBufferParams));
	const UniquePtr<Allocation>				readImageBufferMemory	(allocator.allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));

	VkImageCreateInfo						imageParams				=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									//	VkStructureType		sType;
		DE_NULL,																//	const void*			pNext;
		0u,																		//	VkImageCreateFlags	flags;
		VK_IMAGE_TYPE_2D,														//	VkImageType			imageType;
		VK_FORMAT_R8G8B8A8_UNORM,												//	VkFormat			format;
		{ renderSize.x(), renderSize.y(), 1 },									//	VkExtent3D			extent;
		1u,																		//	deUint32			mipLevels;
		1u,																		//	deUint32			arraySize;
		VK_SAMPLE_COUNT_1_BIT,													//	deUint32			samples;
		VK_IMAGE_TILING_OPTIMAL,												//	VkImageTiling		tiling;
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	//	VkImageUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,												//	VkSharingMode		sharingMode;
		1u,																		//	deUint32			queueFamilyCount;
		&queueFamilyIndex,														//	const deUint32*		pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,												//	VkImageLayout		initialLayout;
	};

	const Unique<VkImage>					image					(createImage(vk, device, &imageParams));
	const UniquePtr<Allocation>				imageMemory				(allocator.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any));

	VK_CHECK(vk.bindImageMemory(device, *image, imageMemory->getMemory(), imageMemory->getOffset()));

	if (needInterface)
	{
		// The pipeline renders four triangles, each with three vertexes.
		// Test instantialization only provides four data points, each
		// for one triangle. So we need allocate space of three times of
		// input buffer's size.
		vector<deUint8>							inputBufferBytes;
		instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);

		const deUint32							inputNumBytes			= deUint32(inputBufferBytes.size() * 3);
		// Create an additional buffer and backing memory for one input variable.
		const VkBufferCreateInfo				vertexInputParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		//	VkStructureType		sType;
			DE_NULL,									//	const void*			pNext;
			0u,											//	VkBufferCreateFlags	flags;
			inputNumBytes,								//	VkDeviceSize		size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			//	VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					//	VkSharingMode		sharingMode;
			1u,											//	deUint32			queueFamilyCount;
			&queueFamilyIndex,							//	const deUint32*		pQueueFamilyIndices;
		};

		vertexInputBuffer = createBuffer(vk, device, &vertexInputParams);
		vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexInputBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(device, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));

		// Create an additional buffer and backing memory for an output variable.
		const VkDeviceSize						fragOutputImgSize		= (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
		const VkBufferCreateInfo				fragOutputParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		//	VkStructureType		sType;
			DE_NULL,									//	const void*			pNext;
			0u,											//	VkBufferCreateFlags	flags;
			fragOutputImgSize,							//	VkDeviceSize		size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			//	VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					//	VkSharingMode		sharingMode;
			1u,											//	deUint32			queueFamilyCount;
			&queueFamilyIndex,							//	const deUint32*		pQueueFamilyIndices;
		};
		fragOutputBuffer = createBuffer(vk, device, &fragOutputParams);
		fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *fragOutputBuffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(device, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));

		// Create an additional image and backing memory for attachment.
		// Reuse the previous imageParams since we only need to change the image format.
		imageParams.format		= instance.interfaces.getOutputType().getVkFormat();

		// Check the usage bits on the given image format are supported.
		requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage);

		fragOutputImage			= createImage(vk, device, &imageParams);
		fragOutputImageMemory	= allocator.allocate(getImageMemoryRequirements(vk, device, *fragOutputImage), MemoryRequirement::Any);

		VK_CHECK(vk.bindImageMemory(device, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
	}

	vector<VkAttachmentDescription>			colorAttDescs;
	vector<VkAttachmentReference>			colorAttRefs;
	{
		const VkAttachmentDescription		attDesc					=
		{
			0u,												//	VkAttachmentDescriptionFlags	flags;
			VK_FORMAT_R8G8B8A8_UNORM,						//	VkFormat						format;
			VK_SAMPLE_COUNT_1_BIT,							//	deUint32						samples;
			VK_ATTACHMENT_LOAD_OP_CLEAR,					//	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;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//	VkImageLayout					initialLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//	VkImageLayout					finalLayout;
		};
		colorAttDescs.push_back(attDesc);

		const VkAttachmentReference			attRef					=
		{
			0u,												//	deUint32		attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//	VkImageLayout	layout;
		};
		colorAttRefs.push_back(attRef);
	}

	if (needInterface)
	{
		const VkAttachmentDescription		attDesc					=
		{
			0u,													//	VkAttachmentDescriptionFlags	flags;
			instance.interfaces.getOutputType().getVkFormat(),	//	VkFormat						format;
			VK_SAMPLE_COUNT_1_BIT,								//	deUint32						samples;
			VK_ATTACHMENT_LOAD_OP_CLEAR,						//	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;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			//	VkImageLayout					initialLayout;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			//	VkImageLayout					finalLayout;
		};
		colorAttDescs.push_back(attDesc);

		const VkAttachmentReference			attRef					=
		{
			1u,												//	deUint32		attachment;
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		//	VkImageLayout	layout;
		};
		colorAttRefs.push_back(attRef);
	}

	VkSubpassDescription					subpassDesc				=
	{
		0u,												//	VkSubpassDescriptionFlags		flags;
		VK_PIPELINE_BIND_POINT_GRAPHICS,				//	VkPipelineBindPoint				pipelineBindPoint;
		0u,												//	deUint32						inputCount;
		DE_NULL,										//	const VkAttachmentReference*	pInputAttachments;
		1u,												//	deUint32						colorCount;
		colorAttRefs.data(),							//	const VkAttachmentReference*	pColorAttachments;
		DE_NULL,										//	const VkAttachmentReference*	pResolveAttachments;
		DE_NULL,										//	const VkAttachmentReference*	pDepthStencilAttachment;
		0u,												//	deUint32						preserveCount;
		DE_NULL,										//	const VkAttachmentReference*	pPreserveAttachments;

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

	if (needInterface)
	{
		subpassDesc.colorAttachmentCount += 1;
		renderPassParams.attachmentCount += 1;
	}

	const Unique<VkRenderPass>				renderPass				(createRenderPass(vk, device, &renderPassParams));

	const VkImageViewCreateInfo				colorAttViewParams		=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		//	VkStructureType				sType;
		DE_NULL,										//	const void*					pNext;
		0u,												//	VkImageViewCreateFlags		flags;
		*image,											//	VkImage						image;
		VK_IMAGE_VIEW_TYPE_2D,							//	VkImageViewType				viewType;
		VK_FORMAT_R8G8B8A8_UNORM,						//	VkFormat					format;
		{
			VK_COMPONENT_SWIZZLE_R,
			VK_COMPONENT_SWIZZLE_G,
			VK_COMPONENT_SWIZZLE_B,
			VK_COMPONENT_SWIZZLE_A
		},												//	VkChannelMapping			channels;
		{
			VK_IMAGE_ASPECT_COLOR_BIT,						//	VkImageAspectFlags	aspectMask;
			0u,												//	deUint32			baseMipLevel;
			1u,												//	deUint32			mipLevels;
			0u,												//	deUint32			baseArrayLayer;
			1u,												//	deUint32			arraySize;
		},												//	VkImageSubresourceRange		subresourceRange;
	};
	const Unique<VkImageView>				colorAttView			(createImageView(vk, device, &colorAttViewParams));
	const VkImageAspectFlags				inputImageAspect		= getImageAspectFlags(instance.resources.inputFormat);

	vector<VkImageView>						attViews;
	attViews.push_back(*colorAttView);

	// Handle resources requested by the test instantiation.
	const deUint32							numInResources			= static_cast<deUint32>(instance.resources.inputs.size());
	const deUint32							numOutResources			= static_cast<deUint32>(instance.resources.outputs.size());
	// These variables should be placed out of the following if block to avoid deallocation after out of scope.
	vector<AllocationSp>					inResourceMemories;
	vector<AllocationSp>					outResourceMemories;
	vector<BufferHandleSp>					inResourceBuffers;
	vector<BufferHandleSp>					outResourceBuffers;
	vector<ImageHandleSp>					inResourceImages;
	vector<ImageViewHandleSp>				inResourceImageViews;
	vector<SamplerHandleSp>					inResourceSamplers;
	Move<VkDescriptorPool>					descriptorPool;
	Move<VkDescriptorSetLayout>				setLayout;
	VkDescriptorSetLayout					rawSetLayout			= DE_NULL;
	VkDescriptorSet							rawSet					= DE_NULL;

	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));

	// Command buffer
	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	if (numResources != 0)
	{
		vector<VkDescriptorSetLayoutBinding>	setLayoutBindings;
		vector<VkDescriptorPoolSize>			poolSizes;

		setLayoutBindings.reserve(numResources);
		poolSizes.reserve(numResources);

		// Process all input resources.
		for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
		{
			const Resource&	resource	= instance.resources.inputs[inputNdx];

			const bool		hasImage	= (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)	||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)	||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);

			const bool		hasSampler	= (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)	||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER)			||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);

			// Resource is a buffer
			if (!hasImage && !hasSampler)
			{
				Move<VkBuffer>					resourceBuffer			= createBufferForResource(vk, device, resource, queueFamilyIndex);
				de::MovePtr<Allocation>			resourceMemory			= allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);

				VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));

				// Copy data to memory.
				{
					const VkMappedMemoryRange		range					=
					{
						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,				//	VkStructureType	sType;
						DE_NULL,											//	const void*		pNext;
						resourceMemory->getMemory(),						//	VkDeviceMemory	mem;
						0,													//	VkDeviceSize	offset;
						VK_WHOLE_SIZE,										//	VkDeviceSize	size;
					};

					vector<deUint8>					resourceBytes;
					resource.getBytes(resourceBytes);

					deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
					VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
				}

				inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
				inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
			}
			// Resource is an image
			else if (hasImage)
			{
				Move<VkBuffer>					resourceBuffer			= createBufferForResource(vk, device, resource, queueFamilyIndex);
				de::MovePtr<Allocation>			resourceMemory			= allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);

				VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));

				// Copy data to memory.
				{
					const VkMappedMemoryRange		range					=
					{
						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,				//	VkStructureType	sType;
						DE_NULL,											//	const void*		pNext;
						resourceMemory->getMemory(),						//	VkDeviceMemory	mem;
						0,													//	VkDeviceSize	offset;
						VK_WHOLE_SIZE,										//	VkDeviceSize	size;
					};

					vector<deUint8>					resourceBytes;
					resource.getBytes(resourceBytes);

					deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
					VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
				}

				Move<VkImage>					resourceImage			= createImageForResource(vk, device, resource, instance.resources.inputFormat, queueFamilyIndex);
				de::MovePtr<Allocation>			resourceImageMemory		= allocator.allocate(getImageMemoryRequirements(vk, device, *resourceImage), MemoryRequirement::Any);

				VK_CHECK(vk.bindImageMemory(device, *resourceImage, resourceImageMemory->getMemory(), resourceImageMemory->getOffset()));

				copyBufferToImage(vk, device, queue, *cmdBuf, resourceBuffer.get(), resourceImage.get(), inputImageAspect);

				inResourceMemories.push_back(AllocationSp(resourceImageMemory.release()));
				inResourceImages.push_back(ImageHandleSp(new ImageHandleUp(resourceImage)));
			}

			// Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
			const VkDescriptorSetLayoutBinding	binding				=
			{
				inputNdx,											// binding
				resource.getDescriptorType(),						// descriptorType
				1u,													// descriptorCount
				VK_SHADER_STAGE_ALL_GRAPHICS,						// stageFlags
				DE_NULL,											// pImmutableSamplers
			};
			setLayoutBindings.push_back(binding);

			// Note: the following code doesn't check and unify descriptors of the same type.
			const VkDescriptorPoolSize		poolSize				=
			{
				resource.getDescriptorType(),						// type
				1u,													// descriptorCount
			};
			poolSizes.push_back(poolSize);
		}

		// Process all output resources.
		for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
		{
			const Resource&					resource				= instance.resources.outputs[outputNdx];
			// Create buffer and allocate memory.
			Move<VkBuffer>					resourceBuffer			= createBufferForResource(vk, device, resource, queueFamilyIndex);
			de::MovePtr<Allocation>			resourceMemory			= allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
			vector<deUint8>					resourceBytes;

			VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));

			// Fill memory with all ones.
			const VkMappedMemoryRange		range					=
			{
				VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,				//	VkStructureType	sType;
				DE_NULL,											//	const void*		pNext;
				resourceMemory->getMemory(),						//	VkDeviceMemory	mem;
				0,													//	VkDeviceSize	offset;
				VK_WHOLE_SIZE,										//	VkDeviceSize	size;
			};

			resource.getBytes(resourceBytes);
			deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size());
			VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));

			outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
			outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));

			// Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
			const VkDescriptorSetLayoutBinding	binding				=
			{
				numInResources  + outputNdx,						// binding
				resource.getDescriptorType(),						// descriptorType
				1u,													// descriptorCount
				VK_SHADER_STAGE_ALL_GRAPHICS,						// stageFlags
				DE_NULL,											// pImmutableSamplers
			};
			setLayoutBindings.push_back(binding);

			// Note: the following code doesn't check and unify descriptors of the same type.
			const VkDescriptorPoolSize		poolSize				=
			{
				resource.getDescriptorType(),						// type
				1u,													// descriptorCount
			};
			poolSizes.push_back(poolSize);
		}

		// Create descriptor set layout, descriptor pool, and allocate descriptor set.
		const VkDescriptorSetLayoutCreateInfo	setLayoutParams		=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// sType
			DE_NULL,												// pNext
			(VkDescriptorSetLayoutCreateFlags)0,					// flags
			numResources,											// bindingCount
			setLayoutBindings.data(),								// pBindings
		};
		setLayout													= createDescriptorSetLayout(vk, device, &setLayoutParams);
		rawSetLayout												= *setLayout;

		const VkDescriptorPoolCreateInfo		poolParams			=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// sType
			DE_NULL,												// pNext
			(VkDescriptorPoolCreateFlags)0,							// flags
			1u,														// maxSets
			numResources,											// poolSizeCount
			poolSizes.data(),										// pPoolSizes
		};
		descriptorPool												= createDescriptorPool(vk, device, &poolParams);

		const VkDescriptorSetAllocateInfo		setAllocParams		=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// sType
			DE_NULL,												// pNext
			*descriptorPool,										// descriptorPool
			1u,														// descriptorSetCount
			&rawSetLayout,											// pSetLayouts
		};
		VK_CHECK(vk.allocateDescriptorSets(device, &setAllocParams, &rawSet));

		// Update descriptor set.
		vector<VkWriteDescriptorSet>			writeSpecs;
		vector<VkDescriptorBufferInfo>			dBufferInfos;
		vector<VkDescriptorImageInfo>			dImageInfos;

		writeSpecs.reserve(numResources);
		dBufferInfos.reserve(numResources);
		dImageInfos.reserve(numResources);

		deUint32								imgResourceNdx		= 0u;
		deUint32								bufResourceNdx		= 0u;

		for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
		{
			const Resource&	resource	= instance.resources.inputs[inputNdx];

			const bool		hasImage	= (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)	||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)	||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);

			const bool		hasSampler	= (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)	||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER)			||
										  (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);

			// Create image view and sampler
			if (hasImage || hasSampler)
			{
				if (resource.getDescriptorType() != VK_DESCRIPTOR_TYPE_SAMPLER)
				{
					const VkImageViewCreateInfo	imgViewParams	=
					{
						VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	//	VkStructureType				sType;
						DE_NULL,									//	const void*					pNext;
						0u,											//	VkImageViewCreateFlags		flags;
						**inResourceImages[imgResourceNdx++],		//	VkImage						image;
						VK_IMAGE_VIEW_TYPE_2D,						//	VkImageViewType				viewType;
						instance.resources.inputFormat,				//	VkFormat					format;
						{
							VK_COMPONENT_SWIZZLE_R,
							VK_COMPONENT_SWIZZLE_G,
							VK_COMPONENT_SWIZZLE_B,
							VK_COMPONENT_SWIZZLE_A
						},											//	VkComponentMapping			channels;
						{
							inputImageAspect,	//	VkImageAspectFlags	aspectMask;
							0u,					//	deUint32			baseMipLevel;
							1u,					//	deUint32			mipLevels;
							0u,					//	deUint32			baseArrayLayer;
							1u,					//	deUint32			arraySize;
						},											//	VkImageSubresourceRange		subresourceRange;
					};

					Move<VkImageView>			imgView			(createImageView(vk, device, &imgViewParams));
					inResourceImageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imgView)));
				}

				if (hasSampler)
				{
					const bool					hasDepthComponent	= tcu::hasDepthComponent(vk::mapVkFormat(instance.resources.inputFormat).order);
					const VkSamplerCreateInfo	samplerParams		=
					{
						VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType;
						DE_NULL,									// const void*				pNext;
						0,											// VkSamplerCreateFlags		flags;
						VK_FILTER_NEAREST,							// VkFilter					magFilter:
						VK_FILTER_NEAREST,							// VkFilter					minFilter;
						VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode;
						VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU;
						VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV;
						VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW;
						0.0f,										// float					mipLodBias;
						VK_FALSE,									// VkBool32					anistoropyÉnable;
						1.0f,										// float					maxAnisotropy;
						(hasDepthComponent) ? VK_TRUE : VK_FALSE,	// VkBool32					compareEnable;
						VK_COMPARE_OP_LESS,							// VkCompareOp				compareOp;
						0.0f,										// float					minLod;
						0.0f,										// float					maxLod;
						VK_BORDER_COLOR_INT_OPAQUE_BLACK,			// VkBorderColor			borderColor;
						VK_FALSE									// VkBool32					unnormalizedCoordinates;
					};

					Move<VkSampler>				sampler			(createSampler(vk, device, &samplerParams));
					inResourceSamplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
				}
			}

			// Create descriptor buffer and image infos
			switch (resource.getDescriptorType())
			{
				case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
				case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
				{
					const VkDescriptorBufferInfo	bufInfo	=
					{
						**inResourceBuffers[bufResourceNdx++],				// buffer
						0,													// offset
						VK_WHOLE_SIZE,										// size
					};
					dBufferInfos.push_back(bufInfo);
					break;
				}
				case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
				case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
				{
					const VkDescriptorImageInfo		imgInfo	=
					{
						DE_NULL,												// sampler
						**inResourceImageViews.back(),							// imageView
						VK_IMAGE_LAYOUT_GENERAL									// imageLayout
					};
					dImageInfos.push_back(imgInfo);
					break;
				}
				case VK_DESCRIPTOR_TYPE_SAMPLER:
				{
					const VkDescriptorImageInfo		imgInfo	=
					{
						**inResourceSamplers.back(),							// sampler
						DE_NULL,												// imageView
						VK_IMAGE_LAYOUT_GENERAL									// imageLayout
					};
					dImageInfos.push_back(imgInfo);
					break;
				}
				case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
				{

					const VkDescriptorImageInfo		imgInfo	=
					{
						**inResourceSamplers.back(),							// sampler
						**inResourceImageViews.back(),							// imageView
						VK_IMAGE_LAYOUT_GENERAL									// imageLayout
					};
					dImageInfos.push_back(imgInfo);
					break;
				}
				default:
					DE_FATAL("Not implemented");
			}

			const VkWriteDescriptorSet			writeSpec			= {
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,							// sType
				DE_NULL,														// pNext
				rawSet,															// dstSet
				inputNdx,														// binding
				0,																// dstArrayElement
				1u,																// descriptorCount
				instance.resources.inputs[inputNdx].getDescriptorType(),		// descriptorType
				( (hasImage | hasSampler)	? &dImageInfos.back()	: DE_NULL),	// pImageInfo
				(!(hasImage | hasSampler)	? &dBufferInfos.back()	: DE_NULL),	// pBufferInfo
				DE_NULL,														// pTexelBufferView
			};
			writeSpecs.push_back(writeSpec);
		}

		for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
		{
			const VkDescriptorBufferInfo		bufInfo				=
			{
				**outResourceBuffers[outputNdx],					// buffer
				0,													// offset
				VK_WHOLE_SIZE,										// size
			};
			dBufferInfos.push_back(bufInfo);

			const VkWriteDescriptorSet			writeSpec			= {
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,						// sType
				DE_NULL,													// pNext
				rawSet,														// dstSet
				numInResources + outputNdx,									// binding
				0,															// dstArrayElement
				1u,															// descriptorCount
				instance.resources.outputs[outputNdx].getDescriptorType(),	// descriptorType
				DE_NULL,													// pImageInfo
				&dBufferInfos.back(),										// pBufferInfo
				DE_NULL,													// pTexelBufferView
			};
			writeSpecs.push_back(writeSpec);
		}
		vk.updateDescriptorSets(device, numResources, writeSpecs.data(), 0, DE_NULL);
	}

	// Pipeline layout
	VkPipelineLayoutCreateInfo				pipelineLayoutParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			//	VkStructureType					sType;
		DE_NULL,												//	const void*						pNext;
		(VkPipelineLayoutCreateFlags)0,
		0u,														//	deUint32						descriptorSetCount;
		DE_NULL,												//	const VkDescriptorSetLayout*	pSetLayouts;
		0u,														//	deUint32						pushConstantRangeCount;
		DE_NULL,												//	const VkPushConstantRange*		pPushConstantRanges;
	};

	VkPushConstantRange						pushConstantRange		=
	{
		VK_SHADER_STAGE_ALL_GRAPHICS,							// VkShaderStageFlags    stageFlags;
		0,														// uint32_t              offset;
		0,														// uint32_t              size;
	};
	if (hasPushConstants)
	{
		vector<deUint8> pushConstantsBytes;
		instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);

		pushConstantRange.size						= static_cast<deUint32>(pushConstantsBytes.size());
		pipelineLayoutParams.pushConstantRangeCount	= 1;
		pipelineLayoutParams.pPushConstantRanges	= &pushConstantRange;
	}
	if (numResources != 0)
	{
		// Update pipeline layout with the descriptor set layout.
		pipelineLayoutParams.setLayoutCount								= 1;
		pipelineLayoutParams.pSetLayouts								= &rawSetLayout;
	}
	const Unique<VkPipelineLayout>			pipelineLayout			(createPipelineLayout(vk, device, &pipelineLayoutParams));

	// Pipeline
	vector<VkPipelineShaderStageCreateInfo>		shaderStageParams;
	// We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
	vector<vector<VkSpecializationMapEntry> >	specConstantEntries;
	vector<VkSpecializationInfo>				specializationInfos;
	if (DE_NULL != instance.resources.verifyBinary)
	{
		std::string shaderName;
		switch(instance.customizedStages)
		{
		case	VK_SHADER_STAGE_VERTEX_BIT:
			shaderName= "vert";
			break;
		case	VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
			shaderName= "tessc";
			break;
		case	VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
			shaderName= "tesse";
			break;
		case	VK_SHADER_STAGE_GEOMETRY_BIT:
			shaderName= "geom";
			break;
		case	VK_SHADER_STAGE_FRAGMENT_BIT:
			shaderName= "frag";
			break;
		default:
			DE_ASSERT(0);
			break;
		}
		const ProgramBinary& binary  = context.getBinaryCollection().get(shaderName);
		if (!instance.resources.verifyBinary(binary))
			return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");

	}
	createPipelineShaderStages(vk, device, instance, context, modules, shaderStageParams);

	// And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
	specConstantEntries.reserve(shaderStageParams.size());
	specializationInfos.reserve(shaderStageParams.size());

	// Patch the specialization info field in PipelineShaderStageCreateInfos.
	for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
	{
		const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);

		if (stageIt != instance.specConstants.end())
		{
			const size_t						numSpecConstants	= stageIt->second.getValuesCount();
			vector<VkSpecializationMapEntry>	entries;
			VkSpecializationInfo				specInfo;
			size_t								offset				= 0;

			entries.resize(numSpecConstants);

			// Constant IDs are numbered sequentially starting from 0.
			for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
			{
				const size_t valueSize	= stageIt->second.getValueSize(ndx);

				entries[ndx].constantID	= (deUint32)ndx;
				entries[ndx].offset		= static_cast<deUint32>(offset);
				entries[ndx].size		= valueSize;

				offset					+= valueSize;
			}

			specConstantEntries.push_back(entries);

			specInfo.mapEntryCount	= (deUint32)numSpecConstants;
			specInfo.pMapEntries	= specConstantEntries.back().data();
			specInfo.dataSize		= offset;
			specInfo.pData			= stageIt->second.getValuesBuffer();
			specializationInfos.push_back(specInfo);

			stageInfo->pSpecializationInfo = &specializationInfos.back();
		}
	}
	const VkPipelineDepthStencilStateCreateInfo	depthStencilParams		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	//	VkStructureType		sType;
		DE_NULL,													//	const void*			pNext;
		(VkPipelineDepthStencilStateCreateFlags)0,
		DE_FALSE,													//	deUint32			depthTestEnable;
		DE_FALSE,													//	deUint32			depthWriteEnable;
		VK_COMPARE_OP_ALWAYS,										//	VkCompareOp			depthCompareOp;
		DE_FALSE,													//	deUint32			depthBoundsTestEnable;
		DE_FALSE,													//	deUint32			stencilTestEnable;
		{
			VK_STENCIL_OP_KEEP,											//	VkStencilOp	stencilFailOp;
			VK_STENCIL_OP_KEEP,											//	VkStencilOp	stencilPassOp;
			VK_STENCIL_OP_KEEP,											//	VkStencilOp	stencilDepthFailOp;
			VK_COMPARE_OP_ALWAYS,										//	VkCompareOp	stencilCompareOp;
			0u,															//	deUint32	stencilCompareMask;
			0u,															//	deUint32	stencilWriteMask;
			0u,															//	deUint32	stencilReference;
		},															//	VkStencilOpState	front;
		{
			VK_STENCIL_OP_KEEP,											//	VkStencilOp	stencilFailOp;
			VK_STENCIL_OP_KEEP,											//	VkStencilOp	stencilPassOp;
			VK_STENCIL_OP_KEEP,											//	VkStencilOp	stencilDepthFailOp;
			VK_COMPARE_OP_ALWAYS,										//	VkCompareOp	stencilCompareOp;
			0u,															//	deUint32	stencilCompareMask;
			0u,															//	deUint32	stencilWriteMask;
			0u,															//	deUint32	stencilReference;
		},															//	VkStencilOpState	back;
		-1.0f,														//	float				minDepthBounds;
		+1.0f,														//	float				maxDepthBounds;
	};
	const VkViewport							viewport0				= makeViewport(renderSize);
	const VkRect2D								scissor0				= makeRect2D(0u, 0u);
	const VkPipelineViewportStateCreateInfo		viewportParams			=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,		//	VkStructureType		sType;
		DE_NULL,													//	const void*			pNext;
		(VkPipelineViewportStateCreateFlags)0,
		1u,															//	deUint32			viewportCount;
		&viewport0,
		1u,
		&scissor0
	};
	const VkSampleMask							sampleMask				= ~0u;
	const VkPipelineMultisampleStateCreateInfo	multisampleParams		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	//	VkStructureType			sType;
		DE_NULL,													//	const void*				pNext;
		(VkPipelineMultisampleStateCreateFlags)0,
		VK_SAMPLE_COUNT_1_BIT,										//	VkSampleCountFlagBits	rasterSamples;
		DE_FALSE,													//	deUint32				sampleShadingEnable;
		0.0f,														//	float					minSampleShading;
		&sampleMask,												//	const VkSampleMask*		pSampleMask;
		DE_FALSE,													//	VkBool32				alphaToCoverageEnable;
		DE_FALSE,													//	VkBool32				alphaToOneEnable;
	};
	const VkPipelineRasterizationStateCreateInfo	rasterParams		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType	sType;
		DE_NULL,													//	const void*		pNext;
		(VkPipelineRasterizationStateCreateFlags)0,
		DE_FALSE,													//	deUint32		depthClampEnable;
		DE_FALSE,													//	deUint32		rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,										//	VkFillMode		fillMode;
		VK_CULL_MODE_NONE,											//	VkCullMode		cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,							//	VkFrontFace		frontFace;
		VK_FALSE,													//	VkBool32		depthBiasEnable;
		0.0f,														//	float			depthBias;
		0.0f,														//	float			depthBiasClamp;
		0.0f,														//	float			slopeScaledDepthBias;
		1.0f,														//	float			lineWidth;
	};
	const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	//	VkStructureType		sType;
		DE_NULL,														//	const void*			pNext;
		(VkPipelineInputAssemblyStateCreateFlags)0,
		topology,														//	VkPrimitiveTopology	topology;
		DE_FALSE,														//	deUint32			primitiveRestartEnable;
	};

	vector<VkVertexInputBindingDescription>		vertexBindings;
	vector<VkVertexInputAttributeDescription>	vertexAttribs;

	const VkVertexInputBindingDescription		vertexBinding0			=
	{
		0u,									// deUint32					binding;
		deUint32(singleVertexDataSize),		// deUint32					strideInBytes;
		VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	stepRate;
	};
	vertexBindings.push_back(vertexBinding0);

	{
		VkVertexInputAttributeDescription		attr0					=
		{
			0u,									// deUint32	location;
			0u,									// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
			0u									// deUint32	offsetInBytes;
		};
		vertexAttribs.push_back(attr0);

		VkVertexInputAttributeDescription		attr1					=
		{
			1u,									// deUint32	location;
			0u,									// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
			sizeof(Vec4),						// deUint32	offsetInBytes;
		};
		vertexAttribs.push_back(attr1);
	};

	// If the test instantiation has additional input/output interface variables, we need to create additional bindings.
	// Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
	// with location #2.
	if (needInterface)
	{
		const VkVertexInputBindingDescription	vertexBinding1			=
		{
			1u,													// deUint32					binding;
			instance.interfaces.getInputType().getNumBytes(),	// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX							// VkVertexInputStepRate	stepRate;
		};
		vertexBindings.push_back(vertexBinding1);

		VkVertexInputAttributeDescription		attr					=
		{
			2u,													// deUint32	location;
			1u,													// deUint32	binding;
			instance.interfaces.getInputType().getVkFormat(),	// VkFormat	format;
			0,													// deUint32	offsetInBytes;
		};
		vertexAttribs.push_back(attr);
	}

	VkPipelineVertexInputStateCreateInfo		vertexInputStateParams	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	VkStructureType								sType;
		DE_NULL,													//	const void*									pNext;
		(VkPipelineVertexInputStateCreateFlags)0,
		1u,															//	deUint32									bindingCount;
		vertexBindings.data(),										//	const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
		2u,															//	deUint32									attributeCount;
		vertexAttribs.data(),										//	const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	if (needInterface)
	{
		vertexInputStateParams.vertexBindingDescriptionCount += 1;
		vertexInputStateParams.vertexAttributeDescriptionCount += 1;
	}

	vector<VkPipelineColorBlendAttachmentState>	attBlendStates;
	const VkPipelineColorBlendAttachmentState	attBlendState			=
	{
		DE_FALSE,													//	deUint32		blendEnable;
		VK_BLEND_FACTOR_ONE,										//	VkBlend			srcBlendColor;
		VK_BLEND_FACTOR_ZERO,										//	VkBlend			destBlendColor;
		VK_BLEND_OP_ADD,											//	VkBlendOp		blendOpColor;
		VK_BLEND_FACTOR_ONE,										//	VkBlend			srcBlendAlpha;
		VK_BLEND_FACTOR_ZERO,										//	VkBlend			destBlendAlpha;
		VK_BLEND_OP_ADD,											//	VkBlendOp		blendOpAlpha;
		(VK_COLOR_COMPONENT_R_BIT|
		 VK_COLOR_COMPONENT_G_BIT|
		 VK_COLOR_COMPONENT_B_BIT|
		 VK_COLOR_COMPONENT_A_BIT),									//	VkChannelFlags	channelWriteMask;
	};
	attBlendStates.push_back(attBlendState);

	if (needInterface)
		attBlendStates.push_back(attBlendState);

	VkPipelineColorBlendStateCreateInfo		blendParams				=
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	//	VkStructureType								sType;
		DE_NULL,													//	const void*									pNext;
		(VkPipelineColorBlendStateCreateFlags)0,
		DE_FALSE,													//	VkBool32									logicOpEnable;
		VK_LOGIC_OP_COPY,											//	VkLogicOp									logicOp;
		1u,															//	deUint32									attachmentCount;
		attBlendStates.data(),										//	const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									//	float										blendConst[4];
	};
	if (needInterface)
	{
		blendParams.attachmentCount += 1;
	}
	const VkPipelineTessellationStateCreateInfo	tessellationState	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineTessellationStateCreateFlags)0,
		3u
	};

	const	VkDynamicState							dynamicStates[]				=
	{
		VK_DYNAMIC_STATE_SCISSOR
	};

	const VkPipelineDynamicStateCreateInfo			dynamicStateCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,  // sType
		DE_NULL,											   // pNext
		0u,													   // flags
		DE_LENGTH_OF_ARRAY(dynamicStates),					   // dynamicStateCount
		dynamicStates										   // pDynamicStates
	};

	const VkPipelineTessellationStateCreateInfo* tessellationInfo	=	hasTessellation ? &tessellationState: DE_NULL;
	const VkGraphicsPipelineCreateInfo		pipelineParams			=
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,		//	VkStructureType									sType;
		DE_NULL,												//	const void*										pNext;
		0u,														//	VkPipelineCreateFlags							flags;
		(deUint32)shaderStageParams.size(),						//	deUint32										stageCount;
		&shaderStageParams[0],									//	const VkPipelineShaderStageCreateInfo*			pStages;
		&vertexInputStateParams,								//	const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
		&inputAssemblyParams,									//	const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
		tessellationInfo,										//	const VkPipelineTessellationStateCreateInfo*	pTessellationState;
		&viewportParams,										//	const VkPipelineViewportStateCreateInfo*		pViewportState;
		&rasterParams,											//	const VkPipelineRasterStateCreateInfo*			pRasterState;
		&multisampleParams,										//	const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
		&depthStencilParams,									//	const VkPipelineDepthStencilStateCreateInfo*	pDepthStencilState;
		&blendParams,											//	const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
		&dynamicStateCreateInfo,								//	const VkPipelineDynamicStateCreateInfo*			pDynamicState;
		*pipelineLayout,										//	VkPipelineLayout								layout;
		*renderPass,											//	VkRenderPass									renderPass;
		0u,														//	deUint32										subpass;
		DE_NULL,												//	VkPipeline										basePipelineHandle;
		0u,														//	deInt32											basePipelineIndex;
	};

	const Unique<VkPipeline>				pipeline				(createGraphicsPipeline(vk, device, DE_NULL, &pipelineParams));

	if (needInterface)
	{
		const VkImageViewCreateInfo			fragOutputViewParams	=
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			//	VkStructureType				sType;
			DE_NULL,											//	const void*					pNext;
			0u,													//	VkImageViewCreateFlags		flags;
			*fragOutputImage,									//	VkImage						image;
			VK_IMAGE_VIEW_TYPE_2D,								//	VkImageViewType				viewType;
			instance.interfaces.getOutputType().getVkFormat(),	//	VkFormat					format;
			{
				VK_COMPONENT_SWIZZLE_R,
				VK_COMPONENT_SWIZZLE_G,
				VK_COMPONENT_SWIZZLE_B,
				VK_COMPONENT_SWIZZLE_A
			},													//	VkChannelMapping			channels;
			{
				VK_IMAGE_ASPECT_COLOR_BIT,						//	VkImageAspectFlags	aspectMask;
				0u,												//	deUint32			baseMipLevel;
				1u,												//	deUint32			mipLevels;
				0u,												//	deUint32			baseArrayLayer;
				1u,												//	deUint32			arraySize;
			},													//	VkImageSubresourceRange		subresourceRange;
		};
		fragOutputImageView = createImageView(vk, device, &fragOutputViewParams);
		attViews.push_back(*fragOutputImageView);
	}

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

	if (needInterface)
		framebufferParams.attachmentCount += 1;

	const Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, device, &framebufferParams));

	bool firstPass = true;

	for (int x = 0; x < numRenderSegments; x++)
	{
		for (int y = 0; y < numRenderSegments; y++)
		{
			// Record commands
			beginCommandBuffer(vk, *cmdBuf);

			{
				const VkMemoryBarrier			vertFlushBarrier	=
				{
					VK_STRUCTURE_TYPE_MEMORY_BARRIER,			//	VkStructureType		sType;
					DE_NULL,									//	const void*			pNext;
					VK_ACCESS_HOST_WRITE_BIT,					//	VkMemoryOutputFlags	outputMask;
					VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,		//	VkMemoryInputFlags	inputMask;
				};
				vector<VkImageMemoryBarrier>	colorAttBarriers;

				VkImageMemoryBarrier			imgBarrier          =
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		//	VkStructureType			sType;
					DE_NULL,									//	const void*				pNext;
					0u,											//	VkMemoryOutputFlags		outputMask;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		//	VkMemoryInputFlags		inputMask;
					VK_IMAGE_LAYOUT_UNDEFINED,					//	VkImageLayout			oldLayout;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout			newLayout;
					queueFamilyIndex,							//	deUint32				srcQueueFamilyIndex;
					queueFamilyIndex,							//	deUint32				destQueueFamilyIndex;
					*image,										//	VkImage					image;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,					//	VkImageAspect	aspect;
						0u,											//	deUint32		baseMipLevel;
						1u,											//	deUint32		mipLevels;
						0u,											//	deUint32		baseArraySlice;
						1u,											//	deUint32		arraySize;
					}											//	VkImageSubresourceRange	subresourceRange;
				};
				colorAttBarriers.push_back(imgBarrier);
				if (needInterface)
				{
					imgBarrier.image = *fragOutputImage;
					colorAttBarriers.push_back(imgBarrier);
					vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, colorAttBarriers.data());
				}
				else
				{
					vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, colorAttBarriers.data());
				}
			}

			{
				vector<VkClearValue>			clearValue;
				clearValue.push_back(makeClearValueColorF32(defaulClearColor[0], defaulClearColor[1], defaulClearColor[2], defaulClearColor[3]));
				if (needInterface)
				{
					clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
				}


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

				beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, scissor, (deUint32)clearValue.size(), clearValue.data());
			}

			vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
			{
				const VkDeviceSize bindingOffset = 0;
				vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
			}
			if (needInterface)
			{
				const VkDeviceSize bindingOffset = 0;
				vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
			}
			if (hasPushConstants)
			{
				vector<deUint8> pushConstantsBytes;
				instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);

				const deUint32	size	= static_cast<deUint32>(pushConstantsBytes.size());
				const void*		data	= &pushConstantsBytes.front();

				vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
			}
			if (numResources != 0)
			{
				// Bind to set number 0.
				vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
			}
			vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
			endRenderPass(vk, *cmdBuf);

			{
				vector<VkImageMemoryBarrier>	renderFinishBarrier;
				VkImageMemoryBarrier			imgBarrier				=
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		//	VkStructureType			sType;
					DE_NULL,									//	const void*				pNext;
					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		//	VkMemoryOutputFlags		outputMask;
					VK_ACCESS_TRANSFER_READ_BIT,				//	VkMemoryInputFlags		inputMask;
					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout			oldLayout;
					VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		//	VkImageLayout			newLayout;
					queueFamilyIndex,							//	deUint32				srcQueueFamilyIndex;
					queueFamilyIndex,							//	deUint32				destQueueFamilyIndex;
					*image,										//	VkImage					image;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,					//	VkImageAspectFlags	aspectMask;
						0u,											//	deUint32			baseMipLevel;
						1u,											//	deUint32			mipLevels;
						0u,											//	deUint32			baseArraySlice;
						1u,											//	deUint32			arraySize;
					}											//	VkImageSubresourceRange	subresourceRange;
				};
				renderFinishBarrier.push_back(imgBarrier);

				if (needInterface)
				{
					imgBarrier.image = *fragOutputImage;
					renderFinishBarrier.push_back(imgBarrier);
					vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, renderFinishBarrier.data());
				}
				else
				{
					vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, renderFinishBarrier.data());
				}
			}

			if ( x ==  numRenderSegments -1 && y == numRenderSegments - 1)
			{
				{
					const VkBufferImageCopy	copyParams	=
					{
						(VkDeviceSize)0u,						//	VkDeviceSize			bufferOffset;
						(deUint32)renderSize.x(),				//	deUint32				bufferRowLength;
						(deUint32)renderSize.y(),				//	deUint32				bufferImageHeight;
						{
							VK_IMAGE_ASPECT_COLOR_BIT,				//	VkImageAspect		aspect;
							0u,										//	deUint32			mipLevel;
							0u,										//	deUint32			arrayLayer;
							1u,										//	deUint32			arraySize;
						},										//	VkImageSubresourceCopy	imageSubresource;
						{ 0u, 0u, 0u },							//	VkOffset3D				imageOffset;
						{ renderSize.x(), renderSize.y(), 1u }
					};
					vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, &copyParams);

					if (needInterface)
					{
					vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, &copyParams);
					}
				}

				{
					vector<VkBufferMemoryBarrier>	cpFinishBarriers;
					VkBufferMemoryBarrier			copyFinishBarrier	=
					{
						VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//	VkStructureType		sType;
						DE_NULL,									//	const void*			pNext;
						VK_ACCESS_TRANSFER_WRITE_BIT,				//	VkMemoryOutputFlags	outputMask;
						VK_ACCESS_HOST_READ_BIT,					//	VkMemoryInputFlags	inputMask;
						queueFamilyIndex,							//	deUint32			srcQueueFamilyIndex;
						queueFamilyIndex,							//	deUint32			destQueueFamilyIndex;
						*readImageBuffer,							//	VkBuffer			buffer;
						0u,											//	VkDeviceSize		offset;
						imageSizeBytes								//	VkDeviceSize		size;
					};
					cpFinishBarriers.push_back(copyFinishBarrier);

					if (needInterface)
					{
						copyFinishBarrier.buffer	= *fragOutputBuffer;
						copyFinishBarrier.size		= VK_WHOLE_SIZE;
						cpFinishBarriers.push_back(copyFinishBarrier);

						vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 2, cpFinishBarriers.data(), 0, (const VkImageMemoryBarrier*)DE_NULL);
					}
					else
					{
						vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, cpFinishBarriers.data(), 0, (const VkImageMemoryBarrier*)DE_NULL);
					}
				}
				}

			endCommandBuffer(vk, *cmdBuf);

			if (firstPass)
			{
				// Upload vertex data
				{
					void* vertexBufPtr = vertexBufferMemory->getHostPtr();
					deMemcpy(vertexBufPtr, &vertexData[0], vertexDataSize);
					flushAlloc(vk, device, *vertexBufferMemory);
				}

				if (needInterface)
				{
					vector<deUint8> inputBufferBytes;
					instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);

					const deUint32				typNumBytes		= instance.interfaces.getInputType().getNumBytes();
					const deUint32				bufNumBytes		= static_cast<deUint32>(inputBufferBytes.size());

					// Require that the test instantation provides four output values.
					DE_ASSERT(bufNumBytes == 4 * typNumBytes);

					// We have four triangles. Because interpolation happens before executing the fragment shader,
					// we need to provide the same vertex attribute for the same triangle. That means, duplicate each
					// value three times for all four values.

					const deUint8*				provided		= static_cast<const deUint8*>(&inputBufferBytes.front());
					vector<deUint8>				data;

					data.reserve(3 * bufNumBytes);

					for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
						for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
							for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
								data.push_back(provided[offset + byteNdx]);

					deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());

					const VkMappedMemoryRange	range			=
					{
						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	//	VkStructureType	sType;
						DE_NULL,								//	const void*		pNext;
						vertexInputMemory->getMemory(),			//	VkDeviceMemory	mem;
						0,										//	VkDeviceSize	offset;
						VK_WHOLE_SIZE,							//	VkDeviceSize	size;
					};

					VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
				}
				firstPass = false;
			}

			// Submit & wait for completion
			submitCommandsAndWait(vk, device, queue, cmdBuf.get());
		}
	}

	const void* imagePtr	= readImageBufferMemory->getHostPtr();
	const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
												  renderSize.x(), renderSize.y(), 1, imagePtr);
	// Log image
	invalidateAlloc(vk, device, *readImageBufferMemory);
	context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);

	if (needInterface)
	{
		const VkDeviceSize			fragOutputImgSize	= (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
		const VkMappedMemoryRange	range				=
		{
			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	//	VkStructureType	sType;
			DE_NULL,								//	const void*		pNext;
			fragOutputMemory->getMemory(),			//	VkDeviceMemory	mem;
			0,										//	VkDeviceSize	offset;
			fragOutputImgSize,						//	VkDeviceSize	size;
		};

		VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
	}

	{ // Make sure all output resources are ready.
		for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
		{
			const VkMappedMemoryRange	range	=
			{
				VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,			//	VkStructureType	sType;
				DE_NULL,										//	const void*		pNext;
				outResourceMemories[outputNdx]->getMemory(),	//	VkDeviceMemory	mem;
				0,												//	VkDeviceSize	offset;
				VK_WHOLE_SIZE,									//	VkDeviceSize	size;
			};

			VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
		}
	}

	const RGBA threshold(1, 1, 1, 1);

	const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
	if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
		return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));

	const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
	if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
		return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));

	const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
	if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
		return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));

	const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
	if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
		return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));

	// Check that the contents in the ouput variable matches expected.
	if (needInterface)
	{
		vector<deUint8>						inputBufferBytes;
		vector<deUint8>						outputBufferBytes;

		instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
		instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes);

		const IFDataType&					inputType				= instance.interfaces.getInputType();
		const IFDataType&					outputType				= instance.interfaces.getOutputType();
		const void*							inputData				= &inputBufferBytes.front();
		const void*							outputData				= &outputBufferBytes.front();
		vector<std::pair<int, int> >		positions;
		const tcu::ConstPixelBufferAccess	fragOutputBufferAccess	(outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());

		positions.push_back(std::make_pair(1, 1));
		positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
		positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
		positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));

		for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
		{
			const int	x		= positions[posNdx].first;
			const int	y		= positions[posNdx].second;
			bool		equal	= true;

			if (outputType.elementType == NUMBERTYPE_FLOAT32)
			{
				const float*		expected	= static_cast<const float*>(outputData) + posNdx * outputType.numElements;
				const float*		actual		= static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
						equal = false;
			}
			else if (outputType.elementType == NUMBERTYPE_INT32)
			{
				const deInt32*		expected	= static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
				const deInt32*		actual		= static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (expected[eleNdx] != actual[eleNdx])
						equal = false;
			}
			else if (outputType.elementType == NUMBERTYPE_UINT32)
			{
				const deUint32*		expected	= static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
				const deUint32*		actual		= static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (expected[eleNdx] != actual[eleNdx])
						equal = false;
			}
			else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType == NUMBERTYPE_FLOAT64)
			{
				const double*		original	= static_cast<const double*>(inputData) + posNdx * outputType.numElements;
				const deFloat16*	actual		= static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (!compare16BitFloat64(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
						equal = false;
			}
			else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType != NUMBERTYPE_FLOAT64)
			{
				if (inputType.elementType == NUMBERTYPE_FLOAT16)
				{
					const deFloat16*	original	= static_cast<const deFloat16*>(inputData) + posNdx * outputType.numElements;
					const deFloat16*	actual		= static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));

					for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
						if (!compare16BitFloat(original[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
							equal = false;
				}
				else
				{
					const float*		original	= static_cast<const float*>(inputData) + posNdx * outputType.numElements;
					const deFloat16*	actual		= static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));

					for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
						if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
							equal = false;
				}
			}
			else if (outputType.elementType == NUMBERTYPE_INT16)
			{
				const deInt16*		expected	= static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
				const deInt16*		actual		= static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (expected[eleNdx] != actual[eleNdx])
						equal = false;
			}
			else if (outputType.elementType == NUMBERTYPE_UINT16)
			{
				const deUint16*		expected	= static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
				const deUint16*		actual		= static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (expected[eleNdx] != actual[eleNdx])
						equal = false;
			}
			else if (outputType.elementType == NUMBERTYPE_FLOAT64)
			{
				const double*		expected	= static_cast<const double*>(outputData) + posNdx * outputType.numElements;
				const double*		actual		= static_cast<const double*>(fragOutputBufferAccess.getPixelPtr(x, y));

				for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
					if (!compare64BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
						equal = false;
			}
			else {
				DE_ASSERT(0 && "unhandled type");
			}

			if (!equal)
				return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
		}
	}

	// Check the contents in output resources match with expected.
	for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
	{
		const BufferSp& expected = instance.resources.outputs[outputNdx].getBuffer();

		if (instance.resources.verifyIO != DE_NULL)
		{
			if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
				return tcu::TestStatus::fail("Resource returned doesn't match with expected");
		}
		else
		{
			vector<deUint8> expectedBytes;
			expected->getBytes(expectedBytes);

			if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
			{
				// Some *variable_pointers* tests store counters in buffer
				// whose value may vary if the same vertex shader may be executed for multiple times
				// in this case the output value can be expected value + non-negative integer N
				if (instance.customizedStages == VK_SHADER_STAGE_VERTEX_BIT)
				{
					const size_t	numExpectedEntries	= expectedBytes.size() / sizeof(float);
					const float*	expectedFloats		= reinterpret_cast<const float*>(&expectedBytes.front());
					const float*	outputFloats		= reinterpret_cast<const float*>(outResourceMemories[outputNdx]->getHostPtr());
					float			diff				= 0.0f;

					for (size_t expectedNdx = 0; expectedNdx < numExpectedEntries; ++expectedNdx)
					{
						if (deFloatIsInf(outputFloats[expectedNdx]) || deFloatIsNaN(outputFloats[expectedNdx]))
							return tcu::TestStatus::fail("Value returned is invalid");

						diff = outputFloats[expectedNdx] - expectedFloats[expectedNdx];

						if ((diff < 0.0f) || (deFloatFloor(diff) != diff))
							return tcu::TestStatus::fail("Value returned should be equal to expected value plus non-negative integer");
					}
				}
				else
				{
					return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
				}
			}

		}
	}

	return TestStatus::pass("Rendered output matches input");
}

const vector<ShaderElement>& getVertFragPipelineStages (void)
{
	static vector<ShaderElement> vertFragPipelineStages;
	if(vertFragPipelineStages.empty())
	{
		vertFragPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
		vertFragPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
	};
	return vertFragPipelineStages;
}

const vector<ShaderElement>& getTessPipelineStages (void)
{
	static vector<ShaderElement> tessPipelineStages;
	if(tessPipelineStages.empty())
	{
		tessPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
		tessPipelineStages.push_back(ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
		tessPipelineStages.push_back(ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
		tessPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
	};
	return tessPipelineStages;
}

const vector<ShaderElement>& getGeomPipelineStages (void)
{
	static vector<ShaderElement> geomPipelineStages;
	if(geomPipelineStages.empty())
	{
		geomPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
		geomPipelineStages.push_back(ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT));
		geomPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
	};
	return geomPipelineStages;
}

// Helper structure used by addTestForStage function.
struct StageData
{
	typedef const vector<ShaderElement>& (*GetPipelineStagesFn)();
	typedef void (*AddShaderCodeCustomStageFn)(vk::SourceCollections&, InstanceContext);

	GetPipelineStagesFn			getPipelineFn;
	AddShaderCodeCustomStageFn	initProgramsFn;

	StageData()
		: getPipelineFn(DE_NULL)
		, initProgramsFn(DE_NULL)
	{
	}

	StageData(GetPipelineStagesFn pipelineGetter, AddShaderCodeCustomStageFn programsInitializer)
		: getPipelineFn(pipelineGetter)
		, initProgramsFn(programsInitializer)
	{
	}
};

// Helper function used by addTestForStage function.
const StageData& getStageData (vk::VkShaderStageFlagBits stage)
{
	// Construct map
	static map<vk::VkShaderStageFlagBits, StageData> testedStageData;
	if(testedStageData.empty())
	{
		testedStageData[VK_SHADER_STAGE_VERTEX_BIT]					 = StageData(getVertFragPipelineStages, addShaderCodeCustomVertex);
		testedStageData[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]	 = StageData(getTessPipelineStages, addShaderCodeCustomTessControl);
		testedStageData[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessEval);
		testedStageData[VK_SHADER_STAGE_GEOMETRY_BIT]				 = StageData(getGeomPipelineStages, addShaderCodeCustomGeometry);
		testedStageData[VK_SHADER_STAGE_FRAGMENT_BIT]				 = StageData(getVertFragPipelineStages, addShaderCodeCustomFragment);
	}

	return testedStageData[stage];
}

void createTestForStage (vk::VkShaderStageFlagBits	stage,
						 const std::string&			name,
						 const RGBA					(&inputColors)[4],
						 const RGBA					(&outputColors)[4],
						 const map<string, string>&	testCodeFragments,
						 const SpecConstants&		specConstants,
						 const PushConstants&		pushConstants,
						 const GraphicsResources&	resources,
						 const GraphicsInterfaces&	interfaces,
						 const vector<string>&		extensions,
						 VulkanFeatures				vulkanFeatures,
						 tcu::TestCaseGroup*		tests,
						 const qpTestResult			failResult,
						 const string&				failMessageTemplate,
						 const bool					renderFullSquare,
						 const bool					splitRenderArea)
{
	const StageData&				stageData			= getStageData(stage);
	DE_ASSERT(stageData.getPipelineFn || stageData.initProgramsFn);
	const vector<ShaderElement>&	pipeline			= stageData.getPipelineFn();

	StageToSpecConstantMap			specConstantMap;
	if (!specConstants.empty())
		specConstantMap[stage] = specConstants;

	InstanceContext					ctx					(inputColors, outputColors, testCodeFragments, specConstantMap, pushConstants, resources, interfaces, extensions, vulkanFeatures, stage);
	ctx.splitRenderArea = splitRenderArea;
	for (size_t i = 0; i < pipeline.size(); ++i)
	{
		ctx.moduleMap[pipeline[i].moduleName].push_back(std::make_pair(pipeline[i].entryName, pipeline[i].stage));
		ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | pipeline[i].stage);
	}

	ctx.failResult = failResult;
	if (!failMessageTemplate.empty())
		ctx.failMessageTemplate = failMessageTemplate;

	ctx.renderFullSquare = renderFullSquare;
	ctx.splitRenderArea	= splitRenderArea;
	addFunctionCaseWithPrograms<InstanceContext>(tests, name, "", stageData.initProgramsFn, runAndVerifyDefaultPipeline, ctx);
}

void createTestsForAllStages (const std::string&			name,
							  const RGBA					(&inputColors)[4],
							  const RGBA					(&outputColors)[4],
							  const map<string, string>&	testCodeFragments,
							  const SpecConstants&			specConstants,
							  const PushConstants&			pushConstants,
							  const GraphicsResources&		resources,
							  const GraphicsInterfaces&		interfaces,
							  const vector<string>&			extensions,
							  VulkanFeatures				vulkanFeatures,
							  tcu::TestCaseGroup*			tests,
							  const qpTestResult			failResult,
							  const string&					failMessageTemplate,
							  const bool					splitRenderArea)
{
	createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, name + "_vert",
					   inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
					   interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);

	createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name + "_tessc",
					   inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
					   interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);

	createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, name + "_tesse",
					   inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
					   interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);

	createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, name + "_geom",
					   inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
					   interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);

	createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, name + "_frag",
					   inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
					   interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate, false, splitRenderArea);
}

void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
{
	RGBA defaultColors[4];
	getDefaultColors(defaultColors);

	createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name,
					   defaultColors, defaultColors, fragments, SpecConstants(), PushConstants(), GraphicsResources(),
					   GraphicsInterfaces(), vector<string>(), VulkanFeatures(), group);
}

} // SpirVAssembly
} // vkt
