/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2021 The Khronos Group Inc.
 * Copyright (c) 2021 Valve Corporation.
 *
 * 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 Mesh Shader Misc Tests
 *//*--------------------------------------------------------------------*/

#include "vktMeshShaderMiscTests.hpp"
#include "vktTestCase.hpp"

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

#include "tcuImageCompare.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuMaybe.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTestLog.hpp"

#include <memory>
#include <utility>
#include <vector>
#include <string>
#include <sstream>
#include <map>

namespace vkt
{
namespace MeshShader
{

namespace
{

using GroupPtr = de::MovePtr<tcu::TestCaseGroup>;

using namespace vk;

// Output images will use this format.
VkFormat getOutputFormat ()
{
	return VK_FORMAT_R8G8B8A8_UNORM;
}

// Threshold that's reasonable for the previous format.
float getCompareThreshold ()
{
	return 0.005f; // 1/256 < 0.005 < 2/256
}

// Check mesh shader support.
void genericCheckSupport (Context& context, bool requireTaskShader, bool requireVertexStores)
{
	context.requireDeviceFunctionality("VK_NV_mesh_shader");

	const auto& meshFeatures = context.getMeshShaderFeatures();

	if (!meshFeatures.meshShader)
		TCU_THROW(NotSupportedError, "Mesh shader not supported");

	if (requireTaskShader && !meshFeatures.taskShader)
		TCU_THROW(NotSupportedError, "Task shader not supported");

	if (requireVertexStores)
	{
		const auto& features = context.getDeviceFeatures();
		if (!features.vertexPipelineStoresAndAtomics)
			TCU_THROW(NotSupportedError, "Vertex pieline stores and atomics not supported");
	}
}

struct MiscTestParams
{
	tcu::Maybe<uint32_t>	taskCount;
	uint32_t				meshCount;

	uint32_t				width;
	uint32_t				height;

	// Makes the class polymorphic and allows the right destructor to be used for subclasses.
	virtual ~MiscTestParams () {}

	bool needsTaskShader () const
	{
		return static_cast<bool>(taskCount);
	}

	uint32_t drawCount () const
	{
		if (needsTaskShader())
			return taskCount.get();
		return meshCount;
	}
};

using ParamsPtr = std::unique_ptr<MiscTestParams>;

class MeshShaderMiscCase : public vkt::TestCase
{
public:
					MeshShaderMiscCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params);
	virtual			~MeshShaderMiscCase		(void) {}

	void			checkSupport			(Context& context) const override;
	void			initPrograms			(vk::SourceCollections& programCollection) const override;

protected:
	std::unique_ptr<MiscTestParams> m_params;
};

MeshShaderMiscCase::MeshShaderMiscCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
	: vkt::TestCase	(testCtx, name, description)
	, m_params		(params.release())
{}

void MeshShaderMiscCase::checkSupport (Context& context) const
{
	genericCheckSupport(context, m_params->needsTaskShader(), /*requireVertexStores*/false);
}

// Adds the generic fragment shader. To be called by subclasses.
void MeshShaderMiscCase::initPrograms (vk::SourceCollections& programCollection) const
{
	std::string frag =
		"#version 450\n"
		"#extension GL_NV_mesh_shader : enable\n"
		"\n"
		"layout (location=0) in perprimitiveNV vec4 primitiveColor;\n"
		"layout (location=0) out vec4 outColor;\n"
		"\n"
		"void main ()\n"
		"{\n"
		"    outColor = primitiveColor;\n"
		"}\n"
		;
	programCollection.glslSources.add("frag") << glu::FragmentSource(frag);
}

class MeshShaderMiscInstance : public vkt::TestInstance
{
public:
					MeshShaderMiscInstance	(Context& context, const MiscTestParams* params)
						: vkt::TestInstance	(context)
						, m_params			(params)
						, m_referenceLevel	()
					{
					}

	void			generateSolidRefLevel	(const tcu::Vec4& color, std::unique_ptr<tcu::TextureLevel>& output);
	virtual void	generateReferenceLevel	() = 0;

	virtual bool	verifyResult			(const tcu::ConstPixelBufferAccess& resultAccess, const tcu::TextureLevel& referenceLevel) const;
	virtual bool	verifyResult			(const tcu::ConstPixelBufferAccess& resultAccess) const;
	tcu::TestStatus	iterate					() override;

protected:
	const MiscTestParams*				m_params;
	std::unique_ptr<tcu::TextureLevel>	m_referenceLevel;
};

void MeshShaderMiscInstance::generateSolidRefLevel (const tcu::Vec4& color, std::unique_ptr<tcu::TextureLevel>& output)
{
	const auto format		= getOutputFormat();
	const auto tcuFormat	= mapVkFormat(format);

	const auto iWidth		= static_cast<int>(m_params->width);
	const auto iHeight		= static_cast<int>(m_params->height);

	output.reset(new tcu::TextureLevel(tcuFormat, iWidth, iHeight));

	const auto access		= output->getAccess();

	// Fill with solid color.
	tcu::clear(access, color);
}

bool MeshShaderMiscInstance::verifyResult (const tcu::ConstPixelBufferAccess& resultAccess) const
{
	return verifyResult(resultAccess, *m_referenceLevel);
}

bool MeshShaderMiscInstance::verifyResult (const tcu::ConstPixelBufferAccess& resultAccess, const tcu::TextureLevel& referenceLevel) const
{
	const auto referenceAccess = referenceLevel.getAccess();

	const auto refWidth		= referenceAccess.getWidth();
	const auto refHeight	= referenceAccess.getHeight();
	const auto refDepth		= referenceAccess.getDepth();

	const auto resWidth		= resultAccess.getWidth();
	const auto resHeight	= resultAccess.getHeight();
	const auto resDepth		= resultAccess.getDepth();

	DE_ASSERT(resWidth == refWidth || resHeight == refHeight || resDepth == refDepth);

	// For release builds.
	DE_UNREF(refWidth);
	DE_UNREF(refHeight);
	DE_UNREF(refDepth);
	DE_UNREF(resWidth);
	DE_UNREF(resHeight);
	DE_UNREF(resDepth);

	const auto outputFormat		= getOutputFormat();
	const auto expectedFormat	= mapVkFormat(outputFormat);
	const auto resFormat		= resultAccess.getFormat();
	const auto refFormat		= referenceAccess.getFormat();

	DE_ASSERT(resFormat == expectedFormat && refFormat == expectedFormat);

	// For release builds
	DE_UNREF(expectedFormat);
	DE_UNREF(resFormat);
	DE_UNREF(refFormat);

	auto&			log				= m_context.getTestContext().getLog();
	const auto		threshold		= getCompareThreshold();
	const tcu::Vec4	thresholdVec	(threshold, threshold, threshold, threshold);

	return tcu::floatThresholdCompare(log, "Result", "", referenceAccess, resultAccess, thresholdVec, tcu::COMPARE_LOG_ON_ERROR);
}

tcu::TestStatus MeshShaderMiscInstance::iterate ()
{
	const auto&		vkd			= m_context.getDeviceInterface();
	const auto		device		= m_context.getDevice();
	auto&			alloc		= m_context.getDefaultAllocator();
	const auto		queueIndex	= m_context.getUniversalQueueFamilyIndex();
	const auto		queue		= m_context.getUniversalQueue();

	const auto		imageFormat	= getOutputFormat();
	const auto		tcuFormat	= mapVkFormat(imageFormat);
	const auto		imageExtent	= makeExtent3D(m_params->width, m_params->height, 1u);
	const auto		imageUsage	= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);

	const VkImageCreateInfo colorBufferInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,								//	const void*				pNext;
		0u,										//	VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		imageFormat,							//	VkFormat				format;
		imageExtent,							//	VkExtent3D				extent;
		1u,										//	uint32_t				mipLevels;
		1u,										//	uint32_t				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		imageUsage,								//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		0u,										//	uint32_t				queueFamilyIndexCount;
		nullptr,								//	const uint32_t*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};

	// Create color image and view.
	ImageWithMemory	colorImage	(vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
	const auto		colorSRR	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto		colorSRL	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const auto		colorView	= makeImageView(vkd, device, colorImage.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, colorSRR);

	// Create a memory buffer for verification.
	const auto			verificationBufferSize	= static_cast<VkDeviceSize>(imageExtent.width * imageExtent.height * tcu::getPixelSize(tcuFormat));
	const auto			verificationBufferUsage	= (VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const auto			verificationBufferInfo	= makeBufferCreateInfo(verificationBufferSize, verificationBufferUsage);

	BufferWithMemory	verificationBuffer		(vkd, device, alloc, verificationBufferInfo, MemoryRequirement::HostVisible);
	auto&				verificationBufferAlloc	= verificationBuffer.getAllocation();
	void*				verificationBufferData	= verificationBufferAlloc.getHostPtr();

	// Pipeline layout.
	const auto pipelineLayout = makePipelineLayout(vkd, device);

	// Shader modules.
	const auto&	binaries	= m_context.getBinaryCollection();
	const auto	hasTask		= binaries.contains("task");

	const auto	meshShader	= createShaderModule(vkd, device, binaries.get("mesh"));
	const auto	fragShader	= createShaderModule(vkd, device, binaries.get("frag"));

	Move<VkShaderModule> taskShader;
	if (hasTask)
		taskShader = createShaderModule(vkd, device, binaries.get("task"));

	// Render pass.
	const auto renderPass = makeRenderPass(vkd, device, imageFormat);

	// Framebuffer.
	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorView.get(), imageExtent.width, imageExtent.height);

	// Viewport and scissor.
	const std::vector<VkViewport>	viewports	(1u, makeViewport(imageExtent));
	const std::vector<VkRect2D>		scissors	(1u, makeRect2D(imageExtent));

	const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
		taskShader.get(), meshShader.get(), fragShader.get(),
		renderPass.get(), viewports, scissors);

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

	beginCommandBuffer(vkd, cmdBuffer);

	// Run pipeline.
	const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 0.0f);
	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0u), clearColor);
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
	vkd.cmdDrawMeshTasksNV(cmdBuffer, m_params->drawCount(), 0u);
	endRenderPass(vkd, cmdBuffer);

	// Copy color buffer to verification buffer.
	const auto colorAccess		= (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
	const auto transferRead		= VK_ACCESS_TRANSFER_READ_BIT;
	const auto transferWrite	= VK_ACCESS_TRANSFER_WRITE_BIT;
	const auto hostRead			= VK_ACCESS_HOST_READ_BIT;

	const auto preCopyBarrier	= makeImageMemoryBarrier(colorAccess, transferRead, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorImage.get(), colorSRR);
	const auto postCopyBarrier	= makeMemoryBarrier(transferWrite, hostRead);
	const auto copyRegion		= makeBufferImageCopy(imageExtent, colorSRL);

	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &preCopyBarrier);
	vkd.cmdCopyImageToBuffer(cmdBuffer, colorImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, &copyRegion);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &postCopyBarrier, 0u, nullptr, 0u, nullptr);

	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Generate reference image and compare results.
	const tcu::IVec3					iExtent				(static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height), 1);
	const tcu::ConstPixelBufferAccess	verificationAccess	(tcuFormat, iExtent, verificationBufferData);

	generateReferenceLevel();
	invalidateAlloc(vkd, device, verificationBufferAlloc);
	if (!verifyResult(verificationAccess))
		TCU_FAIL("Result does not match reference; check log for details");

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

