/*------------------------------------------------------------------------
 * 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 API Tests
 *//*--------------------------------------------------------------------*/

#include "vktMeshShaderApiTests.hpp"
#include "vktTestCase.hpp"

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

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

#include "deRandom.hpp"

#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <limits>

namespace vkt
{
namespace MeshShader
{

namespace
{

using namespace vk;

using GroupPtr				= de::MovePtr<tcu::TestCaseGroup>;
using ImageWithMemoryPtr	= de::MovePtr<ImageWithMemory>;
using BufferWithMemoryPtr	= de::MovePtr<BufferWithMemory>;

enum class DrawType
{
	DRAW = 0,
	DRAW_INDIRECT,
	DRAW_INDIRECT_COUNT,
};

std::ostream& operator<< (std::ostream& stream, DrawType drawType)
{
	switch (drawType)
	{
	case DrawType::DRAW:				stream << "draw";					break;
	case DrawType::DRAW_INDIRECT:		stream << "draw_indirect";			break;
	case DrawType::DRAW_INDIRECT_COUNT:	stream << "draw_indirect_count";	break;
	default: DE_ASSERT(false); break;
	}
	return stream;
}


// This helps test the maxDrawCount rule for the DRAW_INDIRECT_COUNT case.
enum class IndirectCountLimitType
{
	BUFFER_VALUE = 0,		// The actual count will be given by the count buffer.
	MAX_COUNT,				// The actual count will be given by the maxDrawCount argument passed to the draw command.
};

struct IndirectArgs
{
	uint32_t offset;
	uint32_t stride;
};

struct TestParams
{
	DrawType							drawType;
	uint32_t							seed;
	uint32_t							drawCount;				// Equivalent to taskCount or drawCount.
	uint32_t							firstTask;				// Equivalent to firstTask in every call.
	tcu::Maybe<IndirectArgs>			indirectArgs;			// Only used for DRAW_INDIRECT*.
	tcu::Maybe<IndirectCountLimitType>	indirectCountLimit;		// Only used for DRAW_INDIRECT_COUNT.
	tcu::Maybe<uint32_t>				indirectCountOffset;	// Only used for DRAW_INDIRECT_COUNT.
	bool								useTask;
};

// The framebuffer will have a number of rows and 32 columns. Each mesh shader workgroup will generate geometry to fill a single
// framebuffer row, using a triangle list with 32 triangles of different colors, each covering a framebuffer pixel.
//
// Note: the total framebuffer rows is called "full" below (e.g. 64). When using a task shader to generate work, each workgroup will
// generate a single mesh workgroup using a push constant instead of a compile-time constant.
//
// When using DRAW, the task count will tell us how many rows of pixels will be filled in the framebuffer.
//
// When using indirect draws, the full framebuffer will always be drawn into by using multiple draw command structures, except in
// the case of drawCount==0. Each draw will spawn the needed number of tasks to fill the whole framebuffer. In addition, in order to
// make all argument structures different, the number of tasks in each draw count will be slightly different and assigned
// pseudorandomly.
//
// DRAW: taskCount=0, taskCount=1, taskCount=2, taskCount=half, taskCount=full
//
// DRAW_INDIRECT: drawCount=0, drawCount=1, drawCount=2, drawCount=half, drawCount=full.
//  * With offset 0 and pseudorandom (multiples of 4).
//  * With stride adding a padding of 0 and pseudorandom (multiples of 4).
//
// DRAW_INDIRECT_COUNT: same as indirect in two variants:
//  1. Passing the count in a buffer with a large maximum.
//  2. Passing a large value in the buffer and limiting it with the maximum.

class MeshApiCase : public vkt::TestCase
{
public:
					MeshApiCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
						: vkt::TestCase	(testCtx, name, description)
						, m_params		(params)
						{}
	virtual			~MeshApiCase	(void) {}

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

protected:
	TestParams		m_params;
};

class MeshApiInstance : public vkt::TestInstance
{
public:
						MeshApiInstance		(Context& context, const TestParams& params)
							: vkt::TestInstance	(context)
							, m_params			(params)
							{}
	virtual				~MeshApiInstance	(void) {}