// Verify passing more complex data between the task and mesh shaders.
class ComplexTaskDataCase : public MeshShaderMiscCase
{
public:
					ComplexTaskDataCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class ComplexTaskDataInstance : public MeshShaderMiscInstance
{
public:
	ComplexTaskDataInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

void ComplexTaskDataInstance::generateReferenceLevel ()
{
	const auto format		= getOutputFormat();
	const auto tcuFormat	= mapVkFormat(format);

	const auto iWidth		= static_cast<int>(m_params->width);
	const auto iHeight		= static_cast<int>(m_params->height);

	const auto halfWidth	= iWidth / 2;
	const auto halfHeight	= iHeight / 2;

	m_referenceLevel.reset(new tcu::TextureLevel(tcuFormat, iWidth, iHeight));

	const auto access		= m_referenceLevel->getAccess();

	// Each image quadrant gets a different color.
	for (int y = 0; y < iHeight; ++y)
	for (int x = 0; x < iWidth; ++x)
	{
		const float	red			= ((y < halfHeight) ? 0.0f : 1.0f);
		const float	green		= ((x < halfWidth)  ? 0.0f : 1.0f);
		const auto	refColor	= tcu::Vec4(red, green, 1.0f, 1.0f);
		access.setPixel(refColor, x, y);
	}
}

void ComplexTaskDataCase::initPrograms (vk::SourceCollections& programCollection) const
{
	// Add the generic fragment shader.
	MeshShaderMiscCase::initPrograms(programCollection);

	const std::string taskDataDeclTemplate =
		"struct RowId {\n"
		"    uint id;\n"
		"};\n"
		"\n"
		"struct WorkGroupData {\n"
		"    float WorkGroupIdPlusOnex1000Iota[10];\n"
		"    RowId rowId;\n"
		"    uvec3 WorkGroupIdPlusOnex2000Iota;\n"
		"    vec2  WorkGroupIdPlusOnex3000Iota;\n"
		"};\n"
		"\n"
		"struct ExternalData {\n"
		"    float OneMillion;\n"
		"    uint  TwoMillion;\n"
		"    WorkGroupData workGroupData;\n"
		"};\n"
		"\n"
		"${INOUT} taskNV TaskData {\n"
		"    uint yes;\n"
		"    ExternalData externalData;\n"
		"} td;\n"
		;
	const tcu::StringTemplate taskDataDecl(taskDataDeclTemplate);

	{
		std::map<std::string, std::string> taskMap;
		taskMap["INOUT"] = "out";
		std::ostringstream task;
		task
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (local_size_x=1) in;\n"
			<< "\n"
			<< taskDataDecl.specialize(taskMap)
			<< "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "    gl_TaskCountNV = 2u;\n"
			<< "    td.yes = 1u;\n"
			<< "    td.externalData.OneMillion = 1000000.0;\n"
			<< "    td.externalData.TwoMillion = 2000000u;\n"
			<< "    for (uint i = 0; i < 10; i++) {\n"
			<< "        td.externalData.workGroupData.WorkGroupIdPlusOnex1000Iota[i] = float((gl_WorkGroupID.x + 1u) * 1000 + i);\n"
			<< "    }\n"
			<< "    {\n"
			<< "        uint baseVal = (gl_WorkGroupID.x + 1u) * 2000;\n"
			<< "        td.externalData.workGroupData.WorkGroupIdPlusOnex2000Iota = uvec3(baseVal, baseVal + 1, baseVal + 2);\n"
			<< "    }\n"
			<< "    {\n"
			<< "        uint baseVal = (gl_WorkGroupID.x + 1u) * 3000;\n"
			<< "        td.externalData.workGroupData.WorkGroupIdPlusOnex3000Iota = vec2(baseVal, baseVal + 1);\n"
			<< "    }\n"
			<< "    td.externalData.workGroupData.rowId.id = gl_WorkGroupID.x;\n"
			<< "}\n"
			;
		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
	}

	{
		std::map<std::string, std::string> meshMap;
		meshMap["INOUT"] = "in";
		std::ostringstream mesh;
		mesh
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout(local_size_x=2) in;\n"
			<< "layout(triangles) out;\n"
			<< "layout(max_vertices=4, max_primitives=2) out;\n"
			<< "\n"
			<< "layout (location=0) out perprimitiveNV vec4 triangleColor[];\n"
			<< "\n"
			<< taskDataDecl.specialize(meshMap)
			<< "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "    bool dataOK = true;\n"
			<< "    dataOK = (dataOK && (td.yes == 1u));\n"
			<< "    dataOK = (dataOK && (td.externalData.OneMillion == 1000000.0 && td.externalData.TwoMillion == 2000000u));\n"
			<< "    uint rowId = td.externalData.workGroupData.rowId.id;\n"
			<< "    dataOK = (dataOK && (rowId == 0u || rowId == 1u));\n"
			<< "\n"
			<< "    {\n"
			<< "        uint baseVal = (rowId + 1u) * 1000u;\n"
			<< "        for (uint i = 0; i < 10; i++) {\n"
			<< "            if (td.externalData.workGroupData.WorkGroupIdPlusOnex1000Iota[i] != float(baseVal + i)) {\n"
			<< "                dataOK = false;\n"
			<< "                break;\n"
			<< "            }\n"
			<< "        }\n"
			<< "    }\n"
			<< "\n"
			<< "    {\n"
			<< "        uint baseVal = (rowId + 1u) * 2000;\n"
			<< "        uvec3 expected = uvec3(baseVal, baseVal + 1, baseVal + 2);\n"
			<< "        if (td.externalData.workGroupData.WorkGroupIdPlusOnex2000Iota != expected) {\n"
			<< "            dataOK = false;\n"
			<< "        }\n"
			<< "    }\n"
			<< "\n"
			<< "    {\n"
			<< "        uint baseVal = (rowId + 1u) * 3000;\n"
			<< "        vec2 expected = vec2(baseVal, baseVal + 1);\n"
			<< "        if (td.externalData.workGroupData.WorkGroupIdPlusOnex3000Iota != expected) {\n"
			<< "            dataOK = false;\n"
			<< "        }\n"
			<< "    }\n"
			<< "\n"
			<< "    uint columnId = gl_WorkGroupID.x;\n"
			<< "\n"
			<< "    if (dataOK) {\n"
			<< "        gl_PrimitiveCountNV = 2u;\n"
			<< "    }\n"
			<< "    else {\n"
			<< "        gl_PrimitiveCountNV = 0u;\n"
			<< "        return;\n"
			<< "    }\n"
			<< "\n"
			<< "    const vec4 outColor = vec4(rowId, columnId, 1.0f, 1.0f);\n"
			<< "    triangleColor[0] = outColor;\n"
			<< "    triangleColor[1] = outColor;\n"
			<< "\n"
			<< "    // Each local invocation will generate two points and one triangle from the quad.\n"
			<< "    // The first local invocation will generate the top quad vertices.\n"
			<< "    // The second invocation will generate the two bottom vertices.\n"
			<< "    vec4 left  = vec4(0.0, 0.0, 0.0, 1.0);\n"
			<< "    vec4 right = vec4(1.0, 0.0, 0.0, 1.0);\n"
			<< "\n"
			<< "    float localInvocationOffsetY = float(gl_LocalInvocationID.x);\n"
			<< "    left.y  += localInvocationOffsetY;\n"
			<< "    right.y += localInvocationOffsetY;\n"
			<< "\n"
			<< "    // The code above creates a quad from (0, 0) to (1, 1) but we need to offset it\n"
			<< "    // in X and/or Y depending on the row and column, to place it in other quadrants.\n"
			<< "    float quadrantOffsetX = float(int(columnId) - 1);\n"
			<< "    float quadrantOffsetY = float(int(rowId) - 1);\n"
			<< "\n"
			<< "    left.x  += quadrantOffsetX;\n"
			<< "    right.x += quadrantOffsetX;\n"
			<< "\n"
			<< "    left.y  += quadrantOffsetY;\n"
			<< "    right.y += quadrantOffsetY;\n"
			<< "\n"
			<< "    uint baseVertexId = 2*gl_LocalInvocationID.x;\n"
			<< "    gl_MeshVerticesNV[baseVertexId + 0].gl_Position = left;\n"
			<< "    gl_MeshVerticesNV[baseVertexId + 1].gl_Position = right;\n"
			<< "\n"
			<< "    uint baseIndexId = 3*gl_LocalInvocationID.x;\n"
			<< "    // 0,1,2 or 1,2,3 (note: triangles alternate front face this way)\n"
			<< "    gl_PrimitiveIndicesNV[baseIndexId + 0] = 0 + gl_LocalInvocationID.x;\n"
			<< "    gl_PrimitiveIndicesNV[baseIndexId + 1] = 1 + gl_LocalInvocationID.x;\n"
			<< "    gl_PrimitiveIndicesNV[baseIndexId + 2] = 2 + gl_LocalInvocationID.x;\n"
			<< "}\n"
			;
		programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
	}
}

TestInstance* ComplexTaskDataCase::createInstance (Context& context) const
{
	return new ComplexTaskDataInstance(context, m_params.get());
}

// Verify drawing a single point.
class SinglePointCase : public MeshShaderMiscCase
{
public:
					SinglePointCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class SinglePointInstance : public MeshShaderMiscInstance
{
public:
	SinglePointInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* SinglePointCase::createInstance (Context& context) const
{
	return new SinglePointInstance (context, m_params.get());
}

void SinglePointCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(!m_params->needsTaskShader());

	MeshShaderMiscCase::initPrograms(programCollection);

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout(local_size_x=1) in;\n"
		<< "layout(points) out;\n"
		<< "layout(max_vertices=256, max_primitives=256) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 pointColor[];\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 1u;\n"
		<< "    pointColor[0] = vec4(0.0f, 1.0f, 1.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[0].gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[0].gl_PointSize = 1.0f;\n"
		<< "    gl_PrimitiveIndicesNV[0] = 0;\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

void SinglePointInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), m_referenceLevel);

	const auto halfWidth	= static_cast<int>(m_params->width / 2u);
	const auto halfHeight	= static_cast<int>(m_params->height / 2u);
	const auto access		= m_referenceLevel->getAccess();

	access.setPixel(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f), halfWidth, halfHeight);
}

// Verify drawing a single line.
class SingleLineCase : public MeshShaderMiscCase
{
public:
					SingleLineCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class SingleLineInstance : public MeshShaderMiscInstance
{
public:
	SingleLineInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* SingleLineCase::createInstance (Context& context) const
{
	return new SingleLineInstance (context, m_params.get());
}

void SingleLineCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(!m_params->needsTaskShader());

	MeshShaderMiscCase::initPrograms(programCollection);

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout(local_size_x=1) in;\n"
		<< "layout(lines) out;\n"
		<< "layout(max_vertices=256, max_primitives=256) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 lineColor[];\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 1u;\n"
		<< "    lineColor[0] = vec4(0.0f, 1.0f, 1.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[0].gl_Position = vec4(-1.0f, 0.0f, 0.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[1].gl_Position = vec4( 1.0f, 0.0f, 0.0f, 1.0f);\n"
		<< "    gl_PrimitiveIndicesNV[0] = 0;\n"
		<< "    gl_PrimitiveIndicesNV[1] = 1;\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

void SingleLineInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), m_referenceLevel);

	const auto iWidth		= static_cast<int>(m_params->width);
	const auto halfHeight	= static_cast<int>(m_params->height / 2u);
	const auto access		= m_referenceLevel->getAccess();

	// Center row.
	for (int x = 0; x < iWidth; ++x)
		access.setPixel(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f), x, halfHeight);
}

// Verify drawing a single triangle.
class SingleTriangleCase : public MeshShaderMiscCase
{
public:
					SingleTriangleCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class SingleTriangleInstance : public MeshShaderMiscInstance
{
public:
	SingleTriangleInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* SingleTriangleCase::createInstance (Context& context) const
{
	return new SingleTriangleInstance (context, m_params.get());
}

void SingleTriangleCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(!m_params->needsTaskShader());

	MeshShaderMiscCase::initPrograms(programCollection);

	const float halfPixelX = 2.0f / static_cast<float>(m_params->width);
	const float halfPixelY = 2.0f / static_cast<float>(m_params->height);

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout(local_size_x=1) in;\n"
		<< "layout(triangles) out;\n"
		<< "layout(max_vertices=256, max_primitives=256) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 triangleColor[];\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 1u;\n"
		<< "    triangleColor[0] = vec4(0.0f, 1.0f, 1.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[0].gl_Position = vec4(" <<  halfPixelY << ", " << -halfPixelX << ", 0.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[1].gl_Position = vec4(" <<  halfPixelY << ", " <<  halfPixelX << ", 0.0f, 1.0f);\n"
		<< "    gl_MeshVerticesNV[2].gl_Position = vec4(" << -halfPixelY << ", 0.0f, 0.0f, 1.0f);\n"
		<< "    gl_PrimitiveIndicesNV[0] = 0;\n"
		<< "    gl_PrimitiveIndicesNV[1] = 1;\n"
		<< "    gl_PrimitiveIndicesNV[2] = 2;\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

void SingleTriangleInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), m_referenceLevel);

	const auto halfWidth	= static_cast<int>(m_params->width / 2u);
	const auto halfHeight	= static_cast<int>(m_params->height / 2u);
	const auto access		= m_referenceLevel->getAccess();

	// Single pixel in the center.
	access.setPixel(tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f), halfWidth, halfHeight);
}

// Verify drawing the maximum number of points.
class MaxPointsCase : public MeshShaderMiscCase
{
public:
					MaxPointsCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class MaxPointsInstance : public MeshShaderMiscInstance
{
public:
	MaxPointsInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* MaxPointsCase::createInstance (Context& context) const
{
	return new MaxPointsInstance (context, m_params.get());
}

void MaxPointsCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(!m_params->needsTaskShader());

	MeshShaderMiscCase::initPrograms(programCollection);

	// Fill a 16x16 image with 256 points. Each of the 32 local invocations will handle a segment of 8 pixels. Two segments per row.
	DE_ASSERT(m_params->width == 16u && m_params->height == 16u);

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout(local_size_x=32) in;\n"
		<< "layout(points) out;\n"
		<< "layout(max_vertices=256, max_primitives=256) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 pointColor[];\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 256u;\n"
		<< "    uint firstPixel = 8u * gl_LocalInvocationID.x;\n"
		<< "    uint row = firstPixel / 16u;\n"
		<< "    uint col = firstPixel % 16u;\n"
		<< "    float pixSize = 2.0f / 16.0f;\n"
		<< "    float yCoord = pixSize * (float(row) + 0.5f) - 1.0f;\n"
		<< "    float baseXCoord = pixSize * (float(col) + 0.5f) - 1.0f;\n"
		<< "    for (uint i = 0; i < 8u; i++) {\n"
		<< "        float xCoord = baseXCoord + pixSize * float(i);\n"
		<< "        uint pixId = firstPixel + i;\n"
		<< "        gl_MeshVerticesNV[pixId].gl_Position = vec4(xCoord, yCoord, 0.0f, 1.0f);\n"
		<< "        gl_MeshVerticesNV[pixId].gl_PointSize = 1.0f;\n"
		<< "        gl_PrimitiveIndicesNV[pixId] = pixId;\n"
		<< "        pointColor[pixId] = vec4(((xCoord + 1.0f) / 2.0f), ((yCoord + 1.0f) / 2.0f), 0.0f, 1.0f);\n"
		<< "    }\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

void MaxPointsInstance::generateReferenceLevel ()
{
	const auto format		= getOutputFormat();
	const auto tcuFormat	= mapVkFormat(format);

	const auto iWidth		= static_cast<int>(m_params->width);
	const auto iHeight		= static_cast<int>(m_params->height);
	const auto fWidth		= static_cast<float>(m_params->width);
	const auto fHeight		= static_cast<float>(m_params->height);

	m_referenceLevel.reset(new tcu::TextureLevel(tcuFormat, iWidth, iHeight));

	const auto access		= m_referenceLevel->getAccess();

	// Fill with gradient like the shader does.
	for (int y = 0; y < iHeight; ++y)
	for (int x = 0; x < iWidth; ++x)
	{
		const tcu::Vec4 color (
			((static_cast<float>(x) + 0.5f) / fWidth),
			((static_cast<float>(y) + 0.5f) / fHeight),
			0.0f, 1.0f);
		access.setPixel(color, x, y);
	}
}

// Verify drawing the maximum number of lines.
class MaxLinesCase : public MeshShaderMiscCase
{
public:
					MaxLinesCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class MaxLinesInstance : public MeshShaderMiscInstance
{
public:
	MaxLinesInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* MaxLinesCase::createInstance (Context& context) const
{
	return new MaxLinesInstance (context, m_params.get());
}

void MaxLinesCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(!m_params->needsTaskShader());

	MeshShaderMiscCase::initPrograms(programCollection);

	// Fill a 1x1020 image with 255 lines, each line being 4 pixels tall. Each invocation will generate ~8 lines.
	DE_ASSERT(m_params->width == 1u && m_params->height == 1020u);

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout(local_size_x=32) in;\n"
		<< "layout(lines) out;\n"
		<< "layout(max_vertices=256, max_primitives=255) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 lineColor[];\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 255u;\n"
		<< "    uint firstLine = 8u * gl_LocalInvocationID.x;\n"
		<< "    for (uint i = 0u; i < 8u; i++) {\n"
		<< "        uint lineId = firstLine + i;\n"
		<< "        uint topPixel = 4u * lineId;\n"
		<< "        uint bottomPixel = 3u + topPixel;\n"
		<< "        if (bottomPixel < 1020u) {\n"
		<< "            float bottomCoord = ((float(bottomPixel) + 1.0f) / 1020.0) * 2.0 - 1.0;\n"
		<< "            gl_MeshVerticesNV[lineId + 1u].gl_Position = vec4(0.0, bottomCoord, 0.0f, 1.0f);\n"
		<< "            gl_PrimitiveIndicesNV[lineId * 2u] = lineId;\n"
		<< "            gl_PrimitiveIndicesNV[lineId * 2u + 1u] = lineId + 1u;\n"
		<< "            lineColor[lineId] = vec4(0.0f, 1.0f, float(lineId) / 255.0f, 1.0f);\n"
		<< "        } else {\n"
		<< "            // The last iteration of the last invocation emits the first point\n"
		<< "            gl_MeshVerticesNV[0].gl_Position = vec4(0.0, -1.0, 0.0f, 1.0f);\n"
		<< "        }\n"
		<< "    }\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

void MaxLinesInstance::generateReferenceLevel ()
{
	const auto format		= getOutputFormat();
	const auto tcuFormat	= mapVkFormat(format);

	const auto iWidth		= static_cast<int>(m_params->width);
	const auto iHeight		= static_cast<int>(m_params->height);

	m_referenceLevel.reset(new tcu::TextureLevel(tcuFormat, iWidth, iHeight));

	const auto access		= m_referenceLevel->getAccess();

	// Fill lines, 4 pixels per line.
	const uint32_t kNumLines = 255u;
	const uint32_t kLineHeight = 4u;

	for (uint32_t i = 0u; i < kNumLines; ++i)
	{
		const tcu::Vec4 color (0.0f, 1.0f, static_cast<float>(i) / static_cast<float>(kNumLines), 1.0f);
		for (uint32_t j = 0u; j < kLineHeight; ++j)
			access.setPixel(color, 0, i*kLineHeight + j);
	}
}

// Verify drawing the maximum number of triangles.
class MaxTrianglesCase : public MeshShaderMiscCase
{
public:
					MaxTrianglesCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class MaxTrianglesInstance : public MeshShaderMiscInstance
{
public:
	MaxTrianglesInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* MaxTrianglesCase::createInstance (Context& context) const
{
	return new MaxTrianglesInstance (context, m_params.get());
}

void MaxTrianglesCase::initPrograms (vk::SourceCollections& programCollection) const
{
	DE_ASSERT(!m_params->needsTaskShader());

	MeshShaderMiscCase::initPrograms(programCollection);

	// Fill a sufficiently large image with solid color. Generate a quarter of a circle with the center in the top left corner,
	// using a triangle fan that advances from top to bottom. Each invocation will generate ~8 triangles.
	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout(local_size_x=32) in;\n"
		<< "layout(triangles) out;\n"
		<< "layout(max_vertices=256, max_primitives=254) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 triangleColor[];\n"
		<< "\n"
		<< "const float PI_2 = 1.57079632679489661923;\n"
		<< "const float RADIUS = 4.5;\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 254u;\n"
		<< "    uint firstTriangle = 8u * gl_LocalInvocationID.x;\n"
		<< "    for (uint i = 0u; i < 8u; i++) {\n"
		<< "        uint triangleId = firstTriangle + i;\n"
		<< "        if (triangleId < 254u) {\n"
		<< "            uint vertexId = triangleId + 2u;\n"
		<< "            float angleProportion = float(vertexId - 1u) / 254.0f;\n"
		<< "            float angle = PI_2 * angleProportion;\n"
		<< "            float xCoord = cos(angle) * RADIUS - 1.0;\n"
		<< "            float yCoord = sin(angle) * RADIUS - 1.0;\n"
		<< "            gl_MeshVerticesNV[vertexId].gl_Position = vec4(xCoord, yCoord, 0.0, 1.0);\n"
		<< "            gl_PrimitiveIndicesNV[triangleId * 3u + 0u] = 0u;\n"
		<< "            gl_PrimitiveIndicesNV[triangleId * 3u + 1u] = triangleId + 1u;\n"
		<< "            gl_PrimitiveIndicesNV[triangleId * 3u + 2u] = triangleId + 2u;\n"
		<< "            triangleColor[triangleId] = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
		<< "        } else {\n"
		<< "            // The last iterations of the last invocation emit the first two vertices\n"
		<< "            uint vertexId = triangleId - 254u;\n"
		<< "            if (vertexId == 0u) {\n"
		<< "                gl_MeshVerticesNV[0u].gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
		<< "            } else {\n"
		<< "                gl_MeshVerticesNV[1u].gl_Position = vec4(RADIUS, -1.0, 0.0, 1.0);\n"
		<< "            }\n"
		<< "        }\n"
		<< "    }\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

void MaxTrianglesInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), m_referenceLevel);
}

// Large work groups with many threads.
class LargeWorkGroupCase : public MeshShaderMiscCase
{
public:
					LargeWorkGroupCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

	static constexpr uint32_t kLocalInvocations = 32u;
};

class LargeWorkGroupInstance : public MeshShaderMiscInstance
{
public:
	LargeWorkGroupInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* LargeWorkGroupCase::createInstance (Context& context) const
{
	return new LargeWorkGroupInstance(context, m_params.get());
}

void LargeWorkGroupInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), m_referenceLevel);
}

void LargeWorkGroupCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const auto useTaskShader	= m_params->needsTaskShader();
	const auto taskMultiplier	= (useTaskShader ? m_params->taskCount.get() : 1u);

	// Add the frag shader.
	MeshShaderMiscCase::initPrograms(programCollection);

	std::ostringstream taskData;
	taskData
		<< "taskNV TaskData {\n"
		<< "    uint parentTask[" << kLocalInvocations << "];\n"
		<< "} td;\n"
		;
	const auto taskDataStr = taskData.str();

	if (useTaskShader)
	{
		std::ostringstream task;
		task
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (local_size_x=" << kLocalInvocations << ") in;\n"
			<< "\n"
			<< "out " << taskDataStr
			<< "\n"
			<< "void main () {\n"
			<< "    gl_TaskCountNV = " << m_params->meshCount << ";\n"
			<< "    td.parentTask[gl_LocalInvocationID.x] = gl_WorkGroupID.x;\n"
			<< "}\n"
			;
		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
	}

	// Needed for the code below to work.
	DE_ASSERT(m_params->width * m_params->height == taskMultiplier * m_params->meshCount * kLocalInvocations);
	DE_UNREF(taskMultiplier); // For release builds.

	// Emit one point per framebuffer pixel. The number of jobs (kLocalInvocations in each mesh shader work group, multiplied by the
	// number of mesh work groups emitted by each task work group) must be the same as the total framebuffer size. Calculate a job
	// ID corresponding to the current mesh shader invocation, and assign a pixel position to it. Draw a point at that position.
	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=" << kLocalInvocations << ") in;\n"
		<< "layout (points) out;\n"
		<< "layout (max_vertices=" << kLocalInvocations << ", max_primitives=" << kLocalInvocations << ") out;\n"
		<< "\n"
		<< (useTaskShader ? "in " + taskDataStr : "")
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 pointColor[];\n"
		<< "\n"
		<< "void main () {\n"
		;