	tcu::TestStatus		iterate				(void) override;

protected:
	TestParams			m_params;
};

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

struct PushConstantData
{
	uint32_t width;
	uint32_t height;
	uint32_t firstTaskMesh;
	uint32_t one;
	uint32_t firstTaskTask;

	std::vector<VkPushConstantRange> getRanges (bool includeTask) const
	{
		constexpr uint32_t offsetMesh = 0u;
		constexpr uint32_t offsetTask = static_cast<uint32_t>(offsetof(PushConstantData, one));
		constexpr uint32_t sizeMesh = offsetTask;
		constexpr uint32_t sizeTask = static_cast<uint32_t>(sizeof(PushConstantData)) - offsetTask;

		const VkPushConstantRange meshRange =
		{
			VK_SHADER_STAGE_MESH_BIT_NV,	//	VkShaderStageFlags	stageFlags;
			offsetMesh,						//	uint32_t			offset;
			sizeMesh,						//	uint32_t			size;
		};
		const VkPushConstantRange taskRange =
		{
			VK_SHADER_STAGE_TASK_BIT_NV,	//	VkShaderStageFlags	stageFlags;
			offsetTask,						//	uint32_t			offset;
			sizeTask,						//	uint32_t			size;
		};

		std::vector<VkPushConstantRange> ranges (1u, meshRange);
		if (includeTask)
			ranges.push_back(taskRange);
		return ranges;
	}
};

void MeshApiCase::initPrograms (vk::SourceCollections& programCollection) const
{
	const std::string taskDataDecl =
		"taskNV TaskData {\n"
		"    uint blockNumber;\n"
		"    uint blockRow;\n"
		"} td;\n"
		;

	// Task shader if needed.
	if (m_params.useTask)
	{
		std::ostringstream task;
		task
			<< "#version 460\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (local_size_x=1) in;\n"
			<< "\n"
			<< "layout (push_constant, std430) uniform TaskPushConstantBlock {\n"
			<< "    layout (offset=12) uint one;\n"
			<< "    layout (offset=16) uint firstTask;\n"
			<< "} pc;\n"
			<< "\n"
			<< "out " << taskDataDecl
			<< "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "    gl_TaskCountNV  = pc.one;\n"
			<< "    td.blockNumber  = uint(gl_DrawID);\n"
			<< "    td.blockRow     = gl_WorkGroupID.x - pc.firstTask;\n"
			<< "}\n"
			;
		programCollection.glslSources.add("task") << glu::TaskSource(task.str());
	}

	// Mesh shader.
	{
		std::ostringstream mesh;
		mesh
			<< "#version 460\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (local_size_x=32) in;\n"
			<< "layout (triangles) out;\n"
			<< "layout (max_vertices=96, max_primitives=32) out;\n"
			<< "\n"
			<< "layout (push_constant, std430) uniform MeshPushConstantBlock {\n"
			<< "    uint width;\n"
			<< "    uint height;\n"
			<< "    uint firstTask;\n"
			<< "} pc;\n"
			<< "\n"
			<< "layout (location=0) perprimitiveNV out vec4 primitiveColor[];\n"
			<< "\n"
			<< (m_params.useTask ? ("in " + taskDataDecl): "")
			<< "\n"
			<< "layout (set=0, binding=0, std430) readonly buffer BlockSizes {\n"
			<< "    uint blockSize[];\n"
			<< "} bsz;\n"
			<< "\n"
			<< "uint startOfBlock (uint blockNumber)\n"
			<< "{\n"
			<< "    uint start = 0;\n"
			<< "    for (uint i = 0; i < blockNumber; i++)\n"
			<< "        start += bsz.blockSize[i];\n"
			<< "    return start;\n"
			<< "}\n"
			<< "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "    const uint blockNumber = " << (m_params.useTask ? "td.blockNumber" : "uint(gl_DrawID)") << ";\n"
			<< "    const uint blockRow = " << (m_params.useTask ? "td.blockRow" : "(gl_WorkGroupID.x - pc.firstTask)") << ";\n"
			<< "\n"
			<< "    // Each workgroup will fill one row, and each invocation will generate a\n"
			<< "    // triangle around the pixel center in each column.\n"
			<< "    const uint row = startOfBlock(blockNumber) + blockRow;\n"
			<< "    const uint col = gl_LocalInvocationID.x;\n"
			<< "\n"
			<< "    const float fHeight = float(pc.height);\n"
			<< "    const float fWidth = float(pc.width);\n"
			<< "\n"
			<< "    // Pixel coordinates, normalized.\n"
			<< "    const float rowNorm = (float(row) + 0.5) / fHeight;\n"
			<< "    const float colNorm = (float(col) + 0.5) / fWidth;\n"
			<< "\n"
			<< "    // Framebuffer coordinates.\n"
			<< "    const float coordX = (colNorm * 2.0) - 1.0;\n"
			<< "    const float coordY = (rowNorm * 2.0) - 1.0;\n"
			<< "\n"
			<< "    const float pixelWidth = 2.0 / fWidth;\n"
			<< "    const float pixelHeight = 2.0 / fHeight;\n"
			<< "\n"
			<< "    const float offsetX = pixelWidth / 2.0;\n"
			<< "    const float offsetY = pixelHeight / 2.0;\n"
			<< "\n"
			<< "    const uint baseIndex = col*3;\n"
			<< "    const uvec3 indices = uvec3(baseIndex, baseIndex + 1, baseIndex + 2);\n"
			<< "\n"
			<< "    gl_PrimitiveCountNV = 32u;\n"
			<< "    primitiveColor[col] = vec4(rowNorm, colNorm, 0.0, 1.0);\n"
			<< "\n"
			<< "    gl_PrimitiveIndicesNV[indices.x] = indices.x;\n"
			<< "    gl_PrimitiveIndicesNV[indices.y] = indices.y;\n"
			<< "    gl_PrimitiveIndicesNV[indices.z] = indices.z;\n"
			<< "\n"
			<< "    gl_MeshVerticesNV[indices.x].gl_Position = vec4(coordX - offsetX, coordY + offsetY, 0.0, 1.0);\n"
			<< "    gl_MeshVerticesNV[indices.y].gl_Position = vec4(coordX + offsetX, coordY + offsetY, 0.0, 1.0);\n"
			<< "    gl_MeshVerticesNV[indices.z].gl_Position = vec4(coordX, coordY - offsetY, 0.0, 1.0);\n"
			<< "}\n"
			;
		programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str());
	}