	if (useTaskShader)
	{
		mesh
			<< "    uint parentTask = td.parentTask[0];\n"
			<< "    if (td.parentTask[gl_LocalInvocationID.x] != parentTask) {\n"
			<< "        return;\n"
			<< "    }\n"
			;
	}
	else
	{
		mesh << "    uint parentTask = 0;\n";
	}

	mesh
		<< "    gl_PrimitiveCountNV = " << kLocalInvocations << ";\n"
		<< "    uint jobId = ((parentTask * " << m_params->meshCount << ") + gl_WorkGroupID.x) * " << kLocalInvocations << " + gl_LocalInvocationID.x;\n"
		<< "    uint row = jobId / " << m_params->width << ";\n"
		<< "    uint col = jobId % " << m_params->width << ";\n"
		<< "    float yCoord = (float(row + 0.5) / " << m_params->height << ".0) * 2.0 - 1.0;\n"
		<< "    float xCoord = (float(col + 0.5) / " << m_params->width << ".0) * 2.0 - 1.0;\n"
		<< "    gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_Position = vec4(xCoord, yCoord, 0.0, 1.0);\n"
		<< "    gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_PointSize = 1.0;\n"
		<< "    gl_PrimitiveIndicesNV[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n"
		<< "    pointColor[gl_LocalInvocationID.x] = vec4(0.0, 0.0, 1.0, 1.0);\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

// Tests that generate no primitives of a given type.
enum class PrimitiveType { POINTS=0, LINES, TRIANGLES };

std::string primitiveTypeName (PrimitiveType primitiveType)
{
	std::string primitiveName;

	switch (primitiveType)
	{
	case PrimitiveType::POINTS:		primitiveName = "points";		break;
	case PrimitiveType::LINES:		primitiveName = "lines";		break;
	case PrimitiveType::TRIANGLES:	primitiveName = "triangles";	break;
	default: DE_ASSERT(false); break;
	}

	return primitiveName;
}

struct NoPrimitivesParams : public MiscTestParams
{
	PrimitiveType primitiveType;
};

class NoPrimitivesCase : public MeshShaderMiscCase
{
public:
					NoPrimitivesCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class NoPrimitivesInstance : public MeshShaderMiscInstance
{
public:
	NoPrimitivesInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

void NoPrimitivesInstance::generateReferenceLevel ()
{
	// No primitives: clear color.
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), m_referenceLevel);
}

TestInstance* NoPrimitivesCase::createInstance (Context& context) const
{
	return new NoPrimitivesInstance(context, m_params.get());
}

void NoPrimitivesCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const auto params = dynamic_cast<NoPrimitivesParams*>(m_params.get());

	DE_ASSERT(params);
	DE_ASSERT(!params->needsTaskShader());

	const auto primitiveName = primitiveTypeName(params->primitiveType);

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=32) in;\n"
		<< "layout (" << primitiveName << ") out;\n"
		<< "layout (max_vertices=256, max_primitives=256) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 primitiveColor[];\n"
		<< "\n"
		<< "void main () {\n"
		<< "    gl_PrimitiveCountNV = 0u;\n"
		<< "}\n"
		;

	MeshShaderMiscCase::initPrograms(programCollection);
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
}

class NoPrimitivesExtraWritesCase : public NoPrimitivesCase
{
public:
					NoPrimitivesExtraWritesCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: NoPrimitivesCase (testCtx, name, description, std::move(params))
					{}

	void			initPrograms			(vk::SourceCollections& programCollection) const override;

	static constexpr uint32_t kLocalInvocations = 32u;
};

void NoPrimitivesExtraWritesCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const auto params = dynamic_cast<NoPrimitivesParams*>(m_params.get());

	DE_ASSERT(params);
	DE_ASSERT(m_params->needsTaskShader());

	std::ostringstream taskData;
	taskData
		<< "taskNV TaskData {\n"
		<< "    uint localInvocations[" << kLocalInvocations << "];\n"
		<< "} td;\n"
		;
	const auto taskDataStr = taskData.str();

	std::ostringstream task;
	task
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=" << kLocalInvocations << ") in;\n"
		<< "\n"
		<< "out " << taskDataStr
		<< "\n"
		<< "void main () {\n"
		<< "    gl_TaskCountNV = " << params->meshCount << ";\n"
		<< "    td.localInvocations[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n"
		<< "}\n"
		;
	programCollection.glslSources.add("task") << glu::TaskSource(task.str());

	const auto primitiveName = primitiveTypeName(params->primitiveType);

	// Otherwise the shader would be illegal.
	DE_ASSERT(kLocalInvocations > 2u);

	uint32_t maxPrimitives = 0u;
	switch (params->primitiveType)
	{
	case PrimitiveType::POINTS:		maxPrimitives = kLocalInvocations - 0u;	break;
	case PrimitiveType::LINES:		maxPrimitives = kLocalInvocations - 1u;	break;
	case PrimitiveType::TRIANGLES:	maxPrimitives = kLocalInvocations - 2u;	break;
	default: DE_ASSERT(false); break;
	}

	const std::string pointSizeDecl	= ((params->primitiveType == PrimitiveType::POINTS)
									? "        gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_PointSize = 1.0;\n"
									: "");

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=" << kLocalInvocations << ") in;\n"
		<< "layout (" << primitiveName << ") out;\n"
		<< "layout (max_vertices=" << kLocalInvocations << ", max_primitives=" << maxPrimitives << ") out;\n"
		<< "\n"
		<< "in " << taskDataStr
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 primitiveColor[];\n"
		<< "\n"
		<< "shared uint sumOfIds;\n"
		<< "\n"
		<< "const float PI_2 = 1.57079632679489661923;\n"
		<< "const float RADIUS = 1.0f;\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    sumOfIds = 0u;\n"
		<< "    barrier();\n"
		<< "    atomicAdd(sumOfIds, td.localInvocations[gl_LocalInvocationID.x]);\n"
		<< "    barrier();\n"
		<< "    // This should dynamically give 0\n"
		<< "    gl_PrimitiveCountNV = sumOfIds - (" << kLocalInvocations * (kLocalInvocations - 1u) / 2u << ");\n"
		<< "\n"
		<< "    // Emit points and primitives to the arrays in any case\n"
		<< "    if (gl_LocalInvocationID.x > 0u) {\n"
		<< "        float proportion = (float(gl_LocalInvocationID.x - 1u) + 0.5f) / float(" << kLocalInvocations << " - 1u);\n"
		<< "        float angle = PI_2 * proportion;\n"
		<< "        float xCoord = cos(angle) * RADIUS - 1.0;\n"
		<< "        float yCoord = sin(angle) * RADIUS - 1.0;\n"
		<< "        gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_Position = vec4(xCoord, yCoord, 0.0, 1.0);\n"
		<< pointSizeDecl
		<< "    } else {\n"
		<< "        gl_MeshVerticesNV[gl_LocalInvocationID.x].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
		<< pointSizeDecl
		<< "    }\n"
		<< "    uint primitiveId = max(gl_LocalInvocationID.x, " << (maxPrimitives - 1u) << ");\n"
		<< "    primitiveColor[primitiveId] = vec4(0.0, 0.0, 1.0, 1.0);\n"
		;

	if (params->primitiveType == PrimitiveType::POINTS)
	{
		mesh
			<< "    gl_PrimitiveIndicesNV[primitiveId] = primitiveId;\n"
			;
	}
	else if (params->primitiveType == PrimitiveType::LINES)
	{
		mesh
			<< "    gl_PrimitiveIndicesNV[primitiveId * 2u + 0u] = primitiveId + 0u;\n"
			<< "    gl_PrimitiveIndicesNV[primitiveId * 2u + 1u] = primitiveId + 1u;\n"
			;
	}
	else if (params->primitiveType == PrimitiveType::TRIANGLES)
	{
		mesh
			<< "    gl_PrimitiveIndicesNV[primitiveId * 3u + 0u] = 0u;\n"
			<< "    gl_PrimitiveIndicesNV[primitiveId * 3u + 1u] = primitiveId + 1u;\n"
			<< "    gl_PrimitiveIndicesNV[primitiveId * 3u + 2u] = primitiveId + 3u;\n"
			;
	}
	else
		DE_ASSERT(false);

	mesh
		<< "}\n"
		;

	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());

	MeshShaderMiscCase::initPrograms(programCollection);
}

// Case testing barrier().
class SimpleBarrierCase : public MeshShaderMiscCase
{
public:
					SimpleBarrierCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

	static constexpr uint32_t kLocalInvocations = 32u;
};

class SimpleBarrierInstance : public MeshShaderMiscInstance
{
public:
	SimpleBarrierInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
};

TestInstance* SimpleBarrierCase::createInstance (Context& context) const
{
	return new SimpleBarrierInstance(context, m_params.get());
}

void SimpleBarrierInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), m_referenceLevel);
}

void SimpleBarrierCase::initPrograms (vk::SourceCollections& programCollection) const
{
	// Generate frag shader.
	MeshShaderMiscCase::initPrograms(programCollection);

	DE_ASSERT(m_params->meshCount == 1u);
	DE_ASSERT(m_params->width == 1u && m_params->height == 1u);

	std::ostringstream meshPrimData;
	meshPrimData
			<< "gl_PrimitiveCountNV = 1u;\n"
			<< "gl_MeshVerticesNV[0].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
			<< "gl_MeshVerticesNV[0].gl_PointSize = 1.0;\n"
			<< "primitiveColor[0] = vec4(0.0, 0.0, 1.0, 1.0);\n"
			<< "gl_PrimitiveIndicesNV[0] = 0;\n"
			;
	const std::string meshPrimStr	= meshPrimData.str();

	const std::string taskOK		= "gl_TaskCountNV = 1u;\n";
	const std::string taskFAIL		= "gl_TaskCountNV = 0u;\n";

	const std::string meshOK		= meshPrimStr;
	const std::string meshFAIL		= "gl_PrimitiveCountNV = 0u;\n";

	const std::string okStatement	= (m_params->needsTaskShader() ? taskOK : meshOK);
	const std::string failStatement	= (m_params->needsTaskShader() ? taskFAIL : meshFAIL);

	const std::string	sharedDecl = "shared uint counter;\n\n";
	std::ostringstream	verification;
	verification
		<< "counter = 0;\n"
		<< "barrier();\n"
		<< "atomicAdd(counter, 1u);\n"
		<< "barrier();\n"
		<< "if (gl_LocalInvocationID.x == 0u) {\n"
		<< "    if (counter == " << kLocalInvocations << ") {\n"
		<< "\n"
		<< okStatement
		<< "\n"
		<< "    } else {\n"
		<< "\n"
		<< failStatement
		<< "\n"
		<< "    }\n"
		<< "}\n"
		;

	// The mesh shader is very similar in both cases, so we use a template.
	std::ostringstream meshTemplateStr;
	meshTemplateStr
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=${LOCAL_SIZE}) in;\n"
		<< "layout (points) out;\n"
		<< "layout (max_vertices=1, max_primitives=1) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 primitiveColor[];\n"
		<< "\n"
		<< "${GLOBALS:opt}"
		<< "void main ()\n"
		<< "{\n"
		<< "${BODY}"
		<< "}\n"
		;
	const tcu::StringTemplate meshTemplate = meshTemplateStr.str();

	if (m_params->needsTaskShader())
	{
		std::ostringstream task;
		task
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (local_size_x=" << kLocalInvocations << ") in;\n"
			<< "\n"
			<< sharedDecl
			<< "void main ()\n"
			<< "{\n"
			<< verification.str()
			<< "}\n"
			;

		std::map<std::string, std::string> replacements;
		replacements["LOCAL_SIZE"]	= "1";
		replacements["BODY"]		= meshPrimStr;

		const auto meshStr = meshTemplate.specialize(replacements);

		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
		programCollection.glslSources.add("mesh") << glu::MeshSource(meshStr);
	}
	else
	{
		std::map<std::string, std::string> replacements;
		replacements["LOCAL_SIZE"]	= std::to_string(kLocalInvocations);
		replacements["BODY"]		= verification.str();
		replacements["GLOBALS"]		= sharedDecl;

		const auto meshStr = meshTemplate.specialize(replacements);

		programCollection.glslSources.add("mesh") << glu::MeshSource(meshStr);
	}
}

// Case testing memoryBarrierShared() and groupMemoryBarrier().
enum class MemoryBarrierType { SHARED = 0, GROUP };

struct MemoryBarrierParams : public MiscTestParams
{
	MemoryBarrierType memBarrierType;

	std::string glslFunc () const
	{
		std::string funcName;

		switch (memBarrierType)
		{
		case MemoryBarrierType::SHARED:		funcName = "memoryBarrierShared";	break;
		case MemoryBarrierType::GROUP:		funcName = "groupMemoryBarrier";	break;
		default: DE_ASSERT(false); break;
		}

		return funcName;
	}

};

class MemoryBarrierCase : public MeshShaderMiscCase
{
public:
					MemoryBarrierCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

	static constexpr uint32_t kLocalInvocations = 2u;
};

class MemoryBarrierInstance : public MeshShaderMiscInstance
{
public:
	MemoryBarrierInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void	generateReferenceLevel	() override;
	bool	verifyResult			(const tcu::ConstPixelBufferAccess& resultAccess) const override;

protected:
	// Allow two possible outcomes.
	std::unique_ptr<tcu::TextureLevel>	m_referenceLevel2;
};

TestInstance* MemoryBarrierCase::createInstance (Context& context) const
{
	return new MemoryBarrierInstance(context, m_params.get());
}

void MemoryBarrierInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), m_referenceLevel);
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), m_referenceLevel2);
}

bool MemoryBarrierInstance::verifyResult (const tcu::ConstPixelBufferAccess& resultAccess) const
{
	// Any of the two results is considered valid.
	constexpr auto Message		= tcu::TestLog::Message;
	constexpr auto EndMessage	= tcu::TestLog::EndMessage;

	// Clarify what we are checking in the logs; otherwise, they could be confusing.
	auto& log = m_context.getTestContext().getLog();
	const std::vector<tcu::TextureLevel*> levels = { m_referenceLevel.get(), m_referenceLevel2.get() };

	bool good = false;
	for (size_t i = 0; i < levels.size(); ++i)
	{
		log << Message << "Comparing result with reference " << i << "..." << EndMessage;
		const auto success = MeshShaderMiscInstance::verifyResult(resultAccess, *levels[i]);
		if (success)
		{
			log << Message << "Match! The test has passed" << EndMessage;
			good = true;
			break;
		}
	}

	return good;
}

void MemoryBarrierCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const auto params = dynamic_cast<MemoryBarrierParams*>(m_params.get());
	DE_ASSERT(params);

	// Generate frag shader.
	MeshShaderMiscCase::initPrograms(programCollection);

	DE_ASSERT(params->meshCount == 1u);
	DE_ASSERT(params->width == 1u && params->height == 1u);

	const bool taskShader = params->needsTaskShader();

	const std::string	taskDataDecl	= "taskNV TaskData { float blue; } td;\n\n";
	const std::string	inTaskData		= "in " + taskDataDecl;
	const std::string	outTaskData		= "out " + taskDataDecl;
	const auto			barrierFunc		= params->glslFunc();

	std::ostringstream meshPrimData;
	meshPrimData
			<< "gl_PrimitiveCountNV = 1u;\n"
			<< "gl_MeshVerticesNV[0].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
			<< "gl_MeshVerticesNV[0].gl_PointSize = 1.0;\n"
			<< "primitiveColor[0] = vec4(0.0, 0.0, " << (taskShader ? "td.blue" : "float(iterations % 2u)") << ", 1.0);\n"
			<< "gl_PrimitiveIndicesNV[0] = 0;\n"
			;
	const std::string meshPrimStr	= meshPrimData.str();

	const std::string taskAction	= "gl_TaskCountNV = 1u;\ntd.blue = float(iterations % 2u);\n";
	const std::string meshAction	= meshPrimStr;
	const std::string action		= (taskShader ? taskAction : meshAction);

	const std::string	sharedDecl = "shared uint flags[2];\n\n";
	std::ostringstream	verification;
	verification
		<< "flags[gl_LocalInvocationID.x] = 0u;\n"
		<< "barrier();\n"
		<< "flags[gl_LocalInvocationID.x] = 1u;\n"
		<<  barrierFunc << "();\n"
		<< "uint otherInvocation = 1u - gl_LocalInvocationID.x;\n"
		<< "uint iterations = 0u;\n"
		<< "while (flags[otherInvocation] != 1u) {\n"
		<< "    iterations++;\n"
		<< "}\n"
		<< "if (gl_LocalInvocationID.x == 0u) {\n"
		<< "\n"
		<< action
		<< "\n"
		<< "}\n"
		;

	// The mesh shader is very similar in both cases, so we use a template.
	std::ostringstream meshTemplateStr;
	meshTemplateStr
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=${LOCAL_SIZE}) in;\n"
		<< "layout (points) out;\n"
		<< "layout (max_vertices=1, max_primitives=1) out;\n"
		<< "\n"
		<< "layout (location=0) out perprimitiveNV vec4 primitiveColor[];\n"
		<< "\n"
		<< "${GLOBALS}"
		<< "void main ()\n"
		<< "{\n"
		<< "${BODY}"
		<< "}\n"
		;
	const tcu::StringTemplate meshTemplate = meshTemplateStr.str();

	if (params->needsTaskShader())
	{
		std::ostringstream task;
		task
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (local_size_x=" << kLocalInvocations << ") in;\n"
			<< "\n"
			<< sharedDecl
			<< outTaskData
			<< "void main ()\n"
			<< "{\n"
			<< verification.str()
			<< "}\n"
			;

		std::map<std::string, std::string> replacements;
		replacements["LOCAL_SIZE"]	= "1";
		replacements["BODY"]		= meshPrimStr;
		replacements["GLOBALS"]		= inTaskData;

		const auto meshStr = meshTemplate.specialize(replacements);

		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
		programCollection.glslSources.add("mesh") << glu::MeshSource(meshStr);
	}
	else
	{
		std::map<std::string, std::string> replacements;
		replacements["LOCAL_SIZE"]	= std::to_string(kLocalInvocations);
		replacements["BODY"]		= verification.str();
		replacements["GLOBALS"]		= sharedDecl;

		const auto meshStr = meshTemplate.specialize(replacements);

		programCollection.glslSources.add("mesh") << glu::MeshSource(meshStr);
	}
}

class CustomAttributesCase : public MeshShaderMiscCase
{
public:
					CustomAttributesCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase(testCtx, name, description, std::move(params)) {}
	virtual			~CustomAttributesCase		(void) {}

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

class CustomAttributesInstance : public MeshShaderMiscInstance
{
public:
						CustomAttributesInstance	(Context& context, const MiscTestParams* params)
							: MeshShaderMiscInstance(context, params) {}
	virtual				~CustomAttributesInstance	(void) {}

	void				generateReferenceLevel		() override;
	tcu::TestStatus		iterate						(void) override;
};

TestInstance* CustomAttributesCase::createInstance (Context& context) const
{
	return new CustomAttributesInstance(context, m_params.get());
}

void CustomAttributesCase::checkSupport (Context& context) const
{
	MeshShaderMiscCase::checkSupport(context);

	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_VIEWPORT);
	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_CLIP_DISTANCE);
}