	// Frag shader.
	{
		std::ostringstream frag;
		frag
			<< "#version 460\n"
			<< "#extension GL_NV_mesh_shader : enable\n"
			<< "\n"
			<< "layout (location=0) perprimitiveNV in 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.str());
	}
}

void MeshApiCase::checkSupport (Context& context) const
{
	context.requireDeviceFunctionality("VK_NV_mesh_shader");

	const auto& meshFeatures = context.getMeshShaderFeatures();

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

	if (m_params.useTask && !meshFeatures.taskShader)
		TCU_THROW(NotSupportedError, "Task shaders not supported");

	// VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718
	if (m_params.drawType == DrawType::DRAW_INDIRECT && m_params.drawCount > 1u)
	{
		const auto& features = context.getDeviceFeatures();
		if (!features.multiDrawIndirect)
			TCU_THROW(NotSupportedError, "Indirect multi-draws not supported");
	}

	// VUID-vkCmdDrawMeshTasksIndirectCountNV-None-04445
	if (m_params.drawType == DrawType::DRAW_INDIRECT_COUNT)
		context.requireDeviceFunctionality("VK_KHR_draw_indirect_count");
}

template <typename T>
BufferWithMemoryPtr makeStridedBuffer(const DeviceInterface& vkd, VkDevice device, Allocator& alloc, const std::vector<T>& elements, uint32_t offset, uint32_t stride, VkBufferUsageFlags usage, uint32_t endPadding)
{
	const auto elementSize	= static_cast<uint32_t>(sizeof(T));
	const auto actualStride	= std::max(elementSize, stride);
	const auto bufferSize	= static_cast<size_t>(offset) + static_cast<size_t>(actualStride) * elements.size() + static_cast<size_t>(endPadding);
	const auto bufferInfo	= makeBufferCreateInfo(static_cast<VkDeviceSize>(bufferSize), usage);

	BufferWithMemoryPtr buffer(new BufferWithMemory(vkd, device, alloc, bufferInfo, MemoryRequirement::HostVisible));
	auto& bufferAlloc	= buffer->getAllocation();
	char* bufferDataPtr	= reinterpret_cast<char*>(bufferAlloc.getHostPtr());

	char* itr = bufferDataPtr + offset;
	for (const auto& elem : elements)
	{
		deMemcpy(itr, &elem, sizeof(elem));
		itr += actualStride;
	}
	if (endPadding > 0u)
		deMemset(itr, 0xFF, endPadding);

	flushAlloc(vkd, device, bufferAlloc);

	return buffer;
}

VkExtent3D getExtent ()
{
	return makeExtent3D(32u, 64u, 1u);
}

tcu::TestStatus MeshApiInstance::iterate (void)
{
	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		extent		= getExtent();
	const auto		iExtent3D	= tcu::IVec3(static_cast<int>(extent.width), static_cast<int>(extent.height), static_cast<int>(extent.depth));
	const auto		iExtent2D	= tcu::IVec2(iExtent3D.x(), iExtent3D.y());
	const auto		format		= VK_FORMAT_R8G8B8A8_UNORM;
	const auto		tcuFormat	= mapVkFormat(format);
	const auto		colorUsage	= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
	const auto		colorSRR	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const tcu::Vec4	clearColor	(0.0f, 0.0f, 0.0f, 1.0f);
	const float		colorThres	= 0.005f; // 1/255 < 0.005 < 2/255
	const tcu::Vec4	threshold	(colorThres, colorThres, 0.0f, 0.0f);

	ImageWithMemoryPtr	colorBuffer;
	Move<VkImageView>	colorBufferView;
	{
		const VkImageCreateInfo colorBufferInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
			nullptr,								//	const void*				pNext;
			0u,										//	VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
			format,									//	VkFormat				format;
			extent,									//	VkExtent3D				extent;
			1u,										//	uint32_t				mipLevels;
			1u,										//	uint32_t				arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
			colorUsage,								//	VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
			0u,										//	uint32_t				queueFamilyIndexCount;
			nullptr,								//	const uint32_t*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
		};
		colorBuffer = ImageWithMemoryPtr(new ImageWithMemory(vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any));
		colorBufferView = makeImageView(vkd, device, colorBuffer->get(), VK_IMAGE_VIEW_TYPE_2D, format, colorSRR);
	}