void CustomAttributesCase::initPrograms (vk::SourceCollections& programCollection) const
{
	std::ostringstream frag;
	frag
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (location=0) in vec4 customAttribute1;\n"
		<< "layout (location=1) in flat float customAttribute2;\n"
		<< "layout (location=2) in flat int customAttribute3;\n"
		<< "\n"
		<< "layout (location=3) in perprimitiveNV flat uvec4 customAttribute4;\n"
		<< "layout (location=4) in perprimitiveNV float customAttribute5;\n"
		<< "\n"
		<< "layout (location=0) out vec4 outColor;\n"
		<< "\n"
		<< "void main ()\n"
		<< "{\n"
		<< "    bool goodPrimitiveID = (gl_PrimitiveID == 1000 || gl_PrimitiveID == 1001);\n"
		<< "    bool goodViewportIndex = (gl_ViewportIndex == 1);\n"
		<< "    bool goodCustom1 = (customAttribute1.x >= 0.25 && customAttribute1.x <= 0.5 &&\n"
		<< "                        customAttribute1.y >= 0.5  && customAttribute1.y <= 1.0 &&\n"
		<< "                        customAttribute1.z >= 10.0 && customAttribute1.z <= 20.0 &&\n"
		<< "                        customAttribute1.w == 3.0);\n"
		<< "    bool goodCustom2 = (customAttribute2 == 1.0 || customAttribute2 == 2.0);\n"
		<< "    bool goodCustom3 = (customAttribute3 == 3 || customAttribute3 == 4);\n"
		<< "    bool goodCustom4 = ((gl_PrimitiveID == 1000 && customAttribute4 == uvec4(100, 101, 102, 103)) ||\n"
		<< "                        (gl_PrimitiveID == 1001 && customAttribute4 == uvec4(200, 201, 202, 203)));\n"
		<< "    bool goodCustom5 = ((gl_PrimitiveID == 1000 && customAttribute5 == 6.0) ||\n"
		<< "                        (gl_PrimitiveID == 1001 && customAttribute5 == 7.0));\n"
		<< "    \n"
		<< "    if (goodPrimitiveID && goodViewportIndex && goodCustom1 && goodCustom2 && goodCustom3 && goodCustom4 && goodCustom5) {\n"
		<< "        outColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
		<< "    } else {\n"
		<< "        outColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
		<< "    }\n"
		<< "}\n"
		;
	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());

	std::ostringstream pvdDataDeclStream;
	pvdDataDeclStream
		<< "    vec4 positions[4];\n"
		<< "    float pointSizes[4];\n"
		<< "    float clipDistances[4];\n"
		<< "    vec4 custom1[4];\n"
		<< "    float custom2[4];\n"
		<< "    int custom3[4];\n"
		;
	const auto pvdDataDecl = pvdDataDeclStream.str();

	std::ostringstream ppdDataDeclStream;
	ppdDataDeclStream
		<< "    int primitiveIds[2];\n"
		<< "    int viewportIndices[2];\n"
		<< "    uvec4 custom4[2];\n"
		<< "    float custom5[2];\n"
		;
	const auto ppdDataDecl = ppdDataDeclStream.str();

	std::ostringstream bindingsDeclStream;
	bindingsDeclStream
		<< "layout (set=0, binding=0, std430) buffer PerVertexData {\n"
		<< pvdDataDecl
		<< "} pvd;\n"
		<< "layout (set=0, binding=1) uniform PerPrimitiveData {\n"
		<< ppdDataDecl
		<< "} ppd;\n"
		<< "\n"
		;
	const auto bindingsDecl = bindingsDeclStream.str();

	std::ostringstream taskDataStream;
	taskDataStream
		<< "taskNV TaskData {\n"
		<< pvdDataDecl
		<< ppdDataDecl
		<< "} td;\n"
		<< "\n"
		;
	const auto taskDataDecl = taskDataStream.str();

	const auto taskShader = m_params->needsTaskShader();

	const auto meshPvdPrefix = (taskShader ? "td" : "pvd");
	const auto meshPpdPrefix = (taskShader ? "td" : "ppd");

	std::ostringstream mesh;
	mesh
		<< "#version 450\n"
		<< "#extension GL_NV_mesh_shader : enable\n"
		<< "\n"
		<< "layout (local_size_x=1) in;\n"
		<< "layout (max_primitives=2, max_vertices=4) out;\n"
		<< "layout (triangles) out;\n"
		<< "\n"
		<< "out gl_MeshPerVertexNV {\n"
		<< "    vec4  gl_Position;\n"
		<< "    float gl_PointSize;\n"
		<< "    float gl_ClipDistance[1];\n"
		<< "} gl_MeshVerticesNV[];\n"
		<< "\n"
		<< "layout (location=0) out vec4 customAttribute1[];\n"
		<< "layout (location=1) out flat float customAttribute2[];\n"
		<< "layout (location=2) out int customAttribute3[];\n"
		<< "\n"
		<< "layout (location=3) out perprimitiveNV uvec4 customAttribute4[];\n"
		<< "layout (location=4) out perprimitiveNV float customAttribute5[];\n"
		<< "\n"
		<< "out perprimitiveNV gl_MeshPerPrimitiveNV {\n"
		<< "  int gl_PrimitiveID;\n"
		<< "  int gl_ViewportIndex;\n"
		<< "} gl_MeshPrimitivesNV[];\n"
		<< "\n"
		<< (taskShader ? "in " + taskDataDecl : bindingsDecl)
		<< "void main ()\n"
		<< "{\n"
		<< "    gl_PrimitiveCountNV = 2u;\n"
		<< "\n"
		<< "    gl_MeshVerticesNV[0].gl_Position = " << meshPvdPrefix << ".positions[0]; //vec4(-1.0, -1.0, 0.0, 1.0)\n"
		<< "    gl_MeshVerticesNV[1].gl_Position = " << meshPvdPrefix << ".positions[1]; //vec4( 1.0, -1.0, 0.0, 1.0)\n"
		<< "    gl_MeshVerticesNV[2].gl_Position = " << meshPvdPrefix << ".positions[2]; //vec4(-1.0,  1.0, 0.0, 1.0)\n"
		<< "    gl_MeshVerticesNV[3].gl_Position = " << meshPvdPrefix << ".positions[3]; //vec4( 1.0,  1.0, 0.0, 1.0)\n"
		<< "\n"
		<< "    gl_MeshVerticesNV[0].gl_PointSize = " << meshPvdPrefix << ".pointSizes[0]; //1.0\n"
		<< "    gl_MeshVerticesNV[1].gl_PointSize = " << meshPvdPrefix << ".pointSizes[1]; //1.0\n"
		<< "    gl_MeshVerticesNV[2].gl_PointSize = " << meshPvdPrefix << ".pointSizes[2]; //1.0\n"
		<< "    gl_MeshVerticesNV[3].gl_PointSize = " << meshPvdPrefix << ".pointSizes[3]; //1.0\n"
		<< "\n"
		<< "    // Remove geometry on the right side.\n"
		<< "    gl_MeshVerticesNV[0].gl_ClipDistance[0] = " << meshPvdPrefix << ".clipDistances[0]; // 1.0\n"
		<< "    gl_MeshVerticesNV[1].gl_ClipDistance[0] = " << meshPvdPrefix << ".clipDistances[1]; //-1.0\n"
		<< "    gl_MeshVerticesNV[2].gl_ClipDistance[0] = " << meshPvdPrefix << ".clipDistances[2]; // 1.0\n"
		<< "    gl_MeshVerticesNV[3].gl_ClipDistance[0] = " << meshPvdPrefix << ".clipDistances[3]; //-1.0\n"
		<< "    \n"
		<< "    gl_PrimitiveIndicesNV[0] = 0;\n"
		<< "    gl_PrimitiveIndicesNV[1] = 2;\n"
		<< "    gl_PrimitiveIndicesNV[2] = 1;\n"
		<< "\n"
		<< "    gl_PrimitiveIndicesNV[3] = 2;\n"
		<< "    gl_PrimitiveIndicesNV[4] = 3;\n"
		<< "    gl_PrimitiveIndicesNV[5] = 1;\n"
		<< "\n"
		<< "    gl_MeshPrimitivesNV[0].gl_PrimitiveID = " << meshPpdPrefix << ".primitiveIds[0]; //1000\n"
		<< "    gl_MeshPrimitivesNV[1].gl_PrimitiveID = " << meshPpdPrefix << ".primitiveIds[1]; //1001\n"
		<< "\n"
		<< "    gl_MeshPrimitivesNV[0].gl_ViewportIndex = " << meshPpdPrefix << ".viewportIndices[0]; //1\n"
		<< "    gl_MeshPrimitivesNV[1].gl_ViewportIndex = " << meshPpdPrefix << ".viewportIndices[1]; //1\n"
		<< "\n"
		<< "    // Custom per-vertex attributes\n"
		<< "    customAttribute1[0] = " << meshPvdPrefix << ".custom1[0]; //vec4(0.25, 0.5, 10.0, 3.0)\n"
		<< "    customAttribute1[1] = " << meshPvdPrefix << ".custom1[1]; //vec4(0.25, 1.0, 20.0, 3.0)\n"
		<< "    customAttribute1[2] = " << meshPvdPrefix << ".custom1[2]; //vec4( 0.5, 0.5, 20.0, 3.0)\n"
		<< "    customAttribute1[3] = " << meshPvdPrefix << ".custom1[3]; //vec4( 0.5, 1.0, 10.0, 3.0)\n"
		<< "\n"
		<< "    customAttribute2[0] = " << meshPvdPrefix << ".custom2[0]; //1.0f\n"
		<< "    customAttribute2[1] = " << meshPvdPrefix << ".custom2[1]; //1.0f\n"
		<< "    customAttribute2[2] = " << meshPvdPrefix << ".custom2[2]; //2.0f\n"
		<< "    customAttribute2[3] = " << meshPvdPrefix << ".custom2[3]; //2.0f\n"
		<< "\n"
		<< "    customAttribute3[0] = " << meshPvdPrefix << ".custom3[0]; //3\n"
		<< "    customAttribute3[1] = " << meshPvdPrefix << ".custom3[1]; //3\n"
		<< "    customAttribute3[2] = " << meshPvdPrefix << ".custom3[2]; //4\n"
		<< "    customAttribute3[3] = " << meshPvdPrefix << ".custom3[3]; //4\n"
		<< "\n"
		<< "    // Custom per-primitive attributes.\n"
		<< "    customAttribute4[0] = " << meshPpdPrefix << ".custom4[0]; //uvec4(100, 101, 102, 103)\n"
		<< "    customAttribute4[1] = " << meshPpdPrefix << ".custom4[1]; //uvec4(200, 201, 202, 203)\n"
		<< "\n"
		<< "    customAttribute5[0] = " << meshPpdPrefix << ".custom5[0]; //6.0\n"
		<< "    customAttribute5[1] = " << meshPpdPrefix << ".custom5[1]; //7.0\n"
		<< "}\n"
		;
	programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());

	if (taskShader)
	{
		std::ostringstream task;
		task
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "out " << taskDataDecl
			<< bindingsDecl
			<< "void main ()\n"
			<< "{\n"
			<< "    gl_TaskCountNV = " << m_params->meshCount << ";\n"
			<< "\n"
			<< "    td.positions[0] = pvd.positions[0];\n"
			<< "    td.positions[1] = pvd.positions[1];\n"
			<< "    td.positions[2] = pvd.positions[2];\n"
			<< "    td.positions[3] = pvd.positions[3];\n"
			<< "\n"
			<< "    td.pointSizes[0] = pvd.pointSizes[0];\n"
			<< "    td.pointSizes[1] = pvd.pointSizes[1];\n"
			<< "    td.pointSizes[2] = pvd.pointSizes[2];\n"
			<< "    td.pointSizes[3] = pvd.pointSizes[3];\n"
			<< "\n"
			<< "    td.clipDistances[0] = pvd.clipDistances[0];\n"
			<< "    td.clipDistances[1] = pvd.clipDistances[1];\n"
			<< "    td.clipDistances[2] = pvd.clipDistances[2];\n"
			<< "    td.clipDistances[3] = pvd.clipDistances[3];\n"
			<< "\n"
			<< "    td.custom1[0] = pvd.custom1[0];\n"
			<< "    td.custom1[1] = pvd.custom1[1];\n"
			<< "    td.custom1[2] = pvd.custom1[2];\n"
			<< "    td.custom1[3] = pvd.custom1[3];\n"
			<< "\n"
			<< "    td.custom2[0] = pvd.custom2[0];\n"
			<< "    td.custom2[1] = pvd.custom2[1];\n"
			<< "    td.custom2[2] = pvd.custom2[2];\n"
			<< "    td.custom2[3] = pvd.custom2[3];\n"
			<< "\n"
			<< "    td.custom3[0] = pvd.custom3[0];\n"
			<< "    td.custom3[1] = pvd.custom3[1];\n"
			<< "    td.custom3[2] = pvd.custom3[2];\n"
			<< "    td.custom3[3] = pvd.custom3[3];\n"
			<< "\n"
			<< "    td.primitiveIds[0] = ppd.primitiveIds[0];\n"
			<< "    td.primitiveIds[1] = ppd.primitiveIds[1];\n"
			<< "\n"
			<< "    td.viewportIndices[0] = ppd.viewportIndices[0];\n"
			<< "    td.viewportIndices[1] = ppd.viewportIndices[1];\n"
			<< "\n"
			<< "    td.custom4[0] = ppd.custom4[0];\n"
			<< "    td.custom4[1] = ppd.custom4[1];\n"
			<< "\n"
			<< "    td.custom5[0] = ppd.custom5[0];\n"
			<< "    td.custom5[1] = ppd.custom5[1];\n"
			<< "}\n"
			;
		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
	}
}

void CustomAttributesInstance::generateReferenceLevel ()
{
	const auto format		= getOutputFormat();
	const auto tcuFormat	= mapVkFormat(format);

	const auto iWidth		= static_cast<int>(m_params->width);
	const auto iHeight		= static_cast<int>(m_params->height);

	const auto halfWidth	= iWidth / 2;
	const auto halfHeight	= iHeight / 2;

	m_referenceLevel.reset(new tcu::TextureLevel(tcuFormat, iWidth, iHeight));

	const auto access		= m_referenceLevel->getAccess();
	const auto clearColor	= tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	const auto blueColor	= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);

	tcu::clear(access, clearColor);

	// Fill the top left quarter.
	for (int y = 0; y < halfWidth; ++y)
	for (int x = 0; x < halfHeight; ++x)
	{
		access.setPixel(blueColor, x, y);
	}
}

tcu::TestStatus CustomAttributesInstance::iterate ()
{
	struct PerVertexData
	{
		tcu::Vec4	positions[4];
		float		pointSizes[4];
		float		clipDistances[4];
		tcu::Vec4	custom1[4];
		float		custom2[4];
		int32_t		custom3[4];
	};

	struct PerPrimitiveData
	{
		// Note some of these are declared as vectors to match the std140 layout.
		tcu::IVec4	primitiveIds[2];
		tcu::IVec4	viewportIndices[2];
		tcu::UVec4	custom4[2];
		tcu::Vec4	custom5[2];
	};

	const auto&		vkd			= m_context.getDeviceInterface();
	const auto		device		= m_context.getDevice();
	auto&			alloc		= m_context.getDefaultAllocator();
	const auto		queueIndex	= m_context.getUniversalQueueFamilyIndex();
	const auto		queue		= m_context.getUniversalQueue();

	const auto		imageFormat	= getOutputFormat();
	const auto		tcuFormat	= mapVkFormat(imageFormat);
	const auto		imageExtent	= makeExtent3D(m_params->width, m_params->height, 1u);
	const auto		imageUsage	= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);

	const auto&		binaries	= m_context.getBinaryCollection();
	const auto		hasTask		= binaries.contains("task");
	const auto		bufStages	= (hasTask ? VK_SHADER_STAGE_TASK_BIT_NV : VK_SHADER_STAGE_MESH_BIT_NV);

	const VkImageCreateInfo colorBufferInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,								//	const void*				pNext;
		0u,										//	VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		imageFormat,							//	VkFormat				format;
		imageExtent,							//	VkExtent3D				extent;
		1u,										//	uint32_t				mipLevels;
		1u,										//	uint32_t				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		imageUsage,								//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		0u,										//	uint32_t				queueFamilyIndexCount;
		nullptr,								//	const uint32_t*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};

	// Create color image and view.
	ImageWithMemory	colorImage	(vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
	const auto		colorSRR	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto		colorSRL	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const auto		colorView	= makeImageView(vkd, device, colorImage.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, colorSRR);

	// Create a memory buffer for verification.
	const auto			verificationBufferSize	= static_cast<VkDeviceSize>(imageExtent.width * imageExtent.height * tcu::getPixelSize(tcuFormat));
	const auto			verificationBufferUsage	= (VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const auto			verificationBufferInfo	= makeBufferCreateInfo(verificationBufferSize, verificationBufferUsage);

	BufferWithMemory	verificationBuffer		(vkd, device, alloc, verificationBufferInfo, MemoryRequirement::HostVisible);
	auto&				verificationBufferAlloc	= verificationBuffer.getAllocation();
	void*				verificationBufferData	= verificationBufferAlloc.getHostPtr();

	// This needs to match what the fragment shader will expect.
	const PerVertexData perVertexData =
	{
		//	tcu::Vec4	positions[4];
		{
			tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
			tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
			tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
			tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
		},
		//	float		pointSizes[4];
		{ 1.0f, 1.0f, 1.0f, 1.0f, },
		//	float		clipDistances[4];
		{
			1.0f,
			-1.0f,
			1.0f,
			-1.0f,
		},
		//	tcu::Vec4	custom1[4];
		{
			tcu::Vec4(0.25, 0.5, 10.0, 3.0),
			tcu::Vec4(0.25, 1.0, 20.0, 3.0),
			tcu::Vec4( 0.5, 0.5, 20.0, 3.0),
			tcu::Vec4( 0.5, 1.0, 10.0, 3.0),
		},
		//	float		custom2[4];
		{ 1.0f, 1.0f, 2.0f, 2.0f, },
		//	int32_t		custom3[4];
		{ 3, 3, 4, 4 },
	};

	// This needs to match what the fragment shader will expect. Reminder: some of these are declared as gvec4 to match the std140
	// layout, but only the first component is actually used.
	const PerPrimitiveData perPrimitiveData =
	{
		//	int			primitiveIds[2];
		{
			tcu::IVec4(1000, 0, 0, 0),
			tcu::IVec4(1001, 0, 0, 0),
		},
		//	int			viewportIndices[2];
		{
			tcu::IVec4(1, 0, 0, 0),
			tcu::IVec4(1, 0, 0, 0),
		},
		//	uvec4		custom4[2];
		{
			tcu::UVec4(100u, 101u, 102u, 103u),
			tcu::UVec4(200u, 201u, 202u, 203u),
		},
		//	float		custom5[2];
		{
			tcu::Vec4(6.0f, 0.0f, 0.0f, 0.0f),
			tcu::Vec4(7.0f, 0.0f, 0.0f, 0.0f),
		},
	};

	// Create and fill buffers with this data.
	const auto			pvdSize		= static_cast<VkDeviceSize>(sizeof(perVertexData));
	const auto			pvdInfo		= makeBufferCreateInfo(pvdSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
	BufferWithMemory	pvdData		(vkd, device, alloc, pvdInfo, MemoryRequirement::HostVisible);
	auto&				pvdAlloc	= pvdData.getAllocation();
	void*				pvdPtr		= pvdAlloc.getHostPtr();

	const auto			ppdSize		= static_cast<VkDeviceSize>(sizeof(perPrimitiveData));
	const auto			ppdInfo		= makeBufferCreateInfo(ppdSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
	BufferWithMemory	ppdData		(vkd, device, alloc, ppdInfo, MemoryRequirement::HostVisible);
	auto&				ppdAlloc	= ppdData.getAllocation();
	void*				ppdPtr		= ppdAlloc.getHostPtr();

	deMemcpy(pvdPtr, &perVertexData, sizeof(perVertexData));
	deMemcpy(ppdPtr, &perPrimitiveData, sizeof(perPrimitiveData));

	flushAlloc(vkd, device, pvdAlloc);
	flushAlloc(vkd, device, ppdAlloc);

	// Descriptor set layout.
	DescriptorSetLayoutBuilder setLayoutBuilder;
	setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, bufStages);
	setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, bufStages);
	const auto setLayout = setLayoutBuilder.build(vkd, device);

	// Create and update descriptor set.
	DescriptorPoolBuilder descriptorPoolBuilder;
	descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
	descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
	const auto descriptorPool	= descriptorPoolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	const auto descriptorSet	= makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get());

	DescriptorSetUpdateBuilder updateBuilder;
	const auto storageBufferInfo = makeDescriptorBufferInfo(pvdData.get(), 0ull, pvdSize);
	const auto uniformBufferInfo = makeDescriptorBufferInfo(ppdData.get(), 0ull, ppdSize);
	updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &storageBufferInfo);
	updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferInfo);
	updateBuilder.update(vkd, device);

	// Pipeline layout.
	const auto pipelineLayout = makePipelineLayout(vkd, device, setLayout.get());

	// Shader modules.
	const auto	meshShader	= createShaderModule(vkd, device, binaries.get("mesh"));
	const auto	fragShader	= createShaderModule(vkd, device, binaries.get("frag"));

	Move<VkShaderModule> taskShader;
	if (hasTask)
		taskShader = createShaderModule(vkd, device, binaries.get("task"));

	// Render pass.
	const auto renderPass = makeRenderPass(vkd, device, imageFormat);

	// Framebuffer.
	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorView.get(), imageExtent.width, imageExtent.height);

	// Viewport and scissor.
	const auto						topHalf		= makeViewport(imageExtent.width, imageExtent.height / 2u);
	const std::vector<VkViewport>	viewports	{ makeViewport(imageExtent), topHalf };
	const std::vector<VkRect2D>		scissors	(2u, makeRect2D(imageExtent));

	const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
		taskShader.get(), meshShader.get(), fragShader.get(),
		renderPass.get(), viewports, scissors);

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

	beginCommandBuffer(vkd, cmdBuffer);

	// Run pipeline.
	const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 0.0f);
	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0u), clearColor);
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
	vkd.cmdDrawMeshTasksNV(cmdBuffer, m_params->drawCount(), 0u);
	endRenderPass(vkd, cmdBuffer);

	// Copy color buffer to verification buffer.
	const auto colorAccess		= (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
	const auto transferRead		= VK_ACCESS_TRANSFER_READ_BIT;
	const auto transferWrite	= VK_ACCESS_TRANSFER_WRITE_BIT;
	const auto hostRead			= VK_ACCESS_HOST_READ_BIT;

	const auto preCopyBarrier	= makeImageMemoryBarrier(colorAccess, transferRead, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorImage.get(), colorSRR);
	const auto postCopyBarrier	= makeMemoryBarrier(transferWrite, hostRead);
	const auto copyRegion		= makeBufferImageCopy(imageExtent, colorSRL);

	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &preCopyBarrier);
	vkd.cmdCopyImageToBuffer(cmdBuffer, colorImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, &copyRegion);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &postCopyBarrier, 0u, nullptr, 0u, nullptr);

	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Generate reference image and compare results.
	const tcu::IVec3					iExtent				(static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height), 1);
	const tcu::ConstPixelBufferAccess	verificationAccess	(tcuFormat, iExtent, verificationBufferData);

	generateReferenceLevel();
	invalidateAlloc(vkd, device, verificationBufferAlloc);
	if (!verifyResult(verificationAccess))
		TCU_FAIL("Result does not match reference; check log for details");

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

// Tests that use push constants in the new stages.
class PushConstantCase : public MeshShaderMiscCase
{
public:
					PushConstantCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, ParamsPtr params)
						: MeshShaderMiscCase (testCtx, name, description, std::move(params))
					{}

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

class PushConstantInstance : public MeshShaderMiscInstance
{
public:
	PushConstantInstance (Context& context, const MiscTestParams* params)
		: MeshShaderMiscInstance (context, params)
	{}

	void			generateReferenceLevel	() override;
	tcu::TestStatus	iterate					() override;
};

TestInstance* PushConstantCase::createInstance (Context& context) const
{
	return new PushConstantInstance(context, m_params.get());
}

void PushConstantInstance::generateReferenceLevel ()
{
	generateSolidRefLevel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), m_referenceLevel);
}

void PushConstantCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const auto useTaskShader	= m_params->needsTaskShader();
	const auto pcNumFloats		= (useTaskShader ? 2u : 4u);

	std::ostringstream pushConstantStream;
	pushConstantStream
		<< "layout (push_constant, std430) uniform PushConstantBlock {\n"
		<< "    layout (offset=${PCOFFSET}) float values[" << pcNumFloats << "];\n"
		<< "} pc;\n"
		<< "\n"
		;
	const tcu::StringTemplate pushConstantsTemplate (pushConstantStream.str());
	using TemplateMap = std::map<std::string, std::string>;

	std::ostringstream taskDataStream;
	taskDataStream
		<< "taskNV TaskData {\n"
		<< "    float values[2];\n"
		<< "} td;\n"
		<< "\n"
		;
	const auto taskDataDecl = taskDataStream.str();

	if (useTaskShader)
	{
		TemplateMap taskMap;
		taskMap["PCOFFSET"] = std::to_string(2u * sizeof(float));

		std::ostringstream task;
		task
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout(local_size_x=1) in;\n"
			<< "\n"
			<< "out " << taskDataDecl
			<< pushConstantsTemplate.specialize(taskMap)
			<< "void main ()\n"
			<< "{\n"
			<< "    gl_TaskCountNV = " << m_params->meshCount << ";\n"
			<< "\n"
			<< "    td.values[0] = pc.values[0];\n"
			<< "    td.values[1] = pc.values[1];\n"
			<< "}\n"
			;
		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
	}

	{
		const std::string blue	= (useTaskShader ? "td.values[0] + pc.values[0]" : "pc.values[0] + pc.values[2]");
		const std::string alpha	= (useTaskShader ? "td.values[1] + pc.values[1]" : "pc.values[1] + pc.values[3]");

		TemplateMap meshMap;
		meshMap["PCOFFSET"] = "0";

		std::ostringstream mesh;
		mesh
			<< "#version 450\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout(local_size_x=1) in;\n"
			<< "layout(triangles) out;\n"
			<< "layout(max_vertices=3, max_primitives=1) out;\n"
			<< "\n"
			<< "layout (location=0) out perprimitiveNV vec4 triangleColor[];\n"
			<< "\n"
			<< pushConstantsTemplate.specialize(meshMap)
			<< (useTaskShader ? "in " + taskDataDecl : "")
			<< "void main ()\n"
			<< "{\n"
			<< "    gl_PrimitiveCountNV = 1;\n"
			<< "\n"
			<< "    gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
			<< "    gl_MeshVerticesNV[1].gl_Position = vec4( 3.0, -1.0, 0.0, 1.0);\n"
			<< "    gl_MeshVerticesNV[2].gl_Position = vec4(-1.0,  3.0, 0.0, 1.0);\n"
			<< "\n"
			<< "    gl_PrimitiveIndicesNV[0] = 0;\n"
			<< "    gl_PrimitiveIndicesNV[1] = 1;\n"
			<< "    gl_PrimitiveIndicesNV[2] = 2;\n"
			<< "\n"
			<< "    triangleColor[0] = vec4(0.0, 0.0, " << blue << ", " << alpha << ");\n"
			<< "}\n"
			;
		programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
	}

	// Add default fragment shader.
	MeshShaderMiscCase::initPrograms(programCollection);
}