	// Prepare buffer containing the array of block sizes.
	de::Random				rnd				(m_params.seed);
	std::vector<uint32_t>	blockSizes;

	const uint32_t			vectorSize		= std::max(1u, m_params.drawCount);
	const uint32_t			largeDrawCount	= vectorSize + 1u; // The indirect buffer needs to have some padding at the end. See below.
	const uint32_t			evenBlockSize	= extent.height / vectorSize;
	uint32_t				remainingRows	= extent.height;

	blockSizes.reserve(vectorSize);
	for (uint32_t i = 0; i < vectorSize - 1u; ++i)
	{
		const auto blockSize = static_cast<uint32_t>(rnd.getInt(1, evenBlockSize));
		remainingRows -= blockSize;
		blockSizes.push_back(blockSize);
	}
	blockSizes.push_back(remainingRows);

	const auto			blockSizesBufferSize	= static_cast<VkDeviceSize>(de::dataSize(blockSizes));
	BufferWithMemoryPtr	blockSizesBuffer		= makeStridedBuffer(vkd, device, alloc, blockSizes, 0u, 0u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 0u);

	// Descriptor set layout, pool and set.
	DescriptorSetLayoutBuilder layoutBuilder;
	layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_MESH_BIT_NV);
	const auto setLayout = layoutBuilder.build(vkd, device);

	DescriptorPoolBuilder poolBuilder;
	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get());

	// Update descriptor set.
	{
		DescriptorSetUpdateBuilder updateBuilder;

		const auto location				= DescriptorSetUpdateBuilder::Location::binding(0u);
		const auto descriptorBufferInfo	= makeDescriptorBufferInfo(blockSizesBuffer->get(), 0ull, blockSizesBufferSize);

		updateBuilder.writeSingle(descriptorSet.get(), location, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
		updateBuilder.update(vkd, device);
	}

	// Pipeline layout.
	PushConstantData	pcData;
	const auto			pcRanges		= pcData.getRanges(m_params.useTask);
	const auto			pipelineLayout	= makePipelineLayout(vkd, device, 1u, &setLayout.get(), static_cast<uint32_t>(pcRanges.size()), de::dataOrNull(pcRanges));

	// Push constants.
	pcData.width			= extent.width;
	pcData.height			= extent.height;
	pcData.firstTaskMesh	= m_params.firstTask;
	pcData.one				= 1u;
	pcData.firstTaskTask	= m_params.firstTask;

	// Render pass and framebuffer.
	const auto renderPass	= makeRenderPass(vkd, device, format);
	const auto framebuffer	= makeFramebuffer(vkd, device, renderPass.get(), colorBufferView.get(), extent.width, extent.height);

	// Pipeline.
	Move<VkShaderModule> taskModule;
	Move<VkShaderModule> meshModule;
	Move<VkShaderModule> fragModule;

	const auto& binaries = m_context.getBinaryCollection();
	if (m_params.useTask)
		taskModule = createShaderModule(vkd, device, binaries.get("task"));
	meshModule = createShaderModule(vkd, device, binaries.get("mesh"));
	fragModule = createShaderModule(vkd, device, binaries.get("frag"));

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

	const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
		taskModule.get(), meshModule.get(), fragModule.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();

	// Indirect and count buffers if needed.
	BufferWithMemoryPtr indirectBuffer;
	BufferWithMemoryPtr countBuffer;

	if (m_params.drawType != DrawType::DRAW)
	{
		// Indirect draws.
		DE_ASSERT(static_cast<bool>(m_params.indirectArgs));
		const auto& indirectArgs = m_params.indirectArgs.get();

		// Check stride and offset validity.
		DE_ASSERT(indirectArgs.offset % 4u == 0u);
		DE_ASSERT(indirectArgs.stride % 4u == 0u && (indirectArgs.stride == 0u || indirectArgs.stride >= static_cast<uint32_t>(sizeof(VkDrawMeshTasksIndirectCommandNV))));

		// Prepare struct vector, which will be converted to a buffer with the proper stride and offset later.
		std::vector<VkDrawMeshTasksIndirectCommandNV> commands;
		commands.reserve(blockSizes.size());

		std::transform(begin(blockSizes), end(blockSizes), std::back_inserter(commands),
			[this](uint32_t blockSize) { return VkDrawMeshTasksIndirectCommandNV{blockSize, this->m_params.firstTask}; });

		const auto padding	= static_cast<uint32_t>(sizeof(VkDrawMeshTasksIndirectCommandNV));
		indirectBuffer		= makeStridedBuffer(vkd, device, alloc, commands, indirectArgs.offset, indirectArgs.stride, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, padding);

		// Prepare count buffer if needed.
		if (m_params.drawType == DrawType::DRAW_INDIRECT_COUNT)
		{
			DE_ASSERT(static_cast<bool>(m_params.indirectCountLimit));
			DE_ASSERT(static_cast<bool>(m_params.indirectCountOffset));

			const auto countBufferValue	= ((m_params.indirectCountLimit.get() == IndirectCountLimitType::BUFFER_VALUE)
										? m_params.drawCount
										: largeDrawCount);

			const std::vector<uint32_t> singleCount (1u, countBufferValue);
			countBuffer = makeStridedBuffer(vkd, device, alloc, singleCount, m_params.indirectCountOffset.get(), static_cast<uint32_t>(sizeof(uint32_t)), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, 0u);
		}
	}

	// Submit commands.
	beginCommandBuffer(vkd, cmdBuffer);
	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0), clearColor);

	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
	{
		const char* pcDataPtr = reinterpret_cast<const char*>(&pcData);
		for (const auto& range : pcRanges)
			vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), range.stageFlags, range.offset, range.size, pcDataPtr + range.offset);
	}
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());

	if (m_params.drawType == DrawType::DRAW)
	{
		vkd.cmdDrawMeshTasksNV(cmdBuffer, m_params.drawCount, m_params.firstTask);
	}
	else if (m_params.drawType == DrawType::DRAW_INDIRECT)
	{
		const auto& indirectArgs = m_params.indirectArgs.get();
		vkd.cmdDrawMeshTasksIndirectNV(cmdBuffer, indirectBuffer->get(), indirectArgs.offset, m_params.drawCount, indirectArgs.stride);
	}
	else if (m_params.drawType == DrawType::DRAW_INDIRECT_COUNT)
	{
		const auto& indirectArgs		= m_params.indirectArgs.get();
		const auto& indirectCountOffset	= m_params.indirectCountOffset.get();
		const auto& indirectCountLimit	= m_params.indirectCountLimit.get();

		const auto maxCount	= ((indirectCountLimit == IndirectCountLimitType::MAX_COUNT)
							? m_params.drawCount
							: largeDrawCount);
		vkd.cmdDrawMeshTasksIndirectCountNV(cmdBuffer, indirectBuffer->get(), indirectArgs.offset, countBuffer->get(), indirectCountOffset, maxCount, indirectArgs.stride);
	}
	else
		DE_ASSERT(false);

	endRenderPass(vkd, cmdBuffer);

	// Output buffer to extract the color buffer.
	BufferWithMemoryPtr	outBuffer;
	void*				outBufferData = nullptr;
	{
		const auto	outBufferSize	= static_cast<VkDeviceSize>(static_cast<uint32_t>(tcu::getPixelSize(tcuFormat)) * extent.width * extent.height);
		const auto	outBufferUsage	= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
		const auto	outBufferInfo	= makeBufferCreateInfo(outBufferSize, outBufferUsage);

		outBuffer					= BufferWithMemoryPtr(new BufferWithMemory(vkd, device, alloc, outBufferInfo, MemoryRequirement::HostVisible));
		outBufferData				= outBuffer->getAllocation().getHostPtr();
	}

	copyImageToBuffer(vkd, cmdBuffer, colorBuffer->get(), outBuffer->get(), iExtent2D);
	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Generate reference image and compare.
	{
		auto&						log				= m_context.getTestContext().getLog();
		auto&						outBufferAlloc	= outBuffer->getAllocation();
		tcu::ConstPixelBufferAccess	result			(tcuFormat, iExtent3D, outBufferData);
		tcu::TextureLevel			referenceLevel	(tcuFormat, iExtent3D.x(), iExtent3D.y());
		const auto					reference		= referenceLevel.getAccess();
		const auto					setName			= de::toString(m_params.drawType) + "_draw_count_" + de::toString(m_params.drawCount) + (m_params.useTask ? "_with_task" : "_no_task");
		const auto					fHeight			= static_cast<float>(extent.height);
		const auto					fWidth			= static_cast<float>(extent.width);

		invalidateAlloc(vkd, device, outBufferAlloc);

		for (int y = 0; y < iExtent3D.y(); ++y)
		for (int x = 0; x < iExtent3D.x(); ++x)
		{
			const tcu::Vec4 refColor	= ((m_params.drawCount == 0u || (m_params.drawType == DrawType::DRAW && y >= static_cast<int>(m_params.drawCount)))
										? clearColor
										: tcu::Vec4(
											// These match the per-primitive color set by the mesh shader.
											(static_cast<float>(y) + 0.5f) / fHeight,
											(static_cast<float>(x) + 0.5f) / fWidth,
											0.0f,
											1.0f));
			reference.setPixel(refColor, x, y);
		}

		if (!tcu::floatThresholdCompare(log, setName.c_str(), "", reference, result, threshold, tcu::COMPARE_LOG_ON_ERROR))
			return tcu::TestStatus::fail("Image comparison failed; check log for details");
	}

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

} // anonymous