tcu::TestStatus PushConstantInstance::iterate ()
{
	const auto&		vkd			= m_context.getDeviceInterface();
	const auto		device		= m_context.getDevice();
	auto&			alloc		= m_context.getDefaultAllocator();
	const auto		queueIndex	= m_context.getUniversalQueueFamilyIndex();
	const auto		queue		= m_context.getUniversalQueue();

	const auto		imageFormat	= getOutputFormat();
	const auto		tcuFormat	= mapVkFormat(imageFormat);
	const auto		imageExtent	= makeExtent3D(m_params->width, m_params->height, 1u);
	const auto		imageUsage	= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);

	const auto&		binaries	= m_context.getBinaryCollection();
	const auto		hasTask		= binaries.contains("task");

	const VkImageCreateInfo colorBufferInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,								//	const void*				pNext;
		0u,										//	VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		imageFormat,							//	VkFormat				format;
		imageExtent,							//	VkExtent3D				extent;
		1u,										//	uint32_t				mipLevels;
		1u,										//	uint32_t				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		imageUsage,								//	VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		0u,										//	uint32_t				queueFamilyIndexCount;
		nullptr,								//	const uint32_t*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};

	// Create color image and view.
	ImageWithMemory	colorImage	(vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
	const auto		colorSRR	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto		colorSRL	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const auto		colorView	= makeImageView(vkd, device, colorImage.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, colorSRR);

	// Create a memory buffer for verification.
	const auto			verificationBufferSize	= static_cast<VkDeviceSize>(imageExtent.width * imageExtent.height * tcu::getPixelSize(tcuFormat));
	const auto			verificationBufferUsage	= (VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const auto			verificationBufferInfo	= makeBufferCreateInfo(verificationBufferSize, verificationBufferUsage);

	BufferWithMemory	verificationBuffer		(vkd, device, alloc, verificationBufferInfo, MemoryRequirement::HostVisible);
	auto&				verificationBufferAlloc	= verificationBuffer.getAllocation();
	void*				verificationBufferData	= verificationBufferAlloc.getHostPtr();

	// Push constant ranges.
	std::vector<float> pcData { 0.25f, 0.25f, 0.75f, 0.75f };
	const auto pcSize		= static_cast<uint32_t>(de::dataSize(pcData));
	const auto pcHalfSize	= pcSize / 2u;

	std::vector<VkPushConstantRange> pcRanges;
	if (hasTask)
	{
		pcRanges.push_back(makePushConstantRange(VK_SHADER_STAGE_MESH_BIT_NV, 0u, pcHalfSize));
		pcRanges.push_back(makePushConstantRange(VK_SHADER_STAGE_TASK_BIT_NV, pcHalfSize, pcHalfSize));
	}
	else
	{
		pcRanges.push_back(makePushConstantRange(VK_SHADER_STAGE_MESH_BIT_NV, 0u, pcSize));
	}

	// Pipeline layout.
	const auto pipelineLayout = makePipelineLayout(vkd, device, 0u, nullptr, static_cast<uint32_t>(pcRanges.size()), de::dataOrNull(pcRanges));

	// Shader modules.
	const auto	meshShader	= createShaderModule(vkd, device, binaries.get("mesh"));
	const auto	fragShader	= createShaderModule(vkd, device, binaries.get("frag"));

	Move<VkShaderModule> taskShader;
	if (hasTask)
		taskShader = createShaderModule(vkd, device, binaries.get("task"));

	// Render pass.
	const auto renderPass = makeRenderPass(vkd, device, imageFormat);

	// Framebuffer.
	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorView.get(), imageExtent.width, imageExtent.height);

	// Viewport and scissor.
	const std::vector<VkViewport>	viewports	(1u, makeViewport(imageExtent));
	const std::vector<VkRect2D>		scissors	(1u, makeRect2D(imageExtent));

	const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
		taskShader.get(), meshShader.get(), fragShader.get(),
		renderPass.get(), viewports, scissors);

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

	beginCommandBuffer(vkd, cmdBuffer);

	// Run pipeline.
	const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 0.0f);
	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0u), clearColor);
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
	for (const auto& range : pcRanges)
		vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), range.stageFlags, range.offset, range.size, reinterpret_cast<const char*>(pcData.data()) + range.offset);
	vkd.cmdDrawMeshTasksNV(cmdBuffer, m_params->drawCount(), 0u);
	endRenderPass(vkd, cmdBuffer);

	// Copy color buffer to verification buffer.
	const auto colorAccess		= (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
	const auto transferRead		= VK_ACCESS_TRANSFER_READ_BIT;
	const auto transferWrite	= VK_ACCESS_TRANSFER_WRITE_BIT;
	const auto hostRead			= VK_ACCESS_HOST_READ_BIT;

	const auto preCopyBarrier	= makeImageMemoryBarrier(colorAccess, transferRead, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorImage.get(), colorSRR);
	const auto postCopyBarrier	= makeMemoryBarrier(transferWrite, hostRead);
	const auto copyRegion		= makeBufferImageCopy(imageExtent, colorSRL);

	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &preCopyBarrier);
	vkd.cmdCopyImageToBuffer(cmdBuffer, colorImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, &copyRegion);
	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &postCopyBarrier, 0u, nullptr, 0u, nullptr);

	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Generate reference image and compare results.
	const tcu::IVec3					iExtent				(static_cast<int>(imageExtent.width), static_cast<int>(imageExtent.height), 1);
	const tcu::ConstPixelBufferAccess	verificationAccess	(tcuFormat, iExtent, verificationBufferData);

	generateReferenceLevel();
	invalidateAlloc(vkd, device, verificationBufferAlloc);
	if (!verifyResult(verificationAccess))
		TCU_FAIL("Result does not match reference; check log for details");

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

}

tcu::TestCaseGroup* createMeshShaderMiscTests (tcu::TestContext& testCtx)
{
	GroupPtr miscTests (new tcu::TestCaseGroup(testCtx, "misc", "Mesh Shader Misc Tests"));

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::just(2u);
		paramsPtr->meshCount	= 2u;
		paramsPtr->width		= 8u;
		paramsPtr->height		= 8u;

		miscTests->addChild(new ComplexTaskDataCase(testCtx, "complex_task_data", "Pass a complex structure from the task to the mesh shader", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 5u;	// Use an odd value so there's a pixel in the exact center.
		paramsPtr->height		= 7u;	// Idem.

		miscTests->addChild(new SinglePointCase(testCtx, "single_point", "Draw a single point", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 8u;
		paramsPtr->height		= 5u;	// Use an odd value so there's a center line.

		miscTests->addChild(new SingleLineCase(testCtx, "single_line", "Draw a single line", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 5u;	// Use an odd value so there's a pixel in the exact center.
		paramsPtr->height		= 7u;	// Idem.

		miscTests->addChild(new SingleTriangleCase(testCtx, "single_triangle", "Draw a single triangle", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 16u;
		paramsPtr->height		= 16u;

		miscTests->addChild(new MaxPointsCase(testCtx, "max_points", "Draw the maximum number of points", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 1u;
		paramsPtr->height		= 1020u;

		miscTests->addChild(new MaxLinesCase(testCtx, "max_lines", "Draw the maximum number of lines", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 512u;
		paramsPtr->height		= 512u;

		miscTests->addChild(new MaxTrianglesCase(testCtx, "max_triangles", "Draw the maximum number of triangles", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::just(65535u);
		paramsPtr->meshCount	= 1u;
		paramsPtr->width		= 1360u;
		paramsPtr->height		= 1542u;

		miscTests->addChild(new LargeWorkGroupCase(testCtx, "many_task_work_groups", "Generate a large number of task work groups", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::nothing<uint32_t>();
		paramsPtr->meshCount	= 65535u;
		paramsPtr->width		= 1360u;
		paramsPtr->height		= 1542u;

		miscTests->addChild(new LargeWorkGroupCase(testCtx, "many_mesh_work_groups", "Generate a large number of mesh work groups", std::move(paramsPtr)));
	}

	{
		ParamsPtr paramsPtr (new MiscTestParams);

		paramsPtr->taskCount	= tcu::just(512u);
		paramsPtr->meshCount	= 512u;
		paramsPtr->width		= 4096u;
		paramsPtr->height		= 2048u;

		miscTests->addChild(new LargeWorkGroupCase(testCtx, "many_task_mesh_work_groups", "Generate a large number of task and mesh work groups", std::move(paramsPtr)));
	}

	{
		const PrimitiveType types[] = {
			PrimitiveType::POINTS,
			PrimitiveType::LINES,
			PrimitiveType::TRIANGLES,
		};

		for (int i = 0; i < 2; ++i)
		{
			const bool extraWrites = (i > 0);

			for (const auto primType : types)
			{
				std::unique_ptr<NoPrimitivesParams> params (new NoPrimitivesParams);
				params->taskCount		= (extraWrites ? tcu::just(1u) : tcu::nothing<uint32_t>());
				params->meshCount		= 1u;
				params->width			= 16u;
				params->height			= 16u;
				params->primitiveType	= primType;

				ParamsPtr			paramsPtr	(params.release());
				const auto			primName	= primitiveTypeName(primType);
				const std::string	name		= "no_" + primName + (extraWrites ? "_extra_writes" : "");
				const std::string	desc		= "Run a pipeline that generates no " + primName + (extraWrites ? " but generates primitive data" : "");

				miscTests->addChild(extraWrites
					? (new NoPrimitivesExtraWritesCase(testCtx, name, desc, std::move(paramsPtr)))
					: (new NoPrimitivesCase(testCtx, name, desc, std::move(paramsPtr))));
			}
		}
	}

	{
		for (int i = 0; i < 2; ++i)
		{
			const bool useTaskShader = (i == 0);

			ParamsPtr paramsPtr (new MiscTestParams);

			paramsPtr->taskCount		= (useTaskShader ? tcu::just(1u) : tcu::nothing<uint32_t>());
			paramsPtr->meshCount		= 1u;
			paramsPtr->width			= 1u;
			paramsPtr->height			= 1u;

			const std::string shader	= (useTaskShader ? "task" : "mesh");
			const std::string name		= "barrier_in_" + shader;
			const std::string desc		= "Use a control barrier in the " + shader + " shader";

			miscTests->addChild(new SimpleBarrierCase(testCtx, name, desc, std::move(paramsPtr)));
		}
	}

	{
		const struct
		{
			MemoryBarrierType	memBarrierType;
			std::string			caseName;
		} barrierTypes[] =
		{
			{ MemoryBarrierType::SHARED,	"memory_barrier_shared"	},
			{ MemoryBarrierType::GROUP,		"group_memory_barrier"	},
		};

		for (const auto& barrierCase : barrierTypes)
		{
			for (int i = 0; i < 2; ++i)
			{
				const bool useTaskShader = (i == 0);

				std::unique_ptr<MemoryBarrierParams> paramsPtr (new MemoryBarrierParams);

				paramsPtr->taskCount		= (useTaskShader ? tcu::just(1u) : tcu::nothing<uint32_t>());
				paramsPtr->meshCount		= 1u;
				paramsPtr->width			= 1u;
				paramsPtr->height			= 1u;
				paramsPtr->memBarrierType	= barrierCase.memBarrierType;

				const std::string shader	= (useTaskShader ? "task" : "mesh");
				const std::string name		= barrierCase.caseName + "_in_" + shader;
				const std::string desc		= "Use " + paramsPtr->glslFunc() + "() in the " + shader + " shader";

				miscTests->addChild(new MemoryBarrierCase(testCtx, name, desc, std::move(paramsPtr)));
			}
		}
	}

	{
		for (int i = 0; i < 2; ++i)
		{
			const bool useTaskShader	= (i > 0);
			const auto name				= std::string("custom_attributes") + (useTaskShader ? "_and_task_shader" : "");
			const auto desc				= std::string("Use several custom vertex and primitive attributes") + (useTaskShader ? " and also a task shader" : "");

			ParamsPtr paramsPtr (new MiscTestParams);

			paramsPtr->taskCount		= (useTaskShader ? tcu::just(1u) : tcu::nothing<uint32_t>());
			paramsPtr->meshCount		= 1u;
			paramsPtr->width			= 32u;
			paramsPtr->height			= 32u;

			miscTests->addChild(new CustomAttributesCase(testCtx, name, desc, std::move(paramsPtr)));
		}
	}

	{
		for (int i = 0; i < 2; ++i)
		{
			const bool useTaskShader	= (i > 0);
			const auto name				= std::string("push_constant") + (useTaskShader ? "_and_task_shader" : "");
			const auto desc				= std::string("Use push constants in the mesh shader stage") + (useTaskShader ? " and also in the task shader stage" : "");

			ParamsPtr paramsPtr (new MiscTestParams);

			paramsPtr->taskCount		= (useTaskShader ? tcu::just(1u) : tcu::nothing<uint32_t>());
			paramsPtr->meshCount		= 1u;
			paramsPtr->width			= 16u;
			paramsPtr->height			= 16u;

			miscTests->addChild(new PushConstantCase(testCtx, name, desc, std::move(paramsPtr)));
		}
	}

	return miscTests.release();
}

} // MeshShader
} // vkt