tcu::TestCaseGroup* createMeshShaderApiTests (tcu::TestContext& testCtx)
{
	GroupPtr mainGroup (new tcu::TestCaseGroup(testCtx, "api", "Mesh Shader API tests"));

	const DrawType drawCases[] =
	{
		DrawType::DRAW,
		DrawType::DRAW_INDIRECT,
		DrawType::DRAW_INDIRECT_COUNT,
	};

	const auto		extent				= getExtent();
	const uint32_t	drawCountCases[]	= { 0u, 1u, 2u, extent.height / 2u, extent.height };

	const uint32_t normalStride	= static_cast<uint32_t>(sizeof(VkDrawMeshTasksIndirectCommandNV));
	const uint32_t largeStride	= 2u * normalStride + 4u;
	const uint32_t altOffset	= 20u;

	const struct
	{
		tcu::Maybe<IndirectArgs>	indirectArgs;
		const char*					name;
	} indirectArgsCases[] =
	{
		{ tcu::nothing<IndirectArgs>(),							"no_indirect_args"			},

		// Offset 0, varying strides.
		{ tcu::just(IndirectArgs{ 0u, 0u }),					"offset_0_stride_0"			},
		{ tcu::just(IndirectArgs{ 0u, normalStride }),			"offset_0_stride_normal"	},
		{ tcu::just(IndirectArgs{ 0u, largeStride }),			"offset_0_stride_large"		},

		// Nonzero offset, varying strides.
		{ tcu::just(IndirectArgs{ altOffset, 0u }),				"offset_alt_stride_0"		},
		{ tcu::just(IndirectArgs{ altOffset, normalStride }),	"offset_alt_stride_normal"	},
		{ tcu::just(IndirectArgs{ altOffset, largeStride }),	"offset_alt_stride_large"	},
	};

	const struct
	{
		tcu::Maybe<IndirectCountLimitType>	limitType;
		const char*							name;
	} countLimitCases[] =
	{
		{ tcu::nothing<IndirectCountLimitType>(),			"no_count_limit"		},
		{ tcu::just(IndirectCountLimitType::BUFFER_VALUE),	"count_limit_buffer"	},
		{ tcu::just(IndirectCountLimitType::MAX_COUNT),		"count_limit_max_count"	},
	};

	const struct
	{
		tcu::Maybe<uint32_t>	countOffset;
		const char*				name;
	} countOffsetCases[] =
	{
		{ tcu::nothing<uint32_t>(),	"no_count_offset"	},
		{ tcu::just(uint32_t{0u}),	"count_offset_0"	},
		{ tcu::just(altOffset),		"count_offset_alt"	},
	};

	const struct
	{
		bool		useTask;
		const char*	name;
	} taskCases[] =
	{
		{ false,	"no_task_shader"	},
		{ true,		"with_task_shader"	},
	};

	const struct
	{
		uint32_t	firstTask;
		const char*	name;
	} firstTaskCases[] =
	{
		{ 0u,		"first_task_zero"		},
		{ 1001u,	"first_task_nonzero"	},
	};

	uint32_t seed = 1628678795u;

	for (const auto& drawCase : drawCases)
	{
		const auto drawCaseName			= de::toString(drawCase);
		const bool isIndirect			= (drawCase != DrawType::DRAW);
		const bool isIndirectNoCount	= (drawCase == DrawType::DRAW_INDIRECT);
		const bool isIndirectCount		= (drawCase == DrawType::DRAW_INDIRECT_COUNT);

		GroupPtr drawGroup(new tcu::TestCaseGroup(testCtx, drawCaseName.c_str(), ""));

		for (const auto& drawCountCase : drawCountCases)
		{
			const auto drawCountName = "draw_count_" + de::toString(drawCountCase);
			GroupPtr drawCountGroup(new tcu::TestCaseGroup(testCtx, drawCountName.c_str(), ""));

			for (const auto& indirectArgsCase : indirectArgsCases)
			{
				const bool hasIndirectArgs	= static_cast<bool>(indirectArgsCase.indirectArgs);
				const bool strideZero		= (hasIndirectArgs && indirectArgsCase.indirectArgs.get().stride == 0u);

				if (isIndirect != hasIndirectArgs)
					continue;

				// VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146 and VUID-vkCmdDrawMeshTasksIndirectCountNV-stride-02182.
				if (((isIndirectNoCount && drawCountCase > 1u) || isIndirectCount) && strideZero)
					continue;

				GroupPtr indirectArgsGroup(new tcu::TestCaseGroup(testCtx, indirectArgsCase.name, ""));

				for (const auto& countLimitCase : countLimitCases)
				{
					const bool hasCountLimit = static_cast<bool>(countLimitCase.limitType);

					if (isIndirectCount != hasCountLimit)
						continue;

					GroupPtr countLimitGroup(new tcu::TestCaseGroup(testCtx, countLimitCase.name, ""));

					for (const auto& countOffsetCase : countOffsetCases)
					{
						const bool hasCountOffsetType = static_cast<bool>(countOffsetCase.countOffset);

						if (isIndirectCount != hasCountOffsetType)
							continue;

						GroupPtr countOffsetGroup(new tcu::TestCaseGroup(testCtx, countOffsetCase.name, ""));

						for (const auto& taskCase : taskCases)
						{
							GroupPtr taskCaseGrp(new tcu::TestCaseGroup(testCtx, taskCase.name, ""));

							for (const auto& firstTaskCase : firstTaskCases)
							{
								const TestParams params =
								{
									drawCase,						//	DrawType							drawType;
									seed++,							//	uint32_t							seed;
									drawCountCase,					//	uint32_t							drawCount;
									firstTaskCase.firstTask,		//	uint32_t							firstTask;
									indirectArgsCase.indirectArgs,	//	tcu::Maybe<IndirectArgs>			indirectArgs;
									countLimitCase.limitType,		//	tcu::Maybe<IndirectCountLimitType>	indirectCountLimit;
									countOffsetCase.countOffset,	//	tcu::Maybe<uint32_t>				indirectCountOffset;
									taskCase.useTask,				//	bool								useTask;
								};

								taskCaseGrp->addChild(new MeshApiCase(testCtx, firstTaskCase.name, "", params));
							}

							countOffsetGroup->addChild(taskCaseGrp.release());
						}

						countLimitGroup->addChild(countOffsetGroup.release());
					}

					indirectArgsGroup->addChild(countLimitGroup.release());
				}

				drawCountGroup->addChild(indirectArgsGroup.release());
			}

			drawGroup->addChild(drawCountGroup.release());
		}

		mainGroup->addChild(drawGroup.release());
	}

	return mainGroup.release();
}

} // MeshShader
} // vkt
